<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Techie Kho</title>
    <description>The latest articles on DEV Community by Techie Kho (@rechie_kho).</description>
    <link>https://dev.to/rechie_kho</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F660076%2F31b4bf16-dee7-499f-bc60-c7fd42f6952b.png</url>
      <title>DEV Community: Techie Kho</title>
      <link>https://dev.to/rechie_kho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rechie_kho"/>
    <language>en</language>
    <item>
      <title>Meet Ovis: a compiler that reads plain English</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Thu, 22 Oct 2026 14:10:26 +0000</pubDate>
      <link>https://dev.to/rechie_kho/meet-ovis-a-compiler-that-reads-plain-english-1oag</link>
      <guid>https://dev.to/rechie_kho/meet-ovis-a-compiler-that-reads-plain-english-1oag</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Everything starts with a small thought, what if I merge LLM &amp;amp; LLVM?  Will I able to write English Pseudo-code with the performance of a compiled language?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  English in, native code out
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ovis-lang/ovis" rel="noopener noreferrer"&gt;Ovis&lt;/a&gt; is a programming language whose source code is plain English, compiled through LLVM into a native executable. You write lines the way you would say them, such as &lt;code&gt;show the average of numbers rounded to 2 decimals&lt;/code&gt;, and get a fast binary that can call any C library.&lt;/p&gt;

&lt;p&gt;The twist is how it reads English. A deterministic parser reads every line. A small language model built into the compiler steps in only when a line is unclear, and even then it never writes code: it picks one of the readings that already type-check. Every choice it makes is written down, so the next build needs no model at all.&lt;/p&gt;

&lt;p&gt;That makes Ovis different from "ask an AI to write the code". There is no hidden prompt and no code you didn't see. The program is your English, and the compiler shows you exactly how it read it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ovis is an experiment, and the language is still changing. This post describes it as of October 2026.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  A first program
&lt;/h2&gt;

&lt;p&gt;Here is a whole Ovis program. It finds the primes below 50, and it defines its own phrase, &lt;code&gt;(n) is prime&lt;/code&gt;, along the way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Finds the prime numbers below 50.
to (n) is prime:
    if n &amp;lt; 2:
        give back false
    divisor = 2
    while divisor * divisor &amp;lt;= n:
        if n is divisible by divisor:
            give back false
        divisor = divisor + 1
    give back true

primes = empty list of whole numbers
for each n in the numbers from 2 to 49:
    if n is prime:
        add n to primes
show primes
show "Found", length of primes, "primes"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you know Python, the shape is familiar: a line ending in &lt;code&gt;:&lt;/code&gt; opens an indented block, &lt;code&gt;name = value&lt;/code&gt; makes a variable, and Ovis works out the types. What is new is that &lt;code&gt;is divisible by&lt;/code&gt;, &lt;code&gt;add … to …&lt;/code&gt; and &lt;code&gt;length of&lt;/code&gt; are phrases, not keywords. The library has 171 of them, and &lt;code&gt;to WORDS (parameter) …:&lt;/code&gt; adds your own. A phrase you define works on any line, as a statement or as a value.&lt;/p&gt;

&lt;h3&gt;
  
  
  When a line is unclear
&lt;/h3&gt;

&lt;p&gt;Say you write &lt;code&gt;mean of numbers&lt;/code&gt;, but the library only knows &lt;code&gt;average of numbers&lt;/code&gt;. Ovis lists the readings that make sense there, the model picks one, and Ovis writes its choice just above your line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@[meaning: show "Average:", average of numbers rounded to 2 decimals]
show "Average:", mean of numbers rounded to 2 decimals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can read that line, change it, or delete it to ask again. And when the model isn't sure, Ovis doesn't guess. It stops and asks you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ovis run examples/vague.ovis
examples/vague.ovis, line 4: "show square root of x + 7" is unclear. Did you
mean one of these? Write it in the source:
    show ((square root of x) + 7)
    show square root of (x + 7)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Ovis is a normal compiler with one extra step for unclear lines. Most lines go straight from the parser to code; only lines with no single reading become questions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Parsing.&lt;/strong&gt; A chart parser matches each line against the phrases and keeps only the readings that type-check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Questions.&lt;/strong&gt; A line that reads several ways, or uses words no phrase has, becomes a question with a few candidate readings. The six steps in the picture are tried in order; the model is fifth, and you are the last word.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compilation.&lt;/strong&gt; Each phrase stands for a form in Ovis Core, a small typed Lisp. The whole program is type-checked, turned into LLVM IR, optimised, and linked with a small runtime and libc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Phrases are just templates, so the library is readable and extendable. Here is &lt;code&gt;average of&lt;/code&gt;, straight from the phrase files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expr  average of {xs: int[]}   : float  =&amp;gt; (/ (float (prelude_sum_int $xs)) (float (len $xs)))
      alias: average value of {xs}
stmt  add {x: T} to {xs: T[]}           =&amp;gt; (append $xs $x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model runs locally through llama.cpp, so your code never leaves your machine. A background daemon keeps it loaded between builds and quits after 15 minutes unused.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the model is kept on a short leash
&lt;/h2&gt;

&lt;p&gt;An AI in the compiler sounds like a recipe for builds that change from one run to the next. Ovis is designed so that can't happen.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The model only chooses.&lt;/strong&gt; It picks among readings the parser already produced and the type checker already accepted. It can't invent a function or a call that wasn't on the list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rewrites are checked.&lt;/strong&gt; When no reading fits, the model may restate the line in words Ovis reads. The rewrite is kept only if it then parses and keeps every name and value of the original.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every choice is saved.&lt;/strong&gt; Answers go into &lt;code&gt;@[meaning: …]&lt;/code&gt; lines and a &lt;code&gt;&amp;lt;file&amp;gt;.lock&lt;/code&gt; that you commit with the source. After that, builds never load the model, and building again changes no file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Doubt goes to you.&lt;/strong&gt; If the model isn't confident, the build stops and shows you the readings. Nothing ambiguous slips through silently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The effect is that reproducibility comes from the files you commit, not from the model. Another machine might settle a close question differently, but it never has to, because the answer is already in the lockfile. CI checks this: every example builds offline, twice, with no file changed. And a program written entirely in phrases Ovis knows never loads the model at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  More than a toy
&lt;/h2&gt;

&lt;p&gt;Plain English doesn't mean a small language. Here is a record and some phrases that work on any record's fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a book has:
    title (text)
    pages (whole number)
    price (decimal, 0)          # a field with a default

emma = a book with title "Emma", pages 474, price 8.5
show emma's title, title of emma, emma.title
ordered = books sorted by title
longest = the book in books with the most pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a trait, which says what a value can do. A list can mix records, and the right phrase is picked when the program runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a shape can:
    area of (it) gives a decimal
    describe (it)

a circle is a shape:
    area of (it):
        give back 3.14159 * radius of it * radius of it
    describe (it):
        show "a circle of radius", radius of it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What else is built and tested today:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;What it looks like&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Generics&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;a stack of (item) has:&lt;/code&gt;, &lt;code&gt;to push (x: any item) onto (s: stack of item):&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sized numbers and bits&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;byte&lt;/code&gt;, &lt;code&gt;int8&lt;/code&gt;…&lt;code&gt;uint64&lt;/code&gt;, &lt;code&gt;0x4F56&lt;/code&gt;, &lt;code&gt;shifted left by&lt;/code&gt;, &lt;code&gt;a header has, packed:&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Explicit memory, no garbage collector&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;with new memory:&lt;/code&gt;, &lt;code&gt;free x&lt;/code&gt;, &lt;code&gt;keep x&lt;/code&gt;; use-after-free is a checked error that names the lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cleanup&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;at the end, fclose(file)&lt;/code&gt; runs however the block ends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Any C library&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;use "sqlite3.h" from "sqlite3"&lt;/code&gt;; headers read with libclang, tested with zlib and SQLite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-file programs&lt;/td&gt;
&lt;td&gt;a folder with &lt;code&gt;main.ovis&lt;/code&gt;; &lt;code&gt;pricing/tax.ovis&lt;/code&gt; is the module &lt;code&gt;pricing.tax&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Projects and packages&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ovis.toml&lt;/code&gt;, &lt;code&gt;ovis add csv --git URL&lt;/code&gt;, versions as git tags, &lt;code&gt;ovis.lock&lt;/code&gt;; no central registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tooling&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ovis check&lt;/code&gt;, &lt;code&gt;ovis fix&lt;/code&gt;, &lt;code&gt;ovis fmt&lt;/code&gt;, a language server and a VS Code extension, CMake integration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The test suite has 240 cases and 3,063 assertions, and CI runs on Ubuntu and macOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in two minutes
&lt;/h2&gt;

&lt;p&gt;The installer, ovisup, works on Linux (x86-64 and arm64) and macOS on Apple silicon. It bundles LLVM, so the only thing you need is a C compiler for linking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-sSf&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  https://raw.githubusercontent.com/ovis-lang/ovis/main/tools/ovisup | sh

ovis new hello      &lt;span class="c"&gt;# a project: ovis.toml and a main.ovis that says hello&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;hello
ovis run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Until the first tagged release, the installer sets up the &lt;code&gt;nightly&lt;/code&gt; build. &lt;code&gt;ovisup check&lt;/code&gt; tells you what is missing, and &lt;code&gt;ovisup self uninstall&lt;/code&gt; removes everything.&lt;/p&gt;

&lt;p&gt;To let Ovis settle unclear lines of your own, download a model with &lt;code&gt;ovis model pull&lt;/code&gt;. It fetches Qwen2.5-Coder 7B (about 4.7 GB) if your GPU can run it, or the 3B model (about 2 GB) otherwise. A GPU is the intended setup: Macs use Metal with no configuration, and on four CPU cores a question takes about 2.3 seconds with 3B. If you would rather use a server, &lt;code&gt;--endpoint&lt;/code&gt; points Ovis at any OpenAI-compatible API that returns log-probabilities.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;examples/&lt;/code&gt; folder has a program for each part of the language, and every one builds without a model because its readings are already written in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The hardest open problem is the one at the heart of the idea: matching loose English to the right phrase. On 20 held-out lines worded far from any phrase, 7B settles 17.5 on average and 3B settles 13.5. The near-term work is better ranking of candidate readings, measuring 7B on GPUs, and a first tagged release.&lt;/p&gt;

&lt;p&gt;If you want to help, the most useful thing is to write programs the way you would naturally say them and report where Ovis misreads you or asks a question it shouldn't. Those lines become test cases. The code, the design documents and the open task list are all at &lt;a href="https://github.com/ovis-lang/ovis" rel="noopener noreferrer"&gt;github.com/ovis-lang/ovis&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Programming in English has been promised many times. Ovis's bet is that it works when the English stays the source of truth, the compiler stays deterministic, and the model only helps where you were unclear.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>llm</category>
    </item>
    <item>
      <title>Bag: A header-only, simplistic, C++20, zipping &amp; unzipping library.</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Fri, 10 Jan 2025 06:13:39 +0000</pubDate>
      <link>https://dev.to/rechie_kho/bag-a-header-only-simplistic-c20-zipping-unzipping-library-1a6d</link>
      <guid>https://dev.to/rechie_kho/bag-a-header-only-simplistic-c20-zipping-unzipping-library-1a6d</guid>
      <description>&lt;p&gt;Hello! It has been a while since the last time I did something for entertainment and learning purposes. So I take up a fairly simple C++ project that hopefully could be useful for other fellow C++ devs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;As I play around with &lt;a href="https://www.raylib.com" rel="noopener noreferrer"&gt;raylib&lt;/a&gt;, the small, easy, and exceptionally cool game library, I met a small issue. There is no elegant way of packing files together. When I use a texture or audio, or any external resources, I either need to convert it into a C++ header that declares a byte array filled with that resource, or making sure the the user having the resource at the particular place.  The first approach is no good when comes to loading new resource after compilation, while the latter approach is kind of awkward and too easy to break.&lt;/p&gt;

&lt;p&gt;I'm quite fond of the embedded zip approach. Zip files having a quirky file structure in which the header and metadata is at the end of the file in contrast with other file structure, such as executables, which is at the beginning of the file. This quirk gives a possibility, which is appending the zip file at the end of the executable. This makes the file behave like an executable, and a zip file at the same time.&lt;/p&gt;

&lt;p&gt;I believe there is definitely other zip library that did what I requested. But I would like to have some fun in C++20. So let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of bag
&lt;/h2&gt;

&lt;p&gt;With the aforementioned reasoning in mind, I wrote &lt;a href="https://github.com/RechieKho/libbag" rel="noopener noreferrer"&gt;&lt;code&gt;libbag&lt;/code&gt;&lt;/a&gt;, a header-only library for simple zipping and unzipping. It also includes the zipping (&lt;code&gt;bag&lt;/code&gt;) and unzipping (&lt;code&gt;unbag&lt;/code&gt;) utilities. &lt;/p&gt;

&lt;p&gt;By itself, it is sort of like a serialiser and deserialiser for key-value pairs, with key being a simple C-style string and value as byte array. The bag file structure is fairly simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|------------------------|
| key 0 (C-style string) |
|------------------------|
| Content 0 (Byte array) |
|------------------------|
|       ......           |
|------------------------|
| key N (C-style string) |
|------------------------|
| Content N (Byte array) |
|------------------------|
| indices                |
|------------------------|
| metadata               |
|------------------------|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the key-value pairs are tightly packed together, and some data is appended at the end of the pack. Metadata specifies the whole bag's byte count (to ignore any excess byte in front), position and length of indices, and lastly some magic bytes to indicate it is a bag.&lt;/p&gt;

&lt;p&gt;From the length and position of indices specified in metadata, we can query the memory to get the indices slice in bag. There it resides a list of position and length for each of the key-value pairs saved.&lt;/p&gt;

&lt;p&gt;To get the keys, just treat each key-value pairs as a C-style string since there is a null-terminator that marks the end of the key string. To query the content, just skip 'till the first null-terminator (basically the whole key), and then you get the content begin position, with some pointer arithmetic using the position and length from the indices, the end position of the content can be calculated.&lt;/p&gt;

&lt;p&gt;Here is some example usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;libbag.hpp&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;sstring&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;key_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;input_map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;/// Add items into `input_map`.&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;basic_ostreamstring&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unit_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;packed_stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Can be replace with std::basic_ofstream to output to file.&lt;/span&gt;
    &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;packed_stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pack.&lt;/span&gt;

    &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unit_string_type&lt;/span&gt; &lt;span class="n"&gt;packed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;packed_stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;key_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unpack_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libbag&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;bag_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;packed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;inserter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt; &lt;span class="c1"&gt;// Unpack.&lt;/span&gt;
    &lt;span class="c1"&gt;/// Do something about the unpacked data.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API depends on iterators, stream and inserters to reduce allocations.&lt;/p&gt;

&lt;p&gt;I also wrote a simple CLI to zip and unzip files, which is great for referencing as well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/RechieKho/libbag/blob/main/code/bag.cpp" rel="noopener noreferrer"&gt;bag&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/RechieKho/libbag/blob/main/code/unbag.cpp" rel="noopener noreferrer"&gt;unbag&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>gamedev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>React website sample for portfolio</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Thu, 11 Apr 2024 15:18:51 +0000</pubDate>
      <link>https://dev.to/rechie_kho/react-website-sample-for-portfolio-1opi</link>
      <guid>https://dev.to/rechie_kho/react-website-sample-for-portfolio-1opi</guid>
      <description>&lt;p&gt;TL;DR: I make a &lt;a href="https://richie-cativation.pgs.sh/index.html"&gt;website about kitties&lt;/a&gt; for portfolio, and here is the &lt;a href="https://github.com/RechieKho/cativation"&gt;source code&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hello people! So I have been trying to do a little freelance as a front-end web developer. Programming is my passion, but it has yet to feed me. I always heard that front-end web developer is the most common job in the market; many start-ups need a website, right(?). I've realised that I don't really have a web project to show off my web-making skill. My &lt;a href="https://rechiekho.github.io/RechieKho/"&gt;portfolio website&lt;/a&gt; doesn't count as it is made using vanilla javascript. So I guess it is time to make a random website using modern and popular framework like React.&lt;/p&gt;

&lt;p&gt;The tech stack is very simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vite for project setup and bundling.&lt;/li&gt;
&lt;li&gt;React (of course)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was about to use &lt;a href="https://mui.com/material-ui/"&gt;Material UI&lt;/a&gt; as they give a bunch of cool reusable components that is already stylised. But, it feels too "Google" and I am a C programmer (having an obsession over reinvent the wheel). &lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up the project
&lt;/h3&gt;

&lt;p&gt;Vite projects are &lt;strong&gt;VERY&lt;/strong&gt; easy to setup to the point that I feel like it is too good to be true. The last time I play around with web, vite is yet to exist and configuring webpack took me 30 minutes of scanning through the docs only to be forgotten once the setup is completed. &lt;/p&gt;

&lt;p&gt;For vite, it really just these magic word:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do some command line inputs and it is done, amazing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working the design
&lt;/h3&gt;

&lt;p&gt;Alright, I'll going to be honest here: I kind of want to finish this ASAP in the weekend so I made things up along the way instead of planning it in Figma. &lt;/p&gt;

&lt;p&gt;I first checking out any good fonts on &lt;a href="https://fonts.google.com"&gt;Google font&lt;/a&gt; that fits the theme of the website. I select the Nunito as I could feel the playful vibe behind it. &lt;/p&gt;

&lt;p&gt;Then, I get some color palette from this &lt;a href="https://coolors.co"&gt;color palette generator&lt;/a&gt;. I have been using it since the very beginning of web dev journey, a good color palette could better describe the theme of the website. &lt;/p&gt;

&lt;h3&gt;
  
  
  CSS
&lt;/h3&gt;

&lt;p&gt;Writing CSS is much a creative process here since I don't have a mockup, thus it is kind of describe it in detail. But I will still share things that I usually do in CSS.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;reset.css&lt;br&gt;
I will &lt;em&gt;always&lt;/em&gt; use the &lt;a href="https://meyerweb.com/eric/tools/css/reset/"&gt;reset stylesheet&lt;/a&gt;. It is because different web browser has its own default stylesheet that could mess up my code. So I just copy the code and put it in the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CSS variables&lt;br&gt;
I love CSS variables, I use it to for the color palette.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f5f5f5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--grey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#796c9f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#392f5a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2ea9c4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--primary-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#a1d8eb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ff9f1c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--secondary-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffbf69&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It avoids hardcoding colors. Then, I only need to change the value of the variable instead of searching through the codebase for that particular color code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Javascript
&lt;/h3&gt;

&lt;p&gt;Since it is React, I need to do something special here. &lt;br&gt;
I decided to use the &lt;a href="https://cataas.com"&gt;Cataas&lt;/a&gt; API to fetch cat pictures in my code to display the random cats.&lt;/p&gt;

&lt;p&gt;But behind the scene, it is just &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;catImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCatImage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialCatImage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateCatImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="s2"&gt;`https://cataas.com/cat?width=250&amp;amp;height=250`&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;setCatImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
      &lt;span class="p"&gt;})();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateCatImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that is all the special stuff in the website...&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;I'm using &lt;a href="https://pgs.sh"&gt;pgs.sh&lt;/a&gt; to host my static site. It uses &lt;code&gt;ssh&lt;/code&gt; (secure shell) and &lt;code&gt;rsync&lt;/code&gt; (a file transfer protocol) to do all the stuff. It doesn't need to create account or whatsoever. Very quick to setup, very cool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Well, I got a website to show-off and maybe get a freelance project. And, you get to see all my source code and learn something. It is beneficial to both of us. Thank you for reading this late night posting and have a nice day/night.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>Running pre-trained ML models in Godot</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Thu, 18 Jan 2024 12:21:04 +0000</pubDate>
      <link>https://dev.to/rechie_kho/running-pre-trained-ml-models-in-godot-37da</link>
      <guid>https://dev.to/rechie_kho/running-pre-trained-ml-models-in-godot-37da</guid>
      <description>&lt;p&gt;So I have been developing this GDExtension called &lt;a href="https://github.com/RechieKho/iree.gd"&gt;iree.gd&lt;/a&gt;. It is mission to embed &lt;a href="https://github.com/openxla/iree"&gt;IREE&lt;/a&gt;, another cool project that compiles and runs ML models, into Godot. It took me quite a while, but finally It has reached &lt;a href="https://github.com/RechieKho/iree.gd/releases"&gt;alpha&lt;/a&gt;. &lt;br&gt;
Hope you guys could check it out the sample.&lt;/p&gt;

&lt;p&gt;I can't upload video to here, but you still can watch a small clips of &lt;a href="https://github.com/RechieKho/iree.gd/issues/37#issuecomment-1897703268"&gt;iree.gd doing its magic here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Currently, it is still having a very thin abstraction layer, and some manual stuff need to be done in prior.&lt;/p&gt;
&lt;h3&gt;
  
  
  Preparing the ML model
&lt;/h3&gt;

&lt;p&gt;Before doing anything, you'll need to download your trained ML model from the internet. You could find some from &lt;a href="https://www.kaggle.com/models"&gt;Kaggle&lt;/a&gt;. Then, you'll need to preprocess them with python &lt;a href="https://iree.dev/guides/ml-frameworks/tflite/"&gt;via this detailed documentation&lt;/a&gt;. You'll need to set the HAL backend following &lt;a href="https://github.com/RechieKho/iree.gd#supported-platforms"&gt;this table depending on your targeted platform&lt;/a&gt;. As you generate the &lt;code&gt;.vmfb&lt;/code&gt; byte code, you are ready to proceed to the next step.&lt;/p&gt;
&lt;h3&gt;
  
  
  Use the ML model
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;.vmfb&lt;/code&gt; files are automatically imported into the project as you drag and drop 'em into it. You could then use them in your script by loading them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;model&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IREEModule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"res://your_model.vmfb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;@export&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;model_2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;IREEModule&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="kt"&gt;Drag&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;drop&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you'll need to prepare your inputs with &lt;code&gt;IREETensor&lt;/code&gt;, then execute the ML model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;IREETensor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="kt"&gt;Remember&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;consider&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"module.main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="kt"&gt;Do&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;output&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;input&lt;/code&gt; and function name vary models to models. You could inspect the &lt;code&gt;.vmfb&lt;/code&gt; file using &lt;code&gt;iree-dump-module&lt;/code&gt; from the IREE packages you installed during preparing the ML model. &lt;/p&gt;

&lt;p&gt;Here is one section of the dump of the ML model used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
Exported Functions:
  [  0] main(!vm.ref&amp;lt;?&amp;gt;) -&amp;gt; (!vm.ref&amp;lt;?&amp;gt;)
        iree.abi.declaration: sync func @main(%input0: tensor&amp;lt;1x50x50x3xf32&amp;gt; {ml_program.identifier = "input_0"}) -&amp;gt; (%output0: tensor&amp;lt;1x200x200x3xf32&amp;gt; {ml_program.identifier = "Identity"})
  [  1] __init() -&amp;gt; ()
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could kind of guess it, it has &lt;code&gt;main&lt;/code&gt; function that takes a tensor of &lt;code&gt;float32&lt;/code&gt; (&lt;code&gt;1x50x50x3xf32&lt;/code&gt;) and outputs another tensor of &lt;code&gt;float32&lt;/code&gt; (&lt;code&gt;1x200x200x3xf32&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample
&lt;/h2&gt;

&lt;p&gt;There is a readily available sample of esrgan for you to try in the &lt;a href="https://github.com/RechieKho/iree.gd/releases"&gt;release page&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The sample only work on windows and linux.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After download and open &lt;code&gt;iree-gd-sample-*.zip&lt;/code&gt; with Godot 4.2+, you will need to do these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;set &lt;code&gt;res://scenes/main/main.tscn&lt;/code&gt; to be loaded on start.&lt;/li&gt;
&lt;li&gt;Drag and drop appropriate byte code in &lt;code&gt;res://bytecodes/esrgan/esrgan.*.vmfb&lt;/code&gt; into &lt;code&gt;UI/TextureRect&lt;/code&gt;'s module export.&lt;/li&gt;
&lt;li&gt;Run it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Afterword
&lt;/h2&gt;

&lt;p&gt;Hopefully, in the future, Godot developer could utilise this piece of technology and create something extraordinary and magical. Thank you for reading this.&lt;/p&gt;

</description>
      <category>godot</category>
      <category>machinelearning</category>
      <category>gamedev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Minky scripting language</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Wed, 15 Nov 2023 12:38:29 +0000</pubDate>
      <link>https://dev.to/rechie_kho/minky-scripting-language-21pj</link>
      <guid>https://dev.to/rechie_kho/minky-scripting-language-21pj</guid>
      <description>&lt;p&gt;&lt;em&gt;Edit&lt;/em&gt;: It has been rebranded to Blinklet, here is the &lt;a href="https://github.com/RechieKho/blinklet"&gt;repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I have written a simple scripting language in Rust, the obscure language for a lot of devs. It is called "Minky".&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/RechieKho/minky"&gt;link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whole idea of this language stems from this thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if we remove parentheses from LISP?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essentially, Minky is my version of WISP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax
&lt;/h2&gt;

&lt;p&gt;Let's jump into the syntax:&lt;br&gt;
In a typical C-derived language, a function call usually look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function(arg1, arg2, arg3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Minky, since we disdain parentheses, we replace all the separating symbols with whitespace&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1 arg2 arg3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But... what if I want to inline a function call as an argument like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function(arg1, arg2, another_function())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, in Minky, you just indent it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1 arg2
    another_function # This will call
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't indent it, &lt;code&gt;another_function&lt;/code&gt; will be passed as value. &lt;/p&gt;

&lt;p&gt;But! What if I want to pass value after some indents?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1
    another_function 
    arg3 # I don't want this to get call!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, you just prefix it with &lt;code&gt;|&lt;/code&gt; to cancel out the call&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function arg1
    another_function
    | arg3 # Pass as value!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Some features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;String interpolation&lt;/li&gt;
&lt;li&gt;Closure&lt;/li&gt;
&lt;li&gt;Loose Object-Oriented Programming&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  String interpolation
&lt;/h3&gt;

&lt;p&gt;To do string interpolation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;some-command 'Text `identifier`'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;identifier&lt;/code&gt; is the variable name, it will substitute with the variable's string representation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closure
&lt;/h3&gt;

&lt;p&gt;All the user-defined functions are closure. It has access to the lexically scoped variable. In simple term, the scope that the closure is declared in lives with the closure until the closure itself dies, and the closure can access the scope.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var make-counter
    closure
        var counter 0 # counter will live with the returned closure even after `make-counter` complete execution.
        return
            closure
                set counter # access parent counter.
                    add counter 1
                println 'counter: `counter`'

var counter
    make-counter

counter # 1
counter # 2
counter # 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Loose Object-Oriented Programming
&lt;/h3&gt;

&lt;p&gt;In normal class-based object-oriented programming, we have class and object, in which the object's structure is based on the class. In Minky, all of the classes and objects are table. Tables are &lt;em&gt;not&lt;/em&gt; linked together in anyway, but you can make a copy of a table (instancing) and extends on top of it (inheritance). Table is also act as scope, too!&lt;/p&gt;

&lt;p&gt;To make a person class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var Person
    table
        var name 'Bazinga'
        var age 25
        var say-hi
            closure # aka. function but has access to parent scope.
                println 'Hi! I am `name`. Nice to meet you!'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make an instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var peter
    Person
        set name 'Peterson'
        set age 90

# Call the method
peter
    say-hi

# Access values
var peter-age
    peter
        return age
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To extend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var Police
    Person
        set name 'Policeman'
        set age 15
        var gun 'AK15'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It is my attempt on making a scripting language. There are more feature to be discussed, and to be added. You can fetch the code at &lt;a href="https://github.com/RechieKho/minky"&gt;my GitHub repo&lt;/a&gt;. Thank you for reading and have a nice day.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>coding</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Piko-piko OS. A homemade 16-bit x86 toy operating system for fun.</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Wed, 07 Dec 2022 11:33:18 +0000</pubDate>
      <link>https://dev.to/rechie_kho/piko-piko-os-a-homemade-16-bit-x86-toy-operating-system-for-fun-52dm</link>
      <guid>https://dev.to/rechie_kho/piko-piko-os-a-homemade-16-bit-x86-toy-operating-system-for-fun-52dm</guid>
      <description>&lt;p&gt;So I made a &lt;a href="https://github.com/RechieKho/piko-piko"&gt;16-bit x86 toy OS in pure assembly&lt;/a&gt;. 3 months ago, I found a very fun &lt;a href="https://github.com/cfenollosa/os-tutorial"&gt;tutorial&lt;/a&gt; on github that is about Operating system development. I read the first few chapter and from there I made a very simple, extensible (?) toy operating system that could run on hardware (yes, it is madness). &lt;/p&gt;

&lt;h2&gt;
  
  
  Piko-piko OS overview
&lt;/h2&gt;

&lt;p&gt;As the title stated, it is a toy os so itself doesn't do much. Still, the language is still turing complete. Here is an example that prints Hello world 10 times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;00000 &lt;span class="nb"&gt;set &lt;/span&gt;0 10
00001 say n &lt;span class="s2"&gt;"Hello world"&lt;/span&gt;
00002 sub 0 &lt;span class="nv"&gt;$0&lt;/span&gt; 1
00003 cmp &lt;span class="nv"&gt;$0&lt;/span&gt; 0
00004 june 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The language is more or less like an interpreted assembly language without label. It can read user input, print to output, basic arithmetic, save &amp;amp; load data and conditional jumps. &lt;a href="https://github.com/RechieKho/piko-piko/wiki/commands-reference"&gt;Here&lt;/a&gt; is all the commands included. I'll write a more user-friendly tutorial to kick start your Piko-piko OS coding journey, but right now you can only &lt;/p&gt;

&lt;p&gt;In Piko-piko OS, you can either enter the command to the prompt to run the command directly or using &lt;code&gt;=&lt;/code&gt; command to save lines of command to buffer and run it all together with &lt;code&gt;run&lt;/code&gt; command. By default, there is 3 buffer. Each buffer can only holds 2560 lines of text.&lt;/p&gt;

&lt;p&gt;Piko-piko OS is self-contained, which means that it does not rely on any other code and won't effect other files except itself. When saving &amp;amp; loading data, it does read and write to itself &lt;strong&gt;only&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practicality?
&lt;/h2&gt;

&lt;p&gt;Yes, it is not practical but it is a very educational resource to learn lower-level programming and really knowing how machine work. Still, you can use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show off&lt;/li&gt;
&lt;li&gt;Stop your child from watch too much youtube by locking them up in Piko-piko OS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a very cool experience to be able to make an operating from scratch. I might be able to share the experience of developing Piko-piko OS on the next blog post. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Don't write HTML page, I will tell you why.</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Mon, 11 Oct 2021 10:07:03 +0000</pubDate>
      <link>https://dev.to/rechie_kho/don-t-write-html-page-i-will-tell-you-why-1pd4</link>
      <guid>https://dev.to/rechie_kho/don-t-write-html-page-i-will-tell-you-why-1pd4</guid>
      <description>&lt;p&gt;Instead of encourage people, I am here to discourage you a guy, who started / want to start web development. &lt;/p&gt;

&lt;h2&gt;
  
  
  The start
&lt;/h2&gt;

&lt;p&gt;At the start your journey, you install either sublime or vscode or notepad++, then you start to make a website using HTML and know that HTML is a HyperText Markup Language. You feel proud of yourself as your HTML page is displayed in google chrome. Then, you color your page with CSS and make your page interactive with alert() and document.write().&lt;/p&gt;

&lt;h2&gt;
  
  
  framework hell
&lt;/h2&gt;

&lt;p&gt;Slowly, you think you are very good, then you heard of React or Angular and you immediately jump into it. In the blink of an eye, you are overwhelmed. What the hell is Webpack? What is JSX? What is Nodejs? What is typescript? What is npm? What is Sass? Why a simple website need so much technology with weird names?&lt;/p&gt;

&lt;h2&gt;
  
  
  server-side programing
&lt;/h2&gt;

&lt;p&gt;At the verge of giving up, you heard of database and server. You install XAMPP or WAMPP and then start poking around with PHP. You also play around with expressjs. Then, you are once again overwhelmed. What is composer? What is a session? What is phpMyAdmin and MySQL? &lt;/p&gt;

&lt;h2&gt;
  
  
  game development
&lt;/h2&gt;

&lt;p&gt;After you learn one or two things, you think desktop application and game development is cool, so you install Unity. Oh my, Object-Oriented Programming in C# (pain in general). You think that ElectronJS is easier and want to give it a shot but because everyone critisize that it is less performant so you give up.&lt;/p&gt;

&lt;h2&gt;
  
  
  linux
&lt;/h2&gt;

&lt;p&gt;Then, you heard that people keep telling you "I use Arch, btw" and "Vim is the best editor". You watch a few shitpost from Mental Outlaw (on youtube) and decided to install gentoo linux. You are once again overwhelmed. Why so much command (cd, touch, ls, emerge, time, ifconfig, vim and etc.)? Systemd called as soystemd? OpenRC? Init system? GNU and Linux is different? Display server? X.org vs Wayland? dwm vs bloated Gnome?&lt;/p&gt;

&lt;h2&gt;
  
  
  lower-level programming
&lt;/h2&gt;

&lt;p&gt;Then as you get used to the tty and know how to edit some text in vim. You start to do some C and C++ programming. Although the OOP from C# or Java helps, you still feel overwhelmed. CMake, Ninja, gcc, tcc, clang, llvm and etc.&lt;br&gt;
Maybe you also step on some assembly language and suffers. &lt;/p&gt;

&lt;p&gt;Ok I will stop now. All these painful learning + failing + imposter syndrome + mental illness is all because of you decided to install sublime /  vscode to create a HTML page. &lt;/p&gt;

&lt;p&gt;In conclusion, don't create your first HTML page.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Here is my website without fancy stuff like React or Angular or Vue</title>
      <dc:creator>Techie Kho</dc:creator>
      <pubDate>Sat, 09 Oct 2021 01:47:46 +0000</pubDate>
      <link>https://dev.to/rechie_kho/here-is-my-website-without-fancy-stuff-like-react-or-angular-or-vue-37l5</link>
      <guid>https://dev.to/rechie_kho/here-is-my-website-without-fancy-stuff-like-react-or-angular-or-vue-37l5</guid>
      <description>&lt;p&gt;A website that I created using only HTML, CSS, and JS : &lt;a href="https://rechiekho.github.io/RechieKho/index.html"&gt;https://rechiekho.github.io/RechieKho/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, its content is really stupid because I can't come out a new one.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
