<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Rasmus Andersson</title>
  <link href="https://rsms.me/atom.xml" rel="self"/>
  <link href="https://rsms.me/"/>
  <updated>2023-09-11T18:49:21+00:00</updated>
  <id>https://rsms.me/</id>
  <author>
    <name>Rasmus Andersson</name>
  </author>
  
  <entry>
    <title>Introduction to WebAssembly</title>
    <link href="https://rsms.me/wasm-intro"/>
    <updated>2017-01-16T00:00:00+00:00</updated>
    <id>https://rsms.me/wasm-intro</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;/res/wasm/absent-logo.svg&quot; width=&quot;30%&quot; align=&quot;right&quot; alt=&quot;This is not a logotype&quot; /&gt;&lt;a href=&quot;http://webassembly.org/&quot;&gt;WebAssembly&lt;/a&gt;, or WASM for short, is a new technology for running portable programs in a safe and efficient manner primarily aimed at the web platform. Similarly to &lt;a href=&quot;http://asmjs.org/spec/latest/&quot;&gt;ASM.js&lt;/a&gt;, WASM aims at a low level-of abstraction suitable as an intermediate representation of a higher-level program — i.e. WebAssembly code is intended to be generated by compilers rather than being written by humans. The &lt;a href=&quot;https://www.w3.org/community/webassembly/&quot;&gt;W3C community group&lt;/a&gt; includes representatives from the largest web-browser companies, including Google, Microsoft, Apple and Mozilla making this whole thing rather exciting.&lt;/p&gt;

&lt;p&gt;If you’re reading this chances are you’re already familiar with WASM to some extent. If you aren’t, this would be a good time to check out &lt;a href=&quot;http://webassembly.org/&quot;&gt;webassembly.org&lt;/a&gt;. At the time of publishing this article, WebAssembly has just reached the &lt;a href=&quot;http://webassembly.org/roadmap/&quot;&gt;Browser Preview milestone&lt;/a&gt;, meaning that version 1 of WebAssembly will very likely be what the current draft describes. The specifics of this article are for version mvp-13.&lt;/p&gt;

&lt;p&gt;There are
&lt;a href=&quot;https://users.rust-lang.org/t/compiling-to-the-web-with-rust-and-emscripten/7627&quot;&gt;some&lt;/a&gt;
&lt;a href=&quot;http://llvm.org/docs/doxygen/html/WebAssembly_8h.html&quot;&gt;existing&lt;/a&gt;
&lt;a href=&quot;http://webassembly.org/getting-started/developers-guide/&quot;&gt;compilers&lt;/a&gt;
which are getting “WASM’d”, but this article is going to focus on creating WASM programs without
lots of dependencies or high-level languages.&lt;/p&gt;

&lt;blockquote id=&quot;message1&quot;&gt;&lt;/blockquote&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
document.getElementById('message1').innerText = window.WebAssembly ?
  &quot;Congratulations. You're using a web browser with WebAssembly enabled.&quot; :
  &quot;It seems like your web browser doesn't support WebAssembly, but that\'s okay. &quot;+
  &quot;You won't need it to follow along in this article.&quot;;
&lt;/script&gt;

&lt;p&gt;Let’s get started.&lt;/p&gt;

&lt;h2 id=&quot;anatomy-of-a-webassembly-program&quot;&gt;Anatomy of a WebAssembly program&lt;/h2&gt;

&lt;p&gt;Actually, it’s called a “module” since with WebAssembly there’s no difference between a “program” and a “library” — there are only “modules”, each which can tie in and communicate with other modules, and each which can have a “main” function.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/res/wasm/overview.svg&quot; style=&quot;width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;First off a module expresses which version of WebAssembly it uses for its encoding. What then follows are a variable number of &lt;em&gt;sections&lt;/em&gt;, each containing information about the module. A module always begins with standard sections where order is important, and optionally ending in any number of custom sections that can contain any kind of data, all ignored by standard WASM virtual machines.&lt;/p&gt;

&lt;p&gt;The standard sections in WASM version 1 are as follows, where sections required for any functional module is marked by an asterisk (*):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;#type_section&quot;&gt;Type&lt;/a&gt;* — Function signature declarations&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#import_section&quot;&gt;Import&lt;/a&gt; — Import declarations&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#function_section&quot;&gt;Function&lt;/a&gt;* — Function declarations&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#table_section&quot;&gt;Table&lt;/a&gt; — Indirect function table and other tables&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#memory_section&quot;&gt;Memory&lt;/a&gt; — Memory attributes&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#global_section&quot;&gt;Global&lt;/a&gt; — Global declarations&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#export_section&quot;&gt;Export&lt;/a&gt; — Exports&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#start_section&quot;&gt;Start&lt;/a&gt; — Start function declaration&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#element_section&quot;&gt;Element&lt;/a&gt; — Elements section&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#code_section&quot;&gt;Code&lt;/a&gt;* — Function bodies&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#data_section&quot;&gt;Data&lt;/a&gt; — Data segments&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a name=&quot;type_section&quot;&gt;&lt;strong&gt;type section&lt;/strong&gt;&lt;/a&gt; contains a list of each unique function signature used throughout the module.
This includes any signatures of imported functions. The position in the list is the type signature’s unique index within the module. E.g.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// func_type #0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// func_type #1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// func_type #2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;WebAssembly has only four concrete types: 32-bit integer, 64-bit integer, 32-bit floating-point number and 64-bit floating-point number where the integer types are sign-agnostic (&lt;a href=&quot;#sign-agnostic&quot;&gt;more on this later&lt;/a&gt;) and floating-point numbers following the &lt;a href=&quot;http://ieeexplore.ieee.org/document/4610935/&quot;&gt;IEEE 754-2008&lt;/a&gt; standard. Any complex types can be built on top of these basic types by a compiler.
The rest of this article, as well as the &lt;a href=&quot;http://webassembly.org/docs/semantics/#types&quot;&gt;WebAssembly documentation&lt;/a&gt;, will refer to these basic types with the short names i32, i64, f32, and f64 respectively.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;import_section&quot;&gt;&lt;strong&gt;import section&lt;/strong&gt;&lt;/a&gt; declares any external dependencies by listing module name, field name and type for each function, value or data required:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dumb-math&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;quadruple&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func_type&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;// func #0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dumb-math&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;global_type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;immutable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s up to the host system (e.g. web browser) to resolve these imports and this is how runtime-dynamic linking is made possible in WASM, and is also the foreign-function interface for interacting with non-WASM functions, as we will see later.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;function_section&quot;&gt;&lt;strong&gt;function section&lt;/strong&gt;&lt;/a&gt; declares indexes for each function that is later defined in the code section, where the position in the list is the function’s index and the value its type. The effective function index starts at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;number of func_type imports&lt;/code&gt;, meaning that the effective list of functions available in the module is the &lt;a href=&quot;#import_section&quot;&gt;import section&lt;/a&gt; list filtered on function imports joined by the function-section list.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func_type&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// func #1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func_type&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// func #2&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func_type&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// func #3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we later call functions, we will refer to them by their index (“func #N” above, where N is the function’s index.)&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;table_section&quot;&gt;&lt;strong&gt;table section&lt;/strong&gt;&lt;/a&gt; defines any number of &lt;a href=&quot;https://github.com/WebAssembly/design/blob/master/Semantics.md#table&quot;&gt;tables&lt;/a&gt;. Tables are mechanisms for mapping opaque values which can not be represented in nor directly accessed by WebAssembly, like for instance a JavaScript object or an operating-system file handle. This feature bridges the gap between low-level, untrusted linear memory and high-level opaque handles/references at the cost of a bounds-checked table indirection. We won’t go into more detail about tables.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;memory_section&quot;&gt;&lt;strong&gt;memory section&lt;/strong&gt;&lt;/a&gt; defines the optional memory of the module by defining its initial size and
optionally how large it is expected to expand. The &lt;a href=&quot;#data_section&quot;&gt;data section&lt;/a&gt; can be used to initialize the memory.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;global_section&quot;&gt;&lt;strong&gt;global section&lt;/strong&gt;&lt;/a&gt; declares any number of mutable or immutable global variables for the module. These are equivalent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static&lt;/code&gt; variables in C and C++.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;export_section&quot;&gt;&lt;strong&gt;export section&lt;/strong&gt;&lt;/a&gt; declares any parts of the module that can be accessed by the host environment, not including the special start function, which we will get to in a just a few sentences.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;half&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above would export function 1 as “half”. If we look at the &lt;a href=&quot;#function_section&quot;&gt;function section&lt;/a&gt; above, we can see that func #1’s type is func_type #1, so the host environment will see this as:&lt;/p&gt;

&lt;div class=&quot;language-ts highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;half&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arg0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;int64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In addition to functions, modules can also export tables, memory segments and global variables to the outside world.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;start_section&quot;&gt;&lt;strong&gt;start section&lt;/strong&gt;&lt;/a&gt; designates a function index for a function to be called when the module is loading and is the mechanism that can be used to make a module an executable program, or used to dynamically initialize globals or memory of a module.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;element_section&quot;&gt;&lt;strong&gt;element section&lt;/strong&gt;&lt;/a&gt; allows a module to initialize the contents of a table imported from the outside or defined in the &lt;a href=&quot;#table_section&quot;&gt;table section&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a name=&quot;code_section&quot;&gt;&lt;strong&gt;code section&lt;/strong&gt;&lt;/a&gt; is probably the bulk of most WebAssembly modules as it defines all code for all functions in the module. The function bodies are defined in the same order as their respective function indexes in the &lt;a href=&quot;#function_section&quot;&gt;function section&lt;/a&gt;, not including imports of course. Our “half” function’s body could be defined like this:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// push parameter #0 on stack (our dividend)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// push constant int64 &quot;2&quot; on stack (our divisor)&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div_u&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// unsigned division; pushes result onto stack&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// ends function, resulting in one i64 (top of stack)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You probably already guessed it: WebAssembly is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Stack_machine&quot;&gt;stack machine&lt;/a&gt;
which means that we push and pop values onto and off from a virtual stack. Most WASM operator codes (“opcode” for short) takes and/or adds a well-defined amount of values to the stack.&lt;/p&gt;

&lt;p&gt;Let’s walk through to see &lt;a name=&quot;stack&quot;&gt;what happens to the stack&lt;/a&gt; if we run the code of our “half” function:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/res/wasm/stack.svg&quot; style=&quot;width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A few things to note about this diagram:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The stack is abstract in the sense that we can’t index into it, measure it or inspect it;
we can only push to and pop from it. This leaves the door open to efficient VM implementations.&lt;/li&gt;
  &lt;li&gt;The 4th step above is probably never an actual state in a real VM as there would be no reason to
actually empty the stack; the step illustrates what is &lt;em&gt;theoretically&lt;/em&gt; happening to the stack.&lt;/li&gt;
  &lt;li&gt;At the end the function implicitly returns and the caller will have one value (the result)
available on the stack.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are &lt;a href=&quot;https://github.com/WebAssembly/design/blob/master/Semantics.md#32-bit-integer-operators&quot;&gt;quite a lot of number operators defined by WASM 1&lt;/a&gt; — too many to list here.
However, you might find it comforting knowing that in addition to all basic operations you’d expect, like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;div&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt;, there are several other useful common numeric operations defined as opcodes rather than being left to be implemented on top of other, simpler instructions. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eqz&lt;/code&gt; efficiently tests if an integer operand is zero, minimizing stack thrash from otherwise pushing the constant &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; and calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eq&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;popcnt&lt;/code&gt; counts the number of bits set in an integer&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ceil&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;floor&lt;/code&gt; performs the &lt;a href=&quot;https://en.wikipedia.org/wiki/Floor_and_ceiling_functions&quot;&gt;ceiling and floor functions&lt;/a&gt; on a floating-point number&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sqrt&lt;/code&gt; calculates the square root of a floating-point number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a versatile repertoire of conversion operators as well,
for converting between any two types with well-defined behavior.&lt;/p&gt;

&lt;p&gt;Last but not least is the &lt;a name=&quot;data_section&quot;&gt;&lt;strong&gt;data section&lt;/strong&gt;&lt;/a&gt; which can be used to initialize imported or local memory:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data_segment&lt;/span&gt;
  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;                          &lt;span class=&quot;c1&quot;&gt;// linear memory index&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;init_expr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// byte offset at which to place the data&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x2a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This would initialize bytes [4–8] in the 0th memory with the provided byte values, which if read as an unsigned i32 yields the number “42”.&lt;/p&gt;

&lt;h2 id=&quot;managing-data-and-values&quot;&gt;Managing data and values&lt;/h2&gt;

&lt;p&gt;We’ve looked at the WebAssembly value stack for saving and reading basic values.
There are a few more ways to manage data and state in your modules.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#stack&quot;&gt;&lt;strong&gt;Stack&lt;/strong&gt;&lt;/a&gt;: Machine operations takes their operands from—and put their result onto—the stack.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#locals&quot;&gt;&lt;strong&gt;Locals&lt;/strong&gt;&lt;/a&gt; and &lt;a href=&quot;#globals&quot;&gt;&lt;strong&gt;globals&lt;/strong&gt;&lt;/a&gt; are like variables:
named and can hold any of the same basic types as the stack can hold (i32, et al.)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#memory&quot;&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/a&gt;: Random-accessible array of bytes where we can store anything we want.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#elements&quot;&gt;&lt;strong&gt;Elements&lt;/strong&gt;&lt;/a&gt;: “Handles” for opaque foreign values (like OS file handles.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a name=&quot;locals&quot;&gt;&lt;strong&gt;Locals&lt;/strong&gt;&lt;/a&gt; are like variables in many higher-level programming languages:
we can name them, store values to them and load values from them. Locals are named using function-local integer index.&lt;/p&gt;

&lt;p&gt;When defining a function body, we can declare any number of locals for the function’s code. Parameters to a function are also locals and the “name” index of locals start at 0 with the first function parameter and continue incrementing with each additional parameter and eventually with each listed local of the function body. Locals are always initialized to zero (all their bits are 0.)&lt;/p&gt;

&lt;p&gt;In our &lt;a href=&quot;#snippet-5&quot;&gt;example earlier in this article&lt;/a&gt; we used the operation &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get_local&lt;/code&gt; to push the value of the 1st function parameter onto the stack. We can also perform the reverse: popping a value off of the stack and storing it into a local.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// for the purpose of demonstration, push &quot;123&quot; to the stack&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;set_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// pop &quot;123&quot; off of the stack and store it into local #0&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// use the stack for other operations...&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// &quot;123&quot; is pushed to the top of the stack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Locals makes it possible to hold on to temporary values while performing other operations that would otherwise replace or move a value off the stack.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;globals&quot;&gt;&lt;strong&gt;Globals&lt;/strong&gt;&lt;/a&gt; are a form of module-wide locals with their own indexes and operators,
but otherwise shares the semantics of locals. The global index starts with any imported globals and continues incrementing with any globals defined in the &lt;a href=&quot;#global_section&quot;&gt;global section&lt;/a&gt;. We can load and store global values using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get_global&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_global&lt;/code&gt; operations.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;memory&quot;&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/a&gt; is the most flexible as it allows us to store any data we can imagine, but trades ease-of use for flexibility:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/WebAssembly/design/blob/master/Semantics.md#linear-memory&quot;&gt;Memory is linear&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Size of a memory is an even multiple of the memory-page size, which is 64 KiB&lt;/li&gt;
  &lt;li&gt;Memory can be either imported or declared by the module.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Memory being “linear” means that there’s no random allocator operators available — all memory addresses used in a module’s code are expressed in terms of byte offsets from the beginning of a memory segment. WASM being a low-level format, this makes a lot of sense. It’s up to the higher-level language that targets WASM to provide memory management on top of this linear memory space, if needed.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;elements&quot;&gt;&lt;strong&gt;Elements&lt;/strong&gt;&lt;/a&gt; are opaque “value handles” that mean something to the host environment, but are opaque to WebAssembly. For example an element might represent an operating-system file handle or a JavaScript object if the host environment runs JavaScript.&lt;/p&gt;

&lt;p&gt;Elements are cool, but &lt;strong&gt;memory&lt;/strong&gt; is a lot more interesting, so let’s get back to learning about memory and what it enables us to do.&lt;/p&gt;

&lt;p&gt;Future versions of WASM might allow multiple memory segments to be used, but version 1 only uses a single segment per module, which simplifies a lot of things, like memory operators:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i32.load alignment offset&lt;/code&gt; loads a 32-bit integer from the byte range [start..start+4), where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start&lt;/code&gt; is an integer operand popped from the stack&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i64.store16 alignment offset&lt;/code&gt; stores a 16 bit integer, by wrapping a 64-bit integer popped off of the stack, to the byte range &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[start-start+2)&lt;/code&gt;, where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start&lt;/code&gt; is an integer operand which is also popped from the stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following code stores an i32 “123” at byte range [4..7]:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// byte-sized address&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// value to store&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 2 = 32-bit/4-byte alignment, 0 = offset&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can load the value back onto the stack at a later time:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// after this, the top of the stack is i32 &quot;123&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The flexibility of memory is not only in the fact that we can load things that were stored in the past—we can do that with locals too—but that memory is persistent for the duration of a module’s lifetime, meaning we can access values across functions, interpret the same data as different types, and store byte-sized values in a much more compact manner than locals, globals and the stack uses.&lt;/p&gt;

&lt;p&gt;Imagine that we want to call a function with the name of our favorite buddy, “Lolcat”. Encoding the name as UTF-8 text, each character only needs 1 byte (so 6 bytes in total plus some additional sentinel or length value). A naïve and very inflexible way of doing this would be to push each character onto the stack and have the callee accept some predetermined number of parameters,
e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function (c0, c1, c2, c3, c4, c5 i32) :void&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x4c&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 'L'&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6f&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 'o'&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6c&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 'l'&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x63&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 'c'&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x61&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 'a'&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x74&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 't'&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// call a function that takes exactly 6 parameters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Not only is this ridiculously inflexible, but it requires a lot of stack space — each “card on the stack” is one machine word large. On a 32-bit system (or 32-bit virtual machine), that means each letter of our “Lolcat” string occupies 4 bytes, bringing the total to 24 bytes. Another thing to consider is that the stack, although abstract, has a limit; if we push too many values to the stack without popping some off, the host machine will panic and crash our module.&lt;/p&gt;

&lt;p&gt;This is a task for memory. Instead let’s imagine the callee function to take just a single argument that is the &lt;em&gt;memory address&lt;/em&gt; of the string, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function (addr i32) :void&lt;/code&gt;. First, when we assemble out module we initialize a part of module’s memory with the “Lolcat” string:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data_segment&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;init_expr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// byte offset at which to place the data&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x4c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6f&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x63&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x61&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x74&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice how in this example we place an additional “sentinel” zero byte at the end of the string. This is common in languages like C but generally discouraged. If you’re writing a real program you probably want to prefix the string with its length instead, but the “sentinel byte” will do for our example.&lt;/p&gt;

&lt;p&gt;We can now call the function with the address (4) of the string:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// byte offset into memory, &quot;passed&quot; as an argument to...&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// call the receiving function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The receiving function would then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load&lt;/code&gt; whatever parts of the string it needs from memory. For instance, say that it calls an imported “putc” function (which puts a byte to the programs stdout stream):&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load8_u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;putc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In WASM we have declared the need for one additional local (local #1; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;byte&lt;/code&gt; variable) in our function and can now implement the equivalent functionality:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// declares a &quot;label&quot; at it's &quot;end&quot;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// declares a &quot;label&quot; right here&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// byte = i32.load8_u(addr)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// push addr&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load8_u&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// push the byte at addr as an i32&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;tee_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// store the byte to local 1, but don't pop it&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// if (byte == 0) { break }&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;eqz&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// (x i32) =&amp;gt; i32(x == 0 ? 1 : 0)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;br_if&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// if the byte was zero, jump to end of &quot;block&quot;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// putc(byte)&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// push byte&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;// call imported &quot;putc&quot; function with the byte&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// addr = addr + 1&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// push addr&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// push i32 &quot;1&quot;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// push result from addr + 1&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;set_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;// store new address to &quot;addr&quot; local&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// continue&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// jump to &quot;loop&quot; (i.e. continue looping)&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// end of &quot;block&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;addressing-memory&quot;&gt;Addressing memory&lt;/h2&gt;

&lt;p&gt;You may have noticed that we provide two immediate values to the load and store operators.
The first immediate value is an alignment “hint” that is a power-of 2 encoded as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log2(alignment)&lt;/code&gt;. In practice this means that the alignment immediate is one of the following values:
0 = 8-bit, 1 = 16-bit, 2 = 32-bit, and 3 = 64-bit.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If the effective address of a memory access is a multiple of the alignment attribute value of the memory access, the memory access is considered aligned, otherwise it is considered misaligned. Aligned and misaligned accesses have the same behavior.&lt;sup id=&quot;fnref:sem-mem-align&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:sem-mem-align&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The alignment hint is like a promise to the virtual machine executing our code that “the effective address is going to be aligned at N bits”, information which the VM will use to optimize our code. When we promise a certain alignment but fail to keep that promise by providing an address that is misaligned, the operation will likely be &lt;em&gt;much&lt;/em&gt; slower than if we had provided an aligned effective address.&lt;/p&gt;

&lt;p&gt;Therefore as a rule of thumb, you should only promise what you can keep — hint at the largest possible alignment for any operation, but no larger than the native alignment (32-bit for wasm32, 64-bit for wasm64.)&lt;/p&gt;

&lt;p&gt;The second immediate for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;store&lt;/code&gt; operators is the address offset. This has proven to be a point of confusion already, so let’s clarify what the offset really is, what the effective address is and what happens to memory as we store and load values.&lt;/p&gt;

&lt;p&gt;Here’s an illustration of the beginning of linear memory, initialized to zero:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/res/wasm/memory.svg&quot; style=&quot;width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;effective address&lt;/strong&gt; is the offset in bytes measured from the beginning of the memory. The effective address is the sum of the address operand and the offset immediate.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ebnf&quot;&gt;effective-address = address-operand + offset-immediate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might ask “why would I ever need offset if I have an address operand”? And it’s a fair question; as we’ve seen in previous examples, we can provide a constant value (e.g. using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i32.const&lt;/code&gt;) for the address operand. However when we start using dynamic addresses, like we did in our &lt;a href=&quot;#snippet-14&quot;&gt;“print_str” function&lt;/a&gt; earlier, it can be very useful for a compiler to add a constant offset to all memory operations of a module’s functions in order to “relocate” one area of memory to another.&lt;/p&gt;

&lt;p&gt;WASM provides a rich set of memory operators for each of the four basic types, allowing reading some number of bytes as some kind of number. For instance, we can store a 64-bit integer in two bytes by truncating the value to a 16-bit integer:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// address-operand = 3&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// value&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;store16&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// alignment = 1 = 16-bit, offset-immediate = 3&lt;/span&gt;
                 &lt;span class=&quot;c1&quot;&gt;// effective-address = 3 + 3 = 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since we hint at a 16-bit alignment and the effective address is an even multiple of 2 (2 bytes = 16 bits), this is an optimized (aligned) store. Our memory now looks like this, with the segment stored to is marked with dark background color:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/res/wasm/memory-1.svg&quot; style=&quot;width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;WebAssembly always uses little-endian encoding for values in memory, no matter what the host platform’s native “endianess” is. This means that the 16-bit integer “1234” is encoded as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xd2&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x04&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we had stored a 32-bit or 64-bit value instead, the store would have been &lt;em&gt;misaligned&lt;/em&gt; and inefficient since effective-address “6” is in the middle of a 32-bit and 64-bit word:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;store32&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// align = 2 = 32-bit, offset = 3  =&amp;gt;  addr = 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/res/wasm/memory-2.svg&quot; style=&quot;width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The red arrows indicate that for the store to be aligned as promised (at 32-bit boundaries), we’d have to either decrease or increase our address by 2 (i.e. 6 ± 2).&lt;/p&gt;

&lt;p&gt;A load or store is aligned when the effective address is &lt;em&gt;at the boundary&lt;/em&gt; of the promised alignment magnitude.&lt;/p&gt;

&lt;p&gt;Let’s adjust the offset-immediate to get a 32-bit aligned store:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;store32&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// align = 2 = 32-bit, offset = 5  =&amp;gt;  addr = 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/res/wasm/memory-3.svg&quot; style=&quot;width:100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Optimal, aligned store.&lt;/p&gt;

&lt;h2 id=&quot;converting-between-and-reinterpreting-values&quot;&gt;Converting between and reinterpreting values&lt;/h2&gt;

&lt;p&gt;We are free to interpret any bytes as any value. For instance we can load the four bytes representing a 16-bit integer that we stored above as a 32-bit floating-point number:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// address-operand = 4&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// align = 2 = 32-bit, offset = 4  =&amp;gt;  addr = 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The top of the stack now contains a f32 representing roughly the number “1.7292e-42”, which is possibly not what you would have expected. Remember, we didn’t convert a number from one type to another, we just interpreted the raw data used to represent one type as another type.&lt;/p&gt;

&lt;p&gt;If our intention was to load the i32 value as an equivalent f32 number, we instead use one of the numeric conversion operators for the destination type:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;// address-operand = 4&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;// align = 2 = 32-bit, offset = 4  =&amp;gt;  addr = 8&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;f32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;convert_u_i32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The top of the stack is now an f32 with the value “1234.0”.&lt;/p&gt;

&lt;p&gt;Floating-point numbers are always “signed”, but integers can be unsigned. “But… we’ve been working with i32’s all article long and I haven’t seen any sign-specific operators!?” Most of the operators we’ve been using so far only needs to know the size of the data, and doesn’t care if the value is meant to be interpreted as being signed or not. &lt;a name=&quot;sign-agnostic&quot;&gt;WebAssembly integer values are fundamentally &lt;em&gt;sign-agnostic&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are of course a few operations which requires knowing whether its operands are signed or unsigned. For instance, the “less than” operator needs to know if it’s comparing potentially negative numbers.&lt;/p&gt;

&lt;p&gt;Operators that are sign-dependent has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_s&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_u&lt;/code&gt; suffix. Here are a few:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lt_s&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;//   signed-i32  &amp;lt;    signed-i32&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lt_u&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// unsigned-i32  &amp;lt;  unsigned-i32&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div_s&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;//   signed-i32  /    signed-i32&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;javascript-api&quot;&gt;JavaScript API&lt;/h2&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;Note: The following section is out of date. Please refer to the &lt;a href=&quot;https://webassembly.github.io/spec/js-api/&quot;&gt;official documention&lt;/a&gt;.&lt;/em&gt;&lt;small&gt;&lt;/small&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;As “WebAssembly” hints with “Web” in its name, the first useful WebAssembly platforms are the cutting-edge versions of the most popular web browsers:
&lt;a href=&quot;https://www.google.com/chrome/browser/canary.html&quot;&gt;Chrome&lt;/a&gt;,
&lt;a href=&quot;https://www.mozilla.org/firefox/channel/desktop/#nightly&quot;&gt;Firefox&lt;/a&gt;,
&lt;a href=&quot;https://webkit.org/downloads/&quot;&gt;Safari&lt;/a&gt; and
&lt;a href=&quot;https://github.com/Microsoft/ChakraCore/&quot;&gt;Edge&lt;/a&gt;. At the time of writing this article, WebAssembly needs to be enabled through the browser’s advanced settings. In Chrome the setting is found under “flags” (chrome://flags/#enable-webassembly).&lt;/p&gt;

&lt;p&gt;I’m not going to talk much about this since there’s plenty of good information on the
&lt;a href=&quot;https://webassembly.github.io/spec/js-api/&quot;&gt;JavaScript browser API&lt;/a&gt;.
Here’s an example of loading a module, “instantiating” it (running it) and finally calling one of
its exported functions from JavaScript:&lt;/p&gt;

&lt;blockquote id=&quot;message2&quot;&gt;&lt;/blockquote&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
(function(){
  var msg = document.getElementById('message2');
  if (!window.WebAssembly) {
    msg.innerText = &quot;Note: The web browser you're currently viewing this with &quot;+
    &quot;does not support WebAssembly. The below example will not work in this web browser.&quot;;
  } else {
    msg.parentNode.removeChild(msg);
  }
})();
&lt;/script&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;WebAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Uint8Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;`00 61 73 6d  0d 00 00 00  01 09 02 60  00 00 60 01
7f 01 7f 03  03 02 00 01  05 04 01 00  80 01 07 07
01 03 66 6f  6f 00 01 08  01 00 0a 3a  02 02 00 0b
35 01 01 7f  20 00 41 04  6c 21 01 03  40 01 01 01
0b 03 7f 41  01 0b 20 01  41 e4 00 6c  41 cd 02 20
01 1b 21 01  41 00 20 01  36 02 00 41  00 21 01 41
00 28 02 00  0f 0b 0b 0e  01 00 41 00  0b 08 00 00
00 00 2c 00  00 00`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;[\s\r\n]&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;+/g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;WebAssembly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;foo(1) =&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;foo(2) =&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;foo(3) =&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we paste this into a WebAssembly-enabled browser’s console, we should see the result of some simple computations done by the module:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;foo(1) =&amp;gt; 400
foo(2) =&amp;gt; 800
foo(3) =&amp;gt; 1200
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This hopefully gives you a hint of how WASM can inter-operate with JavaScript to actually be practical and useful as an incremental step toward a WebAssembly-powered app. Perhaps you’ll write your UI in React &amp;amp; JavaScript, but write something like a JPEG encoder or file-format parser in WASM, having it all play nicely together.&lt;/p&gt;

&lt;h2 id=&quot;wasm-util&quot;&gt;wasm-util&lt;/h2&gt;

&lt;p&gt;I’ve put together a small collection of TypeScript/JavaScript code for working with WASM dubbed &lt;a href=&quot;https://github.com/rsms/wasm-util&quot;&gt;wasm-util&lt;/a&gt;. This code has no dependencies and is structured in a way that makes it possible to use only a few select source files for tasks that only require some functionality.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ast&lt;/code&gt; provides a full TypeScript type system for &lt;a href=&quot;https://github.com/WebAssembly/design&quot;&gt;the complete WebAssembly specification&lt;/a&gt; and constructors for all parts of a WebAssembly module.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;emit&lt;/code&gt; provides helpers for emitting WASM byte code from an AST.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;repr&lt;/code&gt; generates a human-readable text representation of an AST.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lbtext&lt;/code&gt; generates &lt;a href=&quot;https://github.com/WebAssembly/design/blob/master/TextFormat.md&quot;&gt;Linear Bytecode text&lt;/a&gt; from AST instructions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;See &lt;a href=&quot;https://github.com/rsms/wasm-util#readme&quot;&gt;wasm-util readme&lt;/a&gt; for a complete listing of functionality.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I found myself relying on a very complicated tool chain (source build of llvm, binaryen, etc) while all I was looking for was to get close to WebAssembly. The prime component of wasm-util is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ast&lt;/code&gt; which provides a convenient way of building complete WASM modules, with full static type-checking if you’re using TypeScript.&lt;/p&gt;

&lt;p&gt;Following is an example of building a module that provides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factorial&lt;/code&gt; function.
Let’s start by describing the function we’re making in a C-like syntax:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The equivalent WebAssembly code looks like this:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// push parameter #0 on stack.&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// push constant int64 &quot;0&quot; on stack.&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;eq&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// execute &quot;eq&quot; which pops two operands from stack&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;//  and pushes int32 &quot;1&quot; or &quot;0&quot; on stack.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;// pops one int32 from stack; if its not &quot;0&quot;:&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//   push constant int64 &quot;1&quot; on stack.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;// else (if operand was &quot;0&quot;):&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//   push parameter #0 on stack. [1]&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//   push parameter #0 on stack.&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;//   push constant int64 &quot;1&quot; on stack.&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sub&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;//   execute &quot;sub[tract]&quot; which pops two operands&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;//    from stack (parameter #0 and constant &quot;1&quot;)&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;//    and finally pushes the result int64 on stack.&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;//   call function #0 (&quot;factorial&quot;) which pops one&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;//    int64 from the stack and when it returns an&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;//    int64 has been pushed on stack&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mul&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;//   execute &quot;sub[tract]&quot; which pops two operands&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;//    from stack ([1] and result from function call)&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;//    and finally pushes the resulting int64 on stack&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;// ends function, returning one int64 result (on stack.)&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;// Stack now contains one int64 value that's the result from one of&lt;/span&gt;
               &lt;span class=&quot;c1&quot;&gt;// the two branches above.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above code was printed by &lt;a href=&quot;https://github.com/rsms/wasm-util/blob/master/src/lbtext.ts&quot;&gt;lbtext&lt;/a&gt;, for which we provided an AST built with the &lt;a href=&quot;https://github.com/rsms/wasm-util/blob/master/src/ast.ts&quot;&gt;ast&lt;/a&gt; module:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;wasm-util/ast&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;type_section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;func_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// type index = 0&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;function_section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;varuint32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// function index = 0, using type index 0&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;export_section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// exports &quot;factorial&quot; as function at index 0&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;export_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;str_ascii&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;factorial&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;external_kind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;varuint32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;

  &lt;span class=&quot;nx&quot;&gt;code_section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// body of function at index 0:&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;function_body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* additional local variables here */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;if_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// i64 = result type of `if` expression&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// condition&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// then&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// else&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;varuint32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 0 = function index&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;]))])])]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can now generate WASM bytecode through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Emittable&lt;/code&gt; interface:&lt;/p&gt;

&lt;div class=&quot;language-ts highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;emitbuf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BufferedEmitter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ArrayBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;emit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;emitbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// the array buffer (emitbuf.buffer) now contains the complete module code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or print a human-readable representation of the AST:&lt;/p&gt;

&lt;div class=&quot;language-ts highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;strRepr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;wasm-util/repr&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;strRepr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Which yields the following in the console:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;func_type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;export_entry&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;factorial&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;external_kind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;function_body&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;eq&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mul&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sub&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get_local&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A complete version of this “factorial” demo can be found as &lt;a href=&quot;https://github.com/rsms/wasm-util/blob/master/test/build_factorial_test.ts&quot;&gt;a unit test in the wasm-util repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;a href=&quot;https://github.com/rsms/wasm-util&quot;&gt;wasm-util&lt;/a&gt; you can get started playing around with building your own WebAssembly programs right now with a minimum amount of effort. Perhaps you’re the author of a compiled language and are interested in targeting WASM — this might be a good way to get started.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
———&lt;/p&gt;

&lt;p&gt;If it’s not already clear from this article: I believe in a bright future for WebAssembly. The web is an amazing concept that is currently falling short carrying a heavy legacy from the past. In order to bring truly great experiences to the web and blur the lines of what is and what isn’t a “native” experience, WebAssembly—or something else like it—needs to happen.&lt;/p&gt;

&lt;p&gt;At &lt;a href=&quot;https://www.figma.com/&quot;&gt;Figma&lt;/a&gt; we’re building one of the most complex and performance-critical apps there is on the web platform today, and we are very excited to start moving from &lt;a href=&quot;http://asmjs.org/&quot;&gt;ASM.js&lt;/a&gt; to WebAssembly. &lt;a href=&quot;https://www.figma.com/careers&quot;&gt;Does this stuff excite you? We’re hiring :)&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;wasm-as-intermediate-representation&quot;&gt;WASM as Intermediate Representation&lt;/h2&gt;

&lt;p&gt;As I was writing this article it slowly dawned on me that WebAssembly might be an excellent IR (Intermediate Representation) for compilers of all sorts.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;An intermediate representation is a representation of a program part way between the source and target languages. A good IR is one that is fairly independent of the source and target languages, so that it maximizes its ability to be used in a retargetable compiler.&lt;sup id=&quot;fnref:ray-ir&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:ray-ir&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
  &lt;li&gt;WebAssembly really has no dependencies on anything “web” and its module and bytecode format is at such a low level that it can be used to represent any other higher-level program.&lt;/li&gt;
  &lt;li&gt;There are several high-quality VMs being implemented, many of them in web browser, which can execute WASM programs efficiently, making distribution a bliss (the web!)&lt;/li&gt;
  &lt;li&gt;WASM code can be translated to machine code.&lt;/li&gt;
  &lt;li&gt;WASM can be interpreted and emulated which makes debugging a whole lot more pleasant than debugging programs which only run natively. How about we stop the world and interactively inspect the stack? How about we play back an interpreted recording that reproduces a bug deterministically?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Want to help out? &lt;a href=&quot;http://webassembly.org/community/feedback/&quot;&gt;Join the community&lt;/a&gt; and come hang in &lt;a href=&quot;irc://irc.w3.org:6667/#webassembly&quot;&gt;#webassembly on irc.w3c.org&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:sem-mem-align&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://github.com/WebAssembly/design/blob/master/Semantics.md#alignment&quot;&gt;WebAssembly Semantics: Memory Alignment&lt;/a&gt; &lt;a href=&quot;#fnref:sem-mem-align&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:ray-ir&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://cs.lmu.edu/~ray/notes/ir/&quot;&gt;Intermediate Representations (Ray Toal)&lt;/a&gt; &lt;a href=&quot;#fnref:ray-ir&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>Gotalk</title>
    <link href="https://rsms.me/gotalk"/>
    <updated>2015-01-21T00:00:00+00:00</updated>
    <id>https://rsms.me/gotalk</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/rsms/gotalk&quot;&gt;Gotalk&lt;/a&gt; exists to make it easy for programs to &lt;em&gt;talk with one another over the internet&lt;/em&gt;, like a web app coordinating with a web server, or a bunch of programs dividing work amongst eachother.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/res/gotalk/gotalk-comic.png&quot; alt=&quot;A terribly boring amateur comic strip&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Gotalk takes the natural approach of &lt;em&gt;bidirectional&lt;/em&gt; and &lt;em&gt;concurrent&lt;/em&gt; communication — any peer have the ability to expose “operations” as well as asking other peers to perform operations. The traditional restrictions of who can request and who can respond usually associated with a client-server model is nowhere to be found in gotalk.&lt;/p&gt;

&lt;h2 id=&quot;gotalk-in-a-nutshell&quot;&gt;Gotalk in a nutshell&lt;/h2&gt;

&lt;h3 id=&quot;bidirectional&quot;&gt;Bidirectional&lt;/h3&gt;

&lt;p&gt;There’s no discrimination on capabilities depending on who connected or who accepted. Both “servers” and “clients” can expose operations as well as send requests to the other side.&lt;/p&gt;

&lt;h3 id=&quot;concurrent&quot;&gt;Concurrent&lt;/h3&gt;

&lt;p&gt;Requests, results, and notifications all share a single connection without blocking eachother by means of &lt;a href=&quot;http://en.wikipedia.org/wiki/Protocol_pipelining&quot;&gt;&lt;em&gt;pipelining&lt;/em&gt;&lt;/a&gt;. There’s no serialization on request-result or even for a single large message, as the gotalk protocol is frame-based and multiplexes messages over a single connection. This means you can perform several requests at once without having to think about queueing or blocking.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/res/gotalk/gotalk-pipeline-diagram.png&quot; alt=&quot;Diagram of how Gotalk uses connection pipelining&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;simple&quot;&gt;Simple&lt;/h3&gt;

&lt;p&gt;Gotalk has a simple and opinionated API with very few components. You expose an operation via “handle” and send requests via “request”.&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;In&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;practical&quot;&gt;Practical&lt;/h3&gt;

&lt;p&gt;Gotalk includes a &lt;a href=&quot;https://github.com/rsms/gotalk/tree/master/js&quot;&gt;JavaScript implementation&lt;/a&gt; for Web Sockets alongside the full-featured Go implementation, making it easy to build modern web applications. The Gotalk source code also includes &lt;a href=&quot;https://github.com/rsms/gotalk/tree/master/examples&quot;&gt;a number of easily-readable examples&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;debuggable&quot;&gt;Debuggable&lt;/h3&gt;

&lt;p&gt;The Gotalk protocol’s wire format is byte based for easy on-the-wire inspection of data. It can thus be operated over any reliable byte transport. For example, here’s a protocol message representing a request for an operation “hello” with the parameter “world”:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;r001005hello00000005world
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;by-example&quot;&gt;By example&lt;/h2&gt;

&lt;p&gt;As just mentioned earlier, there are a few examples in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;examples&lt;/code&gt; directory demonstrating how you can use Gotalk. But let’s explore a simple program right here — a little something written in &lt;a href=&quot;http://golang.org/&quot;&gt;Go&lt;/a&gt; which demonstrates the use of an operation named “greet”:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GreetOut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetOut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Serve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tcp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;localhost:1234&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tcp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;localhost:1234&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GreetOut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rasmus&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greeting: %+v&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s look at the above example in more detail, broken apart to see what’s going on.&lt;/p&gt;

&lt;p&gt;We begin by importing the gotalk library together with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log&lt;/code&gt; which we use for printing to the console:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;log&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;github.com/rsms/gotalk&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We define two types: Expected input (request parameters) and output (result) for our “greet” operation:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetIn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;`json:&quot;name&quot;`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetOut&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Greeting&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;`json:&quot;greeting&quot;`&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Registers a process-global request handler for an operation called “greet” accepting parameters of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GreetIn&lt;/code&gt;, returning results of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GreetOut&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GreetOut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetOut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally at the bottom of our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;server&lt;/code&gt; function we call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gotalk.Serve&lt;/code&gt;, which starts a local TCP server on port 1234:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Serve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tcp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;localhost:1234&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;client&lt;/code&gt; function we start by connecting to the server:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tcp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;localhost:1234&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally we send a request for “greet” and print the result:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetOut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GreetIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Rasmus&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fatalln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greeting: %+v&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Greeting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Hello&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rasmus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;gotalk-in-the-web-browser&quot;&gt;Gotalk in the web browser&lt;/h2&gt;

&lt;p&gt;Gotalk is implemented not only in the full-fledged Go package, but also in a &lt;a href=&quot;https://github.com/rsms/gotalk/tree/master/js&quot;&gt;JavaScript library&lt;/a&gt;. This allows writing web apps talking Gotalk via Web Sockets possible.&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// server.go:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;net/http&quot;&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;github.com/rsms/gotalk&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HandleBufferRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;echo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/gotalk&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WebSocketHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ListenAndServe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;:1234&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;panic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ListenAndServe: &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In our html document, we begin by registering any operations we can handle:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gotalk.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Hello &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can’t “listen &amp;amp; accept” connections in a web browser, but we can “connect” so we do just that, connecting to “/gotalk” which is where we registered &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gotalk.WebSocketHandler&lt;/code&gt; in our server.&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gotalk.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Hello &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ws://&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/gotalk&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// s is a gotalk.Sock&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is enough for enabling the &lt;em&gt;server&lt;/em&gt; to do things in the &lt;em&gt;browser&lt;/em&gt; …&lt;/p&gt;

&lt;p&gt;But you probably want to have the &lt;em&gt;browser&lt;/em&gt; send requests to the &lt;em&gt;server&lt;/em&gt;, so let’s send a “echo” request just as our connection opens:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ws://&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/gotalk&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello world&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;echo failed:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;echo result:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We could rewrite our code like this to allow some UI component to send a request:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;gotalk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ws://&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/gotalk&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;echo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello world&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;echo failed:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;echo result:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The request will fail with an error “socket is closed” if the user clicks our button while the connection isn’t open.&lt;/p&gt;

&lt;p&gt;If you’re interested in learning more about using Gotalk with web browsers, check out &lt;a href=&quot;https://github.com/rsms/gotalk/tree/master/examples/websocket&quot;&gt;examples/websocket&lt;/a&gt; and &lt;a href=&quot;https://github.com/rsms/gotalk/tree/master/examples/websocket-chat&quot;&gt;examples/websocket-chat&lt;/a&gt; which shows how to use most of the Gotalk functionality to make interactive websites.&lt;/p&gt;

&lt;h2 id=&quot;protocol-and-wire-format&quot;&gt;Protocol and wire format&lt;/h2&gt;

&lt;p&gt;The wire format is designed to be human-readable and flexible; it’s byte-based and can be efficiently implemented in a number of environments ranging from HTTP and WebSocket in a web browser to raw TCP in Go or C. The protocol provides only a small set of operations on which more elaborate operations can be modeled by the user.&lt;/p&gt;

&lt;p&gt;Here’s a complete description of the protocol:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;conversation&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProtocolVersion&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;         &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StreamRequest&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleResult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StreamResult&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ErrorResult&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ProtocolVersion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;SingleRequest&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;r&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;StreamRequest&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StreamReqPart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;StreamReqPart&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;p&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SingleResult&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;R&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;StreamResult&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;S&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StreamResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ErrorResult&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;E&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestID&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Notification&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;n&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;requestID&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text3&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;            &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text3&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;text3&lt;/span&gt;           &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text3Size&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text3Value&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;text3Size&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hexUInt3&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;text3Value&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text3Size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;payload&lt;/span&gt;         &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payloadSize&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;payloadData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;payloadSize&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hexUInt8&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;payloadData&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;payloadSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;hexUInt3&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;hexUInt8&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A conversation begins with the protocol version:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;00  -- ProtocolVersion 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If the version of the protocol spoken by the other end is not supported by the reader, the connection is terminated and the conversation never starts. Otherwise, any messages are read and/or written.&lt;/p&gt;

&lt;p&gt;This is a “single-payload” request …&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+----------------- SingleRequest
|  +---------------- requestID   &quot;001&quot;
|  |  +------------- text3Size   4
|  |  |   +--------- operation   &quot;echo&quot;
|  |  |   |       +- payloadSize 25
|  |  |   |       |
r001004echo00000019{&quot;message&quot;:&quot;Hello World&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;… and a corresponding “single-payload” result:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+----------------- SingleResult
|  +---------------- requestID   &quot;001&quot;
|  |       +-------- payloadSize 25
|  |       |
R00100000019{&quot;message&quot;:&quot;Hello World&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each request is identified by exactly three bytes—the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;requestID&lt;/code&gt;—which is requestor-specific and has no purpose beyond identity, meaning the value is never interpreted.&lt;/p&gt;

&lt;p&gt;These “single” requests &amp;amp; results are the most common protocol messages, and as their names indicates, their payloads follow immediately after the header. For large payloads this can become an issue when dealing with many concurrent requests over a single connection, for which there’s a more complicated “streaming” request &amp;amp; result type which we will explore later on.&lt;/p&gt;

&lt;p&gt;If an error occurs while handing a request, an “error” is send as the reply instead of a regular result:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+----------------- ErrorResult
|  +---------------- requestID   &quot;001&quot;
|  |       +-------- payloadSize 38
|  |       |
E00100000026{&quot;error&quot;:&quot;Unknown operation \&quot;echo\&quot;&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As with all messages, what the payload data represents is up to each application and not part of the Gotalk protocol although we use JSON in our examples here.&lt;/p&gt;

&lt;p&gt;When there’s no expectation on a response, Gotalk provides a “notification” message type:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+---------------------- Notification
|              +--------- type        &quot;chat message&quot;
|              |       +- payloadSize 50
|              |       |
n00cchat message00000032{&quot;message&quot;:&quot;Hi&quot;,&quot;from&quot;:&quot;nthn&quot;,&quot;chat_room&quot;:&quot;gonuts&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notifications are never replied to nor can they cause “error” results.&lt;/p&gt;

&lt;p&gt;For more complicated scenarios there are “streaming-payload” requests and results at our disposal. This allows transmitting of large amounts of data without the need for large buffers. For example this could be used to forward audio data to audio playback hardware, or to transmit a large file off of slow media like a tape drive or hard-disk drive.&lt;/p&gt;

&lt;p&gt;Because transmitting a streaming request or result does not occupy “the line” (single-payloads are transmitted serially), they can also be useful when there are many concurrent requests happening over a single connection.&lt;/p&gt;

&lt;p&gt;Here’s an example of a “streaming-payload” request …&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+----------------- StreamRequest
|  +---------------- requestID   &quot;001&quot;
|  |      +--------- operation   &quot;echo&quot;
|  |      |       +- payloadSize 25
|  |      |       |
s001004echo0000000b{&quot;message&quot;:

+----------------- streamReqPart
|  +---------------- requestID   &quot;001&quot;
|  |       +-------- payloadSize 25
|  |       |
p0010000000e&quot;Hello World&quot;}

+----------------- streamReqPart
|  +---------------- requestID   &quot;001&quot;
|  |       +-------- payloadSize 0 (end of stream)
|  |       |
p00100000000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;… followed by a “streaming-payload” result:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;+----------------- StreamResult (1st part)
|  +---------------- requestID   &quot;001&quot;
|  |       +-------- payloadSize 25
|  |       |
S0010000000b{&quot;message&quot;:

+----------------- StreamResult (2nd part)
|  +---------------- requestID   &quot;001&quot;
|  |       +-------- payloadSize 25
|  |       |
S0010000000e&quot;Hello World&quot;}

+----------------- StreamResult
|  +---------------- requestID   &quot;001&quot;
|  |       +-------- payloadSize 0 (end of stream)
|  |       |
S00100000000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Requests and results does not need to match on the “single” vs “streaming” detail — it’s perfectly fine to send a streaming request and read a single response, or send a single response just to receive a streaming result. &lt;em&gt;The payload type is orthogonal to the message type&lt;/em&gt;, with the exception of an error response which is always a “single-payload” message, carrying any information about the error in its payload. Note however that the current version of the Go package does not provide a high-level API for mixed-kind request-response handling.&lt;/p&gt;

&lt;h2 id=&quot;open-source-code&quot;&gt;Open source code&lt;/h2&gt;

&lt;p&gt;Gotalk is a hobby project and free to use, modify and even sell within the bounds of &lt;a href=&quot;https://github.com/rsms/gotalk#mit-license&quot;&gt;the liberal MIT-license&lt;/a&gt;. You’ll find the most recent version at &lt;a href=&quot;https://github.com/rsms/gotalk&quot;&gt;https://github.com/rsms/gotalk&lt;/a&gt;&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>DBX 2013</title>
    <link href="https://rsms.me/dbx2013"/>
    <updated>2013-07-09T00:00:00+00:00</updated>
    <id>https://rsms.me/dbx2013</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;//farm8.staticflickr.com/7451/9254559408_e1026556da_k.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Dropbox’s first developer conference &lt;em&gt;DBX&lt;/em&gt; was a lot of fun. Me and Adam Polselli gave a talk on &lt;em&gt;“Designing Products for People”&lt;/em&gt; as seen in the video below.&lt;/p&gt;

&lt;iframe width=&quot;720&quot; height=&quot;405&quot; src=&quot;https://www.youtube.com/embed/J7ZZ0Tjkfoo?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;img src=&quot;//farm4.staticflickr.com/3745/9254556280_10cbcba539_k.jpg&quot; width=&quot;2048&quot; /&gt;&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>Hello, Dropbox</title>
    <link href="https://rsms.me/hello-dropbox"/>
    <updated>2013-03-21T00:00:00+00:00</updated>
    <id>https://rsms.me/hello-dropbox</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8225/8580803186_ccf9d4337b_o.png&quot; width=&quot;50%&quot; align=&quot;right&quot; /&gt;I’m very excited to let you know that I’m joining &lt;a href=&quot;https://www.dropbox.com/&quot;&gt;Dropbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After two years at Facebook I couldn’t be more proud. Proud to have been part of something as important as Facebook and proud of the work I’ve done with shaping the future of mobile communication. It’s truly been a fantastic time of my life — an experience rich of great people, mind-boggling challenges and once-in-a-lifetime experiences.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Look at the past for inspiration, but focus on the future, because tomorrow is shaped by the choices we make today.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At Dropbox I’m going to work hard to make all our lives better. Remove friction from technical details in our modern daily lives, and relieve us from worrying about our “stuff” — from quick snapshots and hasty notes to precious memories.&lt;/p&gt;

&lt;p&gt;This is going to be such a fun adventure.&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>The 1950s called and wanted their toolbox back</title>
    <link href="https://rsms.me/1950s-called-wanted-toolbox-back"/>
    <updated>2013-01-01T00:00:00+00:00</updated>
    <id>https://rsms.me/1950s-called-wanted-toolbox-back</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8358/8336375923_9f0dca4da9_o.png&quot; width=&quot;50%&quot; align=&quot;right&quot; /&gt;Your favourite fancy-pants modern programming language is from the 1950s.&lt;/p&gt;

&lt;p&gt;Pretty much any programming language used today is &lt;a href=&quot;http://www.levenez.com/lang/&quot;&gt;a derivative&lt;/a&gt; of &lt;a href=&quot;http://en.wikipedia.org/wiki/Fortran&quot;&gt;Fortran&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/Lisp_%28programming_language%29&quot;&gt;Lisp&lt;/a&gt;, both born in the 1950s. Okay, reality check: It’s 2013—yes, 60 years later—and we have cars that drive themselves on the street, robots roaming the surface of alien planets and tiny networked devices with interactive surfaces that we keep in our pockets, which are orders of magnitude more powerful than the computers of the 1950s.&lt;/p&gt;

&lt;p&gt;This might come as a surprise to readers not into &lt;a href=&quot;http://en.wikipedia.org/wiki/Computer_programming&quot;&gt;computer programming&lt;/a&gt;, but professional and hobbyist programmers alike all &lt;strong&gt;use the same tools as we did 60 years ago&lt;/strong&gt; — one-dimensional, sequential plain text. It’s like writing a single document in Word &lt;em&gt;without using any formatting&lt;/em&gt;, with the goal of instructing a large symphony orchestra to perform a complex musical piece. That app you’re using could as well have been built in the 1950s, had we the same powerful hardware back then. We are thoughtlessly using Grandpa’s old toolbox to build a spaceship.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Computer_programming&quot;&gt;Wikipedia article on computer programming&lt;/a&gt; opens up with the following description:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Computer programming […] is the process of designing, writing, testing, debugging, and maintaining the source code of computer programs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Interestingly “writing” is an inherent part of this canonical description of “computer programming” — a subject under constant scrutiny. Programming has become synonymous with “writing code”, which really tickles my LOL, so to speak.&lt;/p&gt;

&lt;h2 id=&quot;jumping-higher--beyond-the-written-text&quot;&gt;Jumping higher &amp;amp; beyond the written text&lt;/h2&gt;

&lt;p&gt;Writing is a universal tool we created for conveying information in a way that can be easily copied, shared and distributed. Although writing as a form of communication goes as far back as 5200 years (clay tablets used in Mesopotamia around 3200 BCE), we would not reach an interesting level of literacy until the &lt;a href=&quot;http://en.wikipedia.org/wiki/File:Illiteracy_france.png&quot;&gt;late 19th century&lt;/a&gt; when reading was no longer exclusive to monks, academics and the educated upper class, but became an extremely important tool of humanity, propelling us into the industrial age and beyond. As a species we are builders. In a way, we have taken control of our evolution not by changing our minds or physique, to become larger so we can build greater things, but by building a tower of knowledge that enables us to create small and large tools which in turn enables us to build houses taller than a hundred people and explore the surface of alien planets no human has ever set a foot on.&lt;/p&gt;

&lt;p&gt;Just as the now mundane tools pen and paper have evolved from blood and cave walls into sharp stones and clay tablets—into ink and papyrus into pen and paper and lately into stylus and screen—the fundamental tools (i.e. computer programming) we use today to build tomorrow’s toolbox (i.e. software) have not evolved to make use of our current arsenal of technology. How will we build software 20 years from now? 200 years from now? Hopefully not limited by the same factors as we are today, namely expressing multi-dimensional and naturally concurrent systems in one-dimensional, sequential text.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8078/8337433556_d3104c8b59_o.png&quot; alt=&quot;High jump&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We seem to have reached an upper level of utility with our current toolbox for programming computers, much like the athletic Olympic sport of &lt;a href=&quot;http://en.wikipedia.org/wiki/High_jump&quot;&gt;High Jump&lt;/a&gt;, where the current record of 2.45m has remained for 20 years — here we have reached the limit of the tool box (the human body.) To allow High Jump to “progress” further, we would either need to change the definition and rules of the sport or allow modified human bodies (i.e. doping, cybernetics, etc) to participate.&lt;/p&gt;

&lt;p&gt;Our current toolbox for software creation has an inherent limitation at its very foundation: low bandwidth. One-dimensional, sequential text utilises only our sense of sight, and is interpreted by a small section of our brains, forming a “bridge” or “proxy” for meaning and expression.&lt;/p&gt;

&lt;p&gt;The high-level goal of computer programming is to enable the creation of highly customised tools: A video player app is a tool for playing specific kinds of moving pictures synchronised with audio. The game on your smartphone that you play on the bus is a tool for creating feelings of accomplishment. The system of a bank is a specialised tool that keeps track of who has what money.&lt;/p&gt;

&lt;h2 id=&quot;what-about-tomorrow&quot;&gt;What about tomorrow?&lt;/h2&gt;

&lt;p&gt;So how do we make full use of today’s technology to enable these very creative individuals known as computer programmers—or rather; software engineers—to jump even higher? I doubt a thousand year old one-dimensional tool like text is the answer, when we perform other tasks in life using tools which make better use of our senses — touch and hearing, and don’t forget the higher-level senses like image recognition and spatial ability. Our minds are truly powerful and very able.&lt;/p&gt;

&lt;p&gt;So it all comes down to &lt;a href=&quot;http://en.wikipedia.org/wiki/Human%E2%80%93computer_interaction&quot;&gt;Human-Computer Interaction&lt;/a&gt;, the field of interaction between people and computers. Programming is, in fact, just an interface &lt;em&gt;for&lt;/em&gt; humans &lt;em&gt;to control&lt;/em&gt; computers.&lt;/p&gt;

&lt;p&gt;A good example is the car. If you owned a car in the 1800s you would know how to maintain that car. You would know how the engine operated, and you would be able to diagnose and fix problems. Today you simply press a button to start or stop the car. Open up the engine compartment hood of a modern car and you will probably just see a large flat surface with a logotype on it — the heart of the car has become irrelevant knowledge for most car operators like yourself.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8491/8336375797_bea36eb333_o.png&quot; width=&quot;30%&quot; align=&quot;right&quot; /&gt;The car of the 1800s would not be a very useful tool in today’s measures as it would likely break down during short trips, would not go very fast and was expensive to produce and operate. The car of today is an extremely able tool which extends your ability of transportation both in terms of time (speed), comfort, distance and freight. We have refined our tools (hammers and screwdrivers replaced by robotic specialised factories and lasers) by applying the process of interface abstraction to in order to make the human able to do more using less cognitive effort. They year of 2012 even brought us street-legal &lt;a href=&quot;http://newsfeed.time.com/2012/09/26/speeding-into-the-future-self-driving-cars-are-now-legal-in-california/&quot;&gt;cars which drives themselves&lt;/a&gt; — a step further in the progress of abstraction, enabling us not only to transport ourselves long distances in comfort, but also free up time for other tasks (i.e. while the car is driving.)&lt;/p&gt;

&lt;p&gt;The field of programming need to see a renaissance in fundamental reinvention, just as it did in the 1950s when programming machines using levers and buttons was replaced by programming machines using textual sequences of computer commands.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8072/8337458910_786074443c_o.png&quot; alt=&quot;Minority report FTW&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Okay, maybe we’re not in the movie Minority Report just yet, but still, today’s multi-sensory input-output technology like high-density interactive &lt;a href=&quot;http://www.technologyreview.com/news/417879/touch-screens-that-touch-back/&quot;&gt;touch screens which “touches back”&lt;/a&gt; and &lt;a href=&quot;http://www.hitl.washington.edu/scivw/EVE/I.B.1.3DSoundSynthesis.html&quot;&gt;spatial 3D positional audio&lt;/a&gt; are all interesting technology that just now have become economically viable and high-fidelity enough to be forgotten — “forgotten” as in us no longer thinking about the technology itself, but to be able to intuitively focus on whatever is presented and conveyed.&lt;/p&gt;

&lt;h2 id=&quot;visions-for-the-future-from-the-past&quot;&gt;Visions for the future, from the past&lt;/h2&gt;

&lt;p&gt;In the rather profound &lt;a href=&quot;http://www.cs.virginia.edu/~evans/cs655/readings/smalltalk.html&quot;&gt;Design Principles Behind Smalltalk&lt;/a&gt; in which &lt;a href=&quot;http://en.wikipedia.org/wiki/Daniel_Henry_Holmes_Ingalls%2C_Jr.&quot;&gt;Daniel Ingalls&lt;/a&gt; of the Xerox PARC expresses the interesting ethos of enabling creative individuals to program computers, we can read the following:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[…] a vision that includes a creative individual and the best computing hardware available.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ingalls builds further on this vision, writing:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If a system is to serve the creative spirit, it must be entirely comprehensible to a single individual.&lt;/p&gt;

  &lt;p&gt;The point here is that the human potential manifests itself in individuals. To realize this potential, we must provide a medium that can be mastered by a single individual. Any barrier that exists between the user and some part of the system will eventually be a barrier to creative expression.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Back in 1981 when the above document was published, human-computer hardware interfaces were far from as high fidelity as they are today. There were no low-latency touch screens you could hold in your hand and there were no graphics processors able to render complex movie scenes on-the fly. Keyboards were still the lowest friction and efficient way for a human to provide a computer with input. With today’s hi-fi user input hardware we should be able to further lower the friction—the “barrier”—between the human and the computer, and at the same time also increase the bandwidth of communication.&lt;/p&gt;

&lt;p&gt;As early as 1963 was alternative human-computer interaction hardware with potentially lower level of friction and higher bandwidth explored. Most notably is &lt;a href=&quot;http://en.wikipedia.org/wiki/Sketchpad&quot;&gt;Sketchpad&lt;/a&gt;, which used a stylus pen with an interactive screen, as likely being the most significant invention in the field of HCI.&lt;/p&gt;

&lt;p&gt;Below here is a video of &lt;a href=&quot;http://en.wikipedia.org/wiki/Alan_Kay&quot;&gt;Alan Kay&lt;/a&gt;’s famous talk &lt;a href=&quot;http://archive.org/details/AlanKeyD1987&quot;&gt;“Doing with Images Makes Symbols”&lt;/a&gt; from 1987 in which we see both Sketchpad and GrAIL (another early graphical programming environment from 1968) in action:&lt;/p&gt;

&lt;iframe src=&quot;//archive.org/embed/AlanKeyD1987&quot; width=&quot;640&quot; height=&quot;480&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;br /&gt;
&lt;small&gt;Sketchpad segment start at 04:00. GrAIL segment starts at at 24:10.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;Not only was Sketchpad the first ever stylus input device, but also pioneered graphical windows and object-oriented programming. The computer it ran on was large enough to have it’s own roof and had a total memory of 460 kilobytes (a small photo from your smartphone is likely to be 2-4 times &lt;em&gt;larger&lt;/em&gt; that the entire memory of this machine), and the processor could perform 400 000  instructions per second. Your average smartphone today can perform around 4 000 000 000 instructions per second (per core) — that means that what’s in your pocket today is not only extremely small in comparison to the giant computer Sketchpad was running on in 1963, but is also 10 000 times more powerful.&lt;/p&gt;

&lt;p&gt;Now, remember the 1950s called and still haven’t got their programming toolbox back.&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>The Definition of Design</title>
    <link href="https://rsms.me/eames-definition-of-design"/>
    <updated>2012-12-01T00:00:00+00:00</updated>
    <id>https://rsms.me/eames-definition-of-design</id>
    <content type="html">&lt;p&gt;Questions by Mme. L. Amic, Answers by &lt;strong&gt;Charles Eames&lt;/strong&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;What is your definition of “Design”, Monsieur Eames?&lt;br /&gt;
&lt;strong&gt;One could describe design as a plan for arranging elements to accomplish a particular purpose.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design an expression of art?&lt;br /&gt;
&lt;strong&gt;I would rather say it’s an expression of purpose. It may, if it’s good enough, later be judged as art.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design a craft for industrial purposes?&lt;br /&gt;
&lt;strong&gt;No, but design may be a solution to some industrial problems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What is the boundaries of Design?&lt;br /&gt;
&lt;strong&gt;What are the boundaries of problems?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design a discipline that concerns itself with only one part of the environment?&lt;br /&gt;
&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is it a method of general expression?&lt;br /&gt;
&lt;strong&gt;No, it is a method of action.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design a creation of an individual?&lt;br /&gt;
&lt;strong&gt;No, because to be realistic one must always recognize the influence of those that have gone before.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design a creation of a group?&lt;br /&gt;
&lt;strong&gt;Very often.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is there a Design ethic?&lt;br /&gt;
&lt;strong&gt;There are always design constraints and these often imply an ethic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Does Design imply the idea of products that are necessarily useful?&lt;br /&gt;
&lt;strong&gt;Yes, even though the use might be very suttle.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is it able to cooperate in the creation of works reserved solely for pleasure?&lt;br /&gt;
&lt;strong&gt;Who would say that pleasure is not useful?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ought form to derive from the analysis of function?&lt;br /&gt;
&lt;strong&gt;The great risk here is that the analysis may be incomplete.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Can the computer substitute for the Designer?&lt;br /&gt;
&lt;strong&gt;Probably, in some special cases but usually the computer is an aid to the designer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Does Design imply industrial manufacture?&lt;br /&gt;
&lt;strong&gt;Not neccessarily.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design used to modify an old object through new techniques?&lt;br /&gt;
&lt;strong&gt;This is one kind of design problem.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design used to fit up an existing model so that it is more attractive?&lt;br /&gt;
&lt;strong&gt;One doesn’t usually think of design in this way.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design an element of industrial policy?&lt;br /&gt;
&lt;strong&gt;If design constraints imply an ethic and if industrial policy includes ethical principles then yes, design is an element in industrial policy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Does the creation of Design admit constraint?&lt;br /&gt;
&lt;strong&gt;Design depends largely on constraints.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What constraints?&lt;br /&gt;
&lt;strong&gt;The sum of all constraints. Here is one of the few effective keys to the design problem: the ability of the designer to recognize as many of the constraints as possible, his willingness and enthusiasm for working within these constraints. The constraints of price, size, strength, balance, time and so forth. Each problem has its own peculiar list.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Does Design obey laws?&lt;br /&gt;
&lt;strong&gt;Aren’t constraints enough?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Are there tendencies and schools in Design?&lt;br /&gt;
&lt;strong&gt;Yes, but these are more a measure of human limitation than of ideals.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Is Design ephemeral?&lt;br /&gt;
&lt;strong&gt;Some needs are ephemeral, most designs are ephemeral.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ought Design to tend towards the ephemeral or towards permanence?&lt;br /&gt;
&lt;strong&gt;Those needs and designs that have a more universal quality tend toward relative permanence.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How would you define yourself with respect to a decorator? An interior architect? A stylist?&lt;br /&gt;
&lt;strong&gt;I wouldn’t.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To whom does Design address itself: to the greatest numbers? To the specialsts or the enlightened amateur? To a priviledged social class?&lt;br /&gt;
&lt;strong&gt;Design addresses itself to the need.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After having answered all these questions, do you feel you have been able to practice the profession of “Design” under satisfactory conditions, or even optimum conditions?&lt;br /&gt;
&lt;strong&gt;Yes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you been forced to accept compromises?&lt;br /&gt;
&lt;strong&gt;I don’t remember ever being forced to accept compromises but I have willingly accepted constraints.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What do you feel is the primary condition for the practice of Design and for its propagation?&lt;br /&gt;
&lt;strong&gt;A recognition of need.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What is the future of Design?&lt;/p&gt;

&lt;p&gt;…&lt;/p&gt;

&lt;p&gt;Source: &lt;a href=&quot;http://www.youtube.com/watch?v=3xYi2rd1QCg&quot;&gt;http://www.youtube.com/watch?v=3xYi2rd1QCg&lt;/a&gt;&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>Sol — a sunny little virtual machine</title>
    <link href="https://rsms.me/sol-a-sunny-little-virtual-machine"/>
    <updated>2012-10-14T00:00:00+00:00</updated>
    <id>https://rsms.me/sol-a-sunny-little-virtual-machine</id>
    <content type="html">&lt;p&gt;During this weekend, together with a few evenings earlier this week, I created a rather simple &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_machine&quot;&gt;virtual machine&lt;/a&gt; dubbed &lt;a href=&quot;https://github.com/rsms/sol&quot;&gt;“Sol”&lt;/a&gt;, after the Swedish word for “sun”. I’ve read a lot about VM design and I’m into stuff like OS design, programming languages and other seeminlgy obscure and nerdy stuff surrounding the concept of a computer as a generic tool.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A virtual machine (VM) is a software implementation of a machine (i.e. a computer) that executes programs like a physical machine. — &lt;a href=&quot;http://en.wikipedia.org/wiki/Virtual_machine&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/rsms/sol&quot;&gt;Sol&lt;/a&gt; is a process virtual machine that runs inside an operating system process. However, inside Sol there are multiple tasks (just like most operating systems have processes) and so for a program running in Sol it does not matter what the world looks like on the outside. We could even make Sol boot directly from hardware, but that would just be crazytown. Trust me. I’ve been down that road before.&lt;/p&gt;

&lt;p&gt;The purpose of Sol is learning. As we are defining our world, we have an extremely high degree of freedom. One major component of a virtual machine is the provided &lt;em&gt;instruction set&lt;/em&gt;. An &lt;em&gt;instruction&lt;/em&gt; is the simplest type of operation that a program can perform, and so the set of instructions provided by the virtual machine to programs running in it need to be universal and efficient.&lt;/p&gt;

&lt;h2 id=&quot;design-overview&quot;&gt;Design overview&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8335/8089500428_b103d2c23d_o.png&quot; alt=&quot;Sketch of the VM with schedulers&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the Sol VM there are one or more &lt;em&gt;schedulers&lt;/em&gt;, each running on one CPU core (not yet implemented at the time of writing this).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8049/8089500560_622bd30623_o.png&quot; alt=&quot;Sketch of a scheduler&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Each &lt;em&gt;scheduler&lt;/em&gt; maintains a list of &lt;em&gt;tasks&lt;/em&gt; to be run. This list is called the &lt;em&gt;run queue&lt;/em&gt;. A scheduler also maintains I/O watchers, timers, handles OS interrupts, etc. The scheduler does most of the work in Sol as it not only does all those fancy things I just described, but it also executes program code.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;run queue&lt;/em&gt; is a list of tasks ordered in the way they are scheduled.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The scheduler takes the first task in the list from the &lt;em&gt;run queue&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;executes the task (more on what that means later).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If the task ended with an “end” or “error” status, the task is removed from the run queue…&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;…otherwise places the task at the end of the list.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If there are any I/O watchers or timers, check timers for expiry and possibly call the host OS kernel to check on pending “asynchronous” I/O events.&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;If an event has happened, like a timer expired or fired, the correlating task is added to the run queue so that the task can read the event it is waiting for.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The scheduler repeats this process (e.g. starting from point 1.) as long as there are any tasks in the run queue.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s have a look at a &lt;em&gt;task&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8195/8089499085_ddd9cb9de2_o.png&quot; alt=&quot;Sketch of a task and its activation records&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As we can see, a &lt;em&gt;task&lt;/em&gt; is mostly an abstraction and contains only one significant component: &lt;a href=&quot;http://en.wikipedia.org/wiki/Call_stack#Structure&quot;&gt;&lt;em&gt;Activation records&lt;/em&gt;&lt;/a&gt;. These comprise a task’s call stack and each &lt;em&gt;activation record&lt;/em&gt; corresponds to one (active) function call. An activation record contains a reference to the function prototype (more on this in just a second) it’s executing, a &lt;em&gt;program counter&lt;/em&gt; (usually called &lt;em&gt;PC&lt;/em&gt;) which is a cursor for the currently executing program instruction and finally a registry for values.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;function prototype&lt;/strong&gt; is the constants and the instruction of a function, but without a context (or “function closure”) with local variables etc. A &lt;em&gt;function prototype&lt;/em&gt; is kind of like a building without any people or furniture. Albeit the name, it’s not really comparable to a blueprint as a &lt;em&gt;function prototype&lt;/em&gt; is not copied or implemented, but is actually used as-is.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;program counter&lt;/strong&gt; is simply a number that corresponds to an offset into the function prototype’s program (ordered list of instructions). As an activation record (we can think about this as a piece of running code) is executed, the &lt;em&gt;program counter&lt;/em&gt; (PC) is incremented as each instruction is executed. Sometimes the PC is decremented, when a program jumps backwards (e.g. when performing a loop). The PC plays a central role in an instruction-based program (like your computer or phone’s hardware which is most likely incrementing a PC right now).&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;registry&lt;/strong&gt; is essentially a region of temporary memory that the executing program can use to store variable data. Imagine this simple function:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here the program needs a way to store the value created by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x * 5&lt;/code&gt; that it can then pass to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x * y&lt;/code&gt; which also needs to store its resulting value somewhere before using it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;. All local variables are stored in registers and thus access is very efficient. Something like this happens when executing the “foo” function (“R(x)” means “register x”):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;argument 0 and 1 are already in R(0) and R(1)
load constant &quot;5&quot; into R(2)
multiply value-of R(0) with value-of R(2), put the result in R(0)
multiply value-of R(0) with value-of R(1), put the result in R(0)
return R(0)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sol is a register-based virtual machine. Operands and results are read and stored from and to numbered registers, rather than “pushed” and “popped” to and from a stack (as with &lt;em&gt;stack-based virtual machines&lt;/em&gt;). Register-based virtual machines avoid the push and pop operations usually surrounding other instructions, reducing code size, but in several cases also increases speed of execution (compared to stack-based virtual machines).&lt;/p&gt;

&lt;p&gt;In the most excellent paper &lt;a href=&quot;http://www.lua.org/doc/jucs05.pdf&quot;&gt;“The Implementation of Lua 5.0”&lt;/a&gt; Roberto, Luiz and Waldemar describes the (not really a) problem with code size and decoding overhead:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;There are two problems usually associated with register-based machines: code size and decoding overhead. An instruction in a register machine needs to specify its operands, and so it is typically larger than a corresponding instruction in a stack machine. (For instance, the size of an instruction in Lua’s virtual machine is four bytes, while the size of an instruction in several typical stack machines, including the ones previously used by Lua, is one or two bytes.) On the other hand, register machines generate less opcodes than stack machines, so the total code size is not much larger.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sol takes a lot of inspiration from &lt;a href=&quot;http://www.lua.org/&quot;&gt;Lua&lt;/a&gt; as well as &lt;a href=&quot;http://www.erlang.org/&quot;&gt;Erlang&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;instructions-and-operations&quot;&gt;Instructions and operations&lt;/h2&gt;

&lt;p&gt;An instruction consists of one or more components:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An operation code (e.g. “subtract a from b”)&lt;/li&gt;
  &lt;li&gt;0-3 operands (e.g. “register a and register b, results in register c”)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a virtual machine has the disadvantage of being …virtual, we must do whatever we can in terms of assuring good performance, so one of these instructions fit into one &lt;em&gt;machine word&lt;/em&gt;. Most hardware today is able to deal with 32-bit long chunks of data very efficiently, so inspired by &lt;a href=&quot;http://www.lua.org/&quot;&gt;Lua 5&lt;/a&gt; I chose a 32-bit representation for Sol’s instructions.&lt;/p&gt;

&lt;p&gt;Each instruction and its operands is encoded in one of three layouts (Behold, awesome ASCII art!.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OP ABC&lt;/strong&gt; — Operation OP with operands A, B and C:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0         5 | 6          13 | 14           22 | 23            31   Bit
------------|---------------|-----------------|-----------------
     OP     |       A       |        B        |        C           Field
------------|---------------|-----------------------------------
     6              8                9                 9           Bits
  [0..63]        [0..255]         [0..511]          [0..511]       Range
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Some operations only need two operands and can be made more efficient if one of those operands is large enough for common values. For this need we define an alternate layout of an instruction:&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;OP ABx&lt;/strong&gt; — Operation OP with operands A and Bs&lt;/td&gt;
      &lt;td&gt;Bu:&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0         5 | 6          13 | 14                              31   Bit
------------|---------------|-----------------------------------
     OP     |       A       |              Bs/Bu                   Field
------------|---------------|-----------------------------------
     6              8                        18                    Bits
  [0..63]        [0..255]             Bu: [0..262143]              Range
                                      Bu: [-131071..131072]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A third class of operations only use one operand which size has a correlation with efficiency, so we define a third alternate layout of an instruction where the three operands are effectively collapsed into one 26-bit integer value:&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;OP Bxx&lt;/strong&gt; — Operation OP with operand Bss&lt;/td&gt;
      &lt;td&gt;Buu:&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0         5 | 6                                               31   Bit
------------|---------------------------------------------------
     OP     |                     Bss/Buu                          Field
------------|---------------------------------------------------
     6                               26                            Bits
  [0..63]                   Buu: [0..67108863]                     Range
                            Bss: [-33554431..33554432]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A, B, C, Bu and Buu signify unsigned integers whilst Bs and Bss signify signed integers. As we can read above, there’s room for 64 operations and 256 registers (OP=6 bits, A=8 bits) with this configuration. More than we need :)&lt;/p&gt;

&lt;p&gt;Changing and maintaining instructions (operations + operands) is simple in Sol. I’ve intentionally gone to great lengths in order to make playing around with the instuction set easy. The file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;instr.h&lt;/code&gt; contains a list of instructions:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* Control flow */&lt;/span&gt; \
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;YIELD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* suspend and reschedule */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JUMP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;Bss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* PC += Bss */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CALL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(A+B)) */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RETURN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;AB_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* return R(A), ... ,R(A+B-1) */&lt;/span&gt;\
&lt;span class=&quot;cm&quot;&gt;/* Data */&lt;/span&gt; \
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LOADK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;ABu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* R(A) = K(Bu) */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MOVE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;AB_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* R(A) = R(B) */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DBGREG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* special: Debug dump register values */&lt;/span&gt;\
&lt;span class=&quot;cm&quot;&gt;/* Arithmetic */&lt;/span&gt; \
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* R(A) = RK(B) + RK(C) */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SUB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* R(A) = RK(B) - RK(C) */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MUL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* R(A) = RK(B) * RK(C) */&lt;/span&gt;\
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/rsms/sol&quot;&gt;Sol’s source code&lt;/a&gt; is setup in such a way that changing this list is all that is required, apart from the actual implementation of each instruction. Adding or renaming an instruction automatically makes convenience symbols and functions available. Say that we add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DING&lt;/code&gt; instruction which plays a little sound every time it’s executed:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MUL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* R(A) = RK(B) * RK(C) */&lt;/span&gt;\
&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;Buu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* A = sound number to play */&lt;/span&gt;\
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s now a new operation identifier available called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S_OP_DING&lt;/code&gt; as well as constructor function for encoding DING instructions:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;SInstr&lt;/span&gt;  &lt;span class=&quot;nf&quot;&gt;SInstr_DING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Running a program now that includes a DING operation will cause an error in the VM: “unexpected operation”. We haven’t implemented the DING behavior yet! Operations are (at the time of writing this) implemented in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sched_exec.h&lt;/code&gt; which is the core of the virtual machine as this is what reads and performs the instructions of a Sol program. It can be summed up like this:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Instr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;Instr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instructions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;S_OP_LOADK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Read operands A and B from instruction *pc.&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Put constant at B into register A.&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;S_OP_MOVE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Read operands A and B from instruction *pc.&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Put value of register B in register A.&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// switch&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// while&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pretty much a good old switch loop. When this C code is compiled with a modern compiler like Clang or GCC, it will be rather efficient as each of our virtual operations effectively corresponds to only a few machine instructions. This is where we need to add DING.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;S_OP_DING&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Read operand Buu from instruction *pc.&lt;/span&gt;
      &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound_index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SInstrGetBuu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Find note for sound_index and play it&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;SoundNote&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;note&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SoundGetNote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sound_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;SoundPlay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;note&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here the type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sound&lt;/code&gt; as well as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SoundGet&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SoundPlay&lt;/code&gt; represents some kind of sound playing function that you provide. Now we can write Sol programs that play music:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;melody&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;DING&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;# play note 0
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;DING&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;# play note 1
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;DING&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;# play note 1
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;DING&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;# play note 2
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;DING&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;# play note 0
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;RETURN&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# return
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pling, plong, plong, ding, pling!&lt;/p&gt;

&lt;h2 id=&quot;multitasking&quot;&gt;Multitasking&lt;/h2&gt;

&lt;p&gt;No toy VM can be presented without shame unless it’s able to &lt;a href=&quot;http://en.wikipedia.org/wiki/Computer_multitasking&quot;&gt;multitask&lt;/a&gt;; perform multiple things at once, or at least give the programmer the illusion of concurrency.&lt;/p&gt;

&lt;p&gt;Sol has an operation called “yield” which is able to pause a task in any state and later have that task resume at the exact same state.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;//farm9.staticflickr.com/8468/8089711825_e00b434731_o.png&quot; alt=&quot;Sketch of tasks yielding&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From the task’s perspective it never knew it was paused and resumed. This is a powerful primitive as we can implement many features on top of this. At the time of writing, Sol already has two different types of &lt;em&gt;yield&lt;/em&gt;: Yielding for other tasks (so they can run or be scheduled from I/O etc events), and yielding for a timer to expire. At the end of this article there are a few example programs, all of them making use of yield.&lt;/p&gt;

&lt;p&gt;Yield is used to implement &lt;a href=&quot;http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking.2Ftime-sharing&quot;&gt;&lt;em&gt;cooperative multitasking&lt;/em&gt;&lt;/a&gt; where all tasks cooperate for the use of processing resources. When a task has performed a series of computations and relieves control to another task, one of three things has happened:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The task initiated an external (“blocking”) operation, like reading from a file or waiting for a certain time to occur,&lt;/li&gt;
  &lt;li&gt;the task completed and ended (it’s “main” function returned.),&lt;/li&gt;
  &lt;li&gt;or the task faulted, caused an error.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most systems that communicate with its environment and abroad, like a web server or a text editor, spend most of its time (CPU time relative to real time) waiting for the environment to respond; e.g. producing data on a network socket, writing contents to a file or returning a stepper motors position. These systems often benefit from cooperative multitasking, in particular coherent, specialized systems (unlike operating systems which are general by nature).&lt;/p&gt;

&lt;p&gt;What Sol provides is essentially &lt;a href=&quot;http://en.wikipedia.org/wiki/Coroutine&quot;&gt;coroutines&lt;/a&gt; for concurrency. A nice feature with coroutines (aka “green threads” aka “user threads”) is their ability to run sequential code in a concurrent system. A task like this:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Involves three “blocking” calls to the environment which causes the task to yield:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open&lt;/code&gt; asks the operating system to open a file by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;. The file might get opened sometime in the future. The scheduler takes a note that the task is waiting for this to happen, removes it from the &lt;em&gt;run queue&lt;/em&gt; for the time being.&lt;/li&gt;
  &lt;li&gt;The OS tells the scheduler that “that file you wanted me to open, well here’s the file descriptor” and thus the scheduler places the task on the &lt;em&gt;run queue&lt;/em&gt; again.&lt;/li&gt;
  &lt;li&gt;The task receives the file descriptor representing the opened file&lt;/li&gt;
  &lt;li&gt;The task again calls to the environment, this time asking to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; the contents of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Same thing as before, the scheduler tells the OS, takes a note, unschedules the task and continue with executing other tasks.&lt;/li&gt;
  &lt;li&gt;The OS tells the scheulder “I’ve read that file you asked me to read, here’s the data” (in reality this is slightly more complicated, but the principles are the same)&lt;/li&gt;
  &lt;li&gt;The scheduler queues the task, runs it.&lt;/li&gt;
  &lt;li&gt;Same thing with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;close&lt;/code&gt; function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the programmer it’s easy to follow the flow of her program.&lt;/p&gt;

&lt;p&gt;Comparing the above synchronous program to an asynchronous version:&lt;/p&gt;

&lt;div class=&quot;language-rb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;else:
      &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# returns here before the file has been opened&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Clearly harder to follow. A task in Sol can spawn new tasks in order to perform several things at the same time, like writing a file while replying over the network.&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;write_and_reply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;write_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.msg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;send_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TaskEnd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;noop&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# wait for write_file to end
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, as the &lt;a href=&quot;http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking.2Ftime-sharing&quot;&gt;Wikipedia section on cooperative multitasking&lt;/a&gt; mentions…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Because a cooperatively multitasked system relies on each process regularly giving up time to other processes on the system, one poorly designed program can consume all of the CPU time for itself or cause the whole system to hang.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This can happen when a program performs a very lengthy set of computations and can cause all kinds of problems, especially for other tasks relying on timers. As the Sol scheduler checks for timer expiration only between execution of tasks, a timer might effectively fire long after it was supposed to. Imagine controlling a toy &lt;a href=&quot;http://en.wikipedia.org/wiki/Quadrotor&quot;&gt;quadrotor&lt;/a&gt; where one task needs to update one rotor’s angle each 50 milliseconds, and another task consumes a wholesome 200 milliseconds, then your quadrotor might just crash and burn.&lt;/p&gt;

&lt;p&gt;To address this Sol employs an &lt;em&gt;operation cost counter&lt;/em&gt;. Each task is given a predefined amount of “operation value” per execution iteration (when the scheduler runs a task’s program). When the &lt;em&gt;operation cost counter&lt;/em&gt; reaches its limit, the task is simply forced to yield to other tasks. In the source code, look for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S_VM_EXEC_LIMIT&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;some-examples&quot;&gt;Some examples&lt;/h2&gt;

&lt;p&gt;The code below is expressed in a simplified assembly language that is almost 1:1 with the C API for defining these programs programatically, and so the assembly language itself should be considered irrelevant beyond explaining the instructions executed.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;In the output, lines like these: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[vm] ______________ ...&lt;/code&gt; denote when the scheduler regains control after running a task and the task either returned or yielded. This is one “execution iteration”. When running multiple tasks, you will usually see tasks interleved in round-robin order between these “execution iteration” marker lines.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In the output, lines starting with “…” are comments and/or simplifications and not part of the actual output.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In assembly comments, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R(x)&lt;/code&gt; means “Register x”, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RK(x)&lt;/code&gt; means “Register x if x is less than k else Constant (x-k)” where k is a special value, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;K(x)&lt;/code&gt; means “Constant x”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In assembly comments, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PC&lt;/code&gt; signifies the “program counter” which is sort of a cursor to the instructions of a program. It is incremented by one for each instruction executed. Some instructions will further modify this counter, like for instance the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JUMP&lt;/code&gt; instruction.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;example-1-while-x--0-yield-&quot;&gt;Example 1: while x &amp;gt; 0 yield …&lt;/h3&gt;

&lt;p&gt;While the variable x is greater than zero, decrement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt; by one and yield to the
scheduler, letting other tasks run. Eventually return.&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Assembly:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;# K(0) = 5
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;# K(1) = 0
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;# K(2) = 1
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;LOADK&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# R(0) = K(0)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;LE&lt;/span&gt;     &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# (0 == RK(k+1) &amp;lt; RK(0)) ? continue else PC++
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;JUMP&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;# PC += 3 to RETURN
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;SUB&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;257&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# R(0) = R(0) - RK(k+1)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;YIELD&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# yield A=type=sched
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;JUMP&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;# PC -= 5 to LE
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;RETURN&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# return
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Output when running in debug mode:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;$ build/debug/bin/sol
Sol 0.1.0 x64
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 0          LOADK   AB:    0,   0
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 3          SUB     ABC:   0,   0, 257
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 4          YIELD   ABC:   0,   0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 5          JUMP    Bss:       -5
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 3          SUB     ABC:   0,   0, 257
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 4          YIELD   ABC:   0,   0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
...three more execution iterations identical to the above block...
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 5          JUMP    Bss:       -5
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 2          JUMP    Bss:        3
[vm] 0x7fdf28c03c00 0x7fdf28c000e0 6          RETURN  AB:    0,   0
Scheduler runloop exited.
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;example-2-function-calls-and-timers&quot;&gt;Example 2: Function calls and timers&lt;/h3&gt;

&lt;p&gt;This program uses two functions. The entry point is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; function which simply
calls the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kitten&lt;/code&gt; function with one argument ‘500’. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kitten&lt;/code&gt; function “sleeps” for
the number of milliseconds passed to it (as the first argument.) The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kitten&lt;/code&gt; function
then returns the number “123” to the caller—the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; function—which dumps register values and
finally returns, causing the task to exit and subsequently the scheduler and the VM too to exit.&lt;/p&gt;

&lt;p&gt;Assembly:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kitten&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# Arguments: (R(0)=sleep_ms)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# K(0) = 123
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;YIELD&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# yield A=type=timer, RK(B)=R(0)=arg0
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;LOADK&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# R(0) = K(0) = 123
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;RETURN&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# return R(0)..R(0) = R(0) = 123
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# Arguments: ()
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kitten&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# K(0) = &amp;lt;func kitten&amp;gt;
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;CONST&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# K(1) = 500
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;LOADK&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# R(0) = K(0) = the kitten function
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;LOADK&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# R(1) = K(1) = 500
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;CALL&lt;/span&gt;   &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# R(0)..R(0) = R(0)(R(1)..R(1)) = a(R(1))
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;DBGREG&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# VM debug function that dumps register values
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;RETURN&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;c1&quot;&gt;# return
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Output when running in debug mode:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;$ time build/debug/bin/sol
Sol 0.1.0 x64
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 0          LOADK   AB:    0,   0
[vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 1          LOADK   AB:    1,   1
[vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 2          CALL    ABC:   0,   1,   1
[vm] 0x7f8c9bc03bf0 0x7f8c9bc000e0 1          YIELD   ABC:   1,   0,   0
D Timer scheduled to trigger after 500.000000 ms (sched.c:81)
# ...time passes and in this case the scheduler is idling...
D Timer triggered -- scheduling task (sched.c:57)
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7f8c9bc03bf0 0x7f8c9bc000e0 2          LOADK   AB:    0,   0
[vm] 0x7f8c9bc03bf0 0x7f8c9bc000e0 3          RETURN  AB:    0,   1
[vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 3          DBGREG
D [vm] R(0) = 123.000000 (sched_exec.h:214)
D [vm] R(1) = 500.000000 (sched_exec.h:215)
D [vm] R(0) = 123.000000 (sched_exec.h:216)
[vm] 0x7f8c9bc03bf0 0x7f8c9bc03910 4          RETURN  AB:    0,   0
Scheduler runloop exited.

real  0m0.504s
user  0m0.001s
sys   0m0.001s
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;example-3-multitasking&quot;&gt;Example 3: Multitasking&lt;/h3&gt;

&lt;p&gt;Here we run three tasks, each running the program in &lt;em&gt;Example 1&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;$ build/debug/bin/sol
Sol 0.1.0 x64
[sched 0x7fc219403930] run queue:
  [task 0x7fc219403c00] -&amp;gt; [task 0x7fc219403cd0] -&amp;gt; [task 0x7fc219403da0]
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fc219403c00 0x7fc2194000e0 0          LOADK   AB:    0,   0
[vm] 0x7fc219403c00 0x7fc2194000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fc219403c00 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257
[vm] 0x7fc219403c00 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fc219403cd0 0x7fc2194000e0 0          LOADK   AB:    0,   0
[vm] 0x7fc219403cd0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fc219403cd0 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257
[vm] 0x7fc219403cd0 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fc219403da0 0x7fc2194000e0 0          LOADK   AB:    0,   0
[vm] 0x7fc219403da0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fc219403da0 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257
[vm] 0x7fc219403da0 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fc219403c00 0x7fc2194000e0 5          JUMP    Bss:       -5
[vm] 0x7fc219403c00 0x7fc2194000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fc219403c00 0x7fc2194000e0 3          SUB     ABC:   0,   0, 257
[vm] 0x7fc219403c00 0x7fc2194000e0 4          YIELD   ABC:   0,   0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
# The above block of instruction is repeated three times in interleved
# round-robin order for each task. Then:
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fc219403c00 0x7fc2194000e0 5          JUMP    Bss:       -5
[vm] 0x7fc219403c00 0x7fc2194000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fc219403c00 0x7fc2194000e0 2          JUMP    Bss:        3
[vm] 0x7fc219403c00 0x7fc2194000e0 6          RETURN  AB:    0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fc219403cd0 0x7fc2194000e0 5          JUMP    Bss:       -5
[vm] 0x7fc219403cd0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fc219403cd0 0x7fc2194000e0 2          JUMP    Bss:        3
[vm] 0x7fc219403cd0 0x7fc2194000e0 6          RETURN  AB:    0,   0
[vm] ______________ ______________ __________ _______ ____ ______________
[vm] Task           Function       PC         Op      Values
[vm] 0x7fc219403da0 0x7fc2194000e0 5          JUMP    Bss:       -5
[vm] 0x7fc219403da0 0x7fc2194000e0 1          LE      ABC:   0,   0, 256
[vm] 0x7fc219403da0 0x7fc2194000e0 2          JUMP    Bss:        3
[vm] 0x7fc219403da0 0x7fc2194000e0 6          RETURN  AB:    0,   0
Scheduler runloop exited.
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;source-code&quot;&gt;&lt;a href=&quot;https://github.com/rsms/sol&quot;&gt;Source code&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Released free under a very permissive MIT-style license at &lt;a href=&quot;https://github.com/rsms/sol&quot;&gt;https://github.com/rsms/sol&lt;/a&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>Our own little computer language</title>
    <link href="https://rsms.me/mylang-tutorial1"/>
    <updated>2012-10-07T00:00:00+00:00</updated>
    <id>https://rsms.me/mylang-tutorial1</id>
    <content type="html">&lt;p&gt;Let’s write our own programming language. It’ll be fun and we will learn some key tools for processing structured data, performing semantic analysis, how to make a computer execute code, and all this using modern JavaScript.&lt;/p&gt;

&lt;p&gt;We will create five major components, each outlined in a separate article:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Lexical analyzer&lt;/li&gt;
  &lt;li&gt;Semantic parser&lt;/li&gt;
  &lt;li&gt;Code generator&lt;/li&gt;
  &lt;li&gt;Management and support&lt;/li&gt;
  &lt;li&gt;Runtime library&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Today we will actually do two things: Define a first version of our language’ lexicon, and write a lexical analyzer—or &lt;em&gt;lexer&lt;/em&gt;—which performs &lt;em&gt;lexical analysis&lt;/em&gt; of our language. From &lt;a href=&quot;http://en.wikipedia.org/wiki/Lexical_analysis&quot;&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;lexical analysis is the process of converting a sequence of characters into a sequence of tokens. A program or function which performs lexical analysis is called a lexical analyzer, lexer, or scanner.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our &lt;em&gt;lexer&lt;/em&gt; will understand the basic building blocks of our language, similar to what a word and punctuation are in natural language text. Naturally we need to decide which these words and punctuation are. I think this is one of the most fun parts of writing your own language, as we are completely free to design our language.&lt;/p&gt;

&lt;p&gt;A lexer is usually the first part in the &lt;em&gt;evaluation pipeline&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source code → Lexer → Parser → Code generator → Execution&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;language-lexicon-and-syntax&quot;&gt;Language lexicon and syntax&lt;/h2&gt;

&lt;p&gt;Let’s formulate the basic building blocks of our language. Before we write anything, let’s take a minute and think about what kind of language we wish to design. We don’t have to commit to anything yet, but it will be easier for us to make progress if we have an idea of what we are trying to accomplish.&lt;/p&gt;

&lt;p&gt;If we have the answers to the following to questions, our work will be easier.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Are linebreaks significant?&lt;/li&gt;
  &lt;li&gt;Is leading whitespace significant?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A language like C does not care about whitespace at all, except for separating keywords, whilst a language like Python cares about both linebreaks and leading whitespace. Let’s say “yes” to both these questions. Our language might care about both linebreaks and leading whitespace.&lt;/p&gt;

&lt;h3 id=&quot;syntax&quot;&gt;Syntax&lt;/h3&gt;

&lt;p&gt;Here’s a &lt;a href=&quot;http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form&quot;&gt;BNF&lt;/a&gt;-style sketch of the language I have in mind for this tutorial. Feel free to make up your own version.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-none&quot;&gt;Expression           = ExpressionGroup | Number | Text | Path | List | Map
ExpressionGroup      = &quot;(&quot; Expression* &quot;)&quot;
Line                 = Linebreak Space*

Whitespace           = Linebreak | Space
Linebreak            = U+000A..U+000D | U+0085 | U+2028 | U+2029
Space                = U+0009 | U+0020 | U+00A0 | U+180E | U+2000..U+200B
                     | U+202F | U+205F | U+3000 | U+FEFF

Number               = IntegerNumber | HexIntegerNumber | FractionalNumber
IntegerNumber        = DecimalDigit+
DecimalDigit         = 0..9
HexIntegerNumber     = &quot;0x&quot; HexDigit+
HexDigit             = 0..9 | A..F | a..f
FractionalNumber     = DecimalDigit+ &quot;.&quot; DecimalDigit* FractionExponent?
FractionalExponent   = (&quot;E&quot; | &quot;e&quot;) (&quot;-&quot; | &quot;+&quot;)? DecimalDigit+

Text                 = &quot;'&quot; TextCharacter* &quot;'&quot;
TextCharacter        = U+0021..U+0026
                     | U+0028..U+005B
                     | &quot;\&quot; TextEscCharacter
                     | U+005D..U+FFEE
TextEscCharacter     = &quot;\&quot; | &quot;'&quot; | &quot;t&quot; | &quot;n&quot; | &quot;r&quot; | UnicodeValue
UnicodeValue         = &quot;u&quot; HexDigit{4} | &quot;U&quot; HexDigit{8}

Path                 = Symbol (&quot;.&quot; Symbol)*
Symbol               = &amp;lt;SymbolCharacter except 0..9&amp;gt; SymbolCharacter*
SymbolCharacter      = &amp;lt;VisibleCharacter except SingleTerminator&amp;gt;
VisibleCharacter     = &amp;lt;UnicodeCharacter except Whitespace | ControlCharacter&amp;gt;
UnicodeCharacter     = U+0000..U+FFFE
ControlCharacter     = U+0000..U+0020 | U+007F..00A0 | U+FFEF..U+FFFF
SingleTerminator     = &quot;(&quot; | &quot;)&quot; | &quot;.&quot; | &quot;:&quot; | &quot;[&quot; | &quot;]&quot; | &quot;{&quot; | &quot;}&quot;

List                 = &quot;[&quot; Expression* &quot;]&quot;

Map                  = &quot;{&quot; MapPair* &quot;}&quot;
MapPair              = MapKey &quot;:&quot; Expression
MapKey               = Symbol | Text
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This format, usually referred to as BNF (although not actual strict BNF), is a way of expressing a syntax in terms of simple reductions. A quick guide to general BNF format:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo = Bar | Baz&lt;/code&gt; — “Foo” means either exactly one Bar or exactly one Baz.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar?&lt;/code&gt; — Zero or one “Bar” (a trailing “?” means “optional”)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar*&lt;/code&gt; — Zero or more “Bar” in succession&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar+&lt;/code&gt; — One or more “Bar” in succession&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar{4}&lt;/code&gt; — Exactly 4 “Bar” in succession&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A..F&lt;/code&gt; — Exactly one of the items in the natural sequence (here, A, B, C, D, E or F)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;Bar&quot;&lt;/code&gt; — The literal “Bar”&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(A | B) C&lt;/code&gt; — “(“ and “)” groups an anonymous reduction, here meaning “one of A or B, then one C”&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;U+2192&lt;/code&gt; — A Unicode character value (in this case the RIGHTWARDS ARROW codepoint)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;Foo except A and C&amp;gt;&lt;/code&gt; — Simplification of a reduction of “Foo”. Generally not recommented but useful in early stages of design.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above language is definitely incomplete (no functions or operators), but is a great start and to be honest it’s more than we need to get started. It would allow source code like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Hello = (bar baz) -&amp;gt;
  ה = can-haz [bar 'bar bara']
  54.8 * ה
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first step to interpreting this code is to perform &lt;em&gt;lexical analysis&lt;/em&gt;. As discussed earlier this means that a stream of bytes is the input and a stream of tokens is the result. Given our partial language specification, the above source should produce the following tokens:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;Hello&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;=&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LeftParen&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;bar&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;baz&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RightParen&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;-&amp;gt;&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Line(with 2 spaces)&lt;/code&gt;,&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;ה&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;=&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;can-haz&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LeftSquareBracket&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;bar&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Text(&quot;bar bara&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RightSquareBracket&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Line(with 2 spaces)&lt;/code&gt;,&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FractionalNumber(&quot;54.8&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;*&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Symbol(&quot;ה&quot;)&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Line(with 0 spaces)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With our current language lexicon and syntax we are able to formulate more complex structures that the above example, for instance:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Text.join = (list-of-text glue) -&amp;gt;
  result = nil
  for text in list-of-text
    result = if (result == nil) text
             else result + glue + text
  result

(print (Text.join ['Yet another' 'Hello' 'world'] ' '))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, let’s stick to the previous simpler example for now.&lt;/p&gt;

&lt;p&gt;This is an excellent time to take a break and play around with some different imaginary language syntax. Remember that the &lt;em&gt;lexer&lt;/em&gt; only needs to know about &lt;em&gt;what a word is&lt;/em&gt; not &lt;em&gt;all the possible words&lt;/em&gt; or even the sequence of words. When I say “words” here I mean the smallest building blocks of the syntax, or &lt;em&gt;tokens&lt;/em&gt; as they are usually called. Let’s call each small unit of meaning a “token” from here on forward.&lt;/p&gt;

&lt;h2 id=&quot;behold-a-lexer&quot;&gt;Behold, a lexer&lt;/h2&gt;

&lt;p&gt;Remember the &lt;em&gt;evaluation pipeline&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source code → Lexer → Parser → Code generator → Execution&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Parsing and dealing with code is inherently a flowing system with no specific beginning or end. Sure, if we read the source from a file the file will have a start and it will have an ending, but let’s write a pipeline that is universal and has &lt;em&gt;incremental&lt;/em&gt; functionality. In contrary to traditional &lt;em&gt;batch&lt;/em&gt; lexers, an &lt;em&gt;incremental&lt;/em&gt; lexer is able to iteratively analyze a continuous stream of characters and with little delay produce tokens on-the-fly. The tokens produced by our lexer will even be able to retain a persistent “snapshot” of the lexer’s state, for the abilitly to perform an incremental modification from a certain point. However, our lexer will merely make this possible but not directly provide this functionality.&lt;/p&gt;

&lt;p&gt;Given these requirements of being able to pause, resume and change source as we are producing tokens, there are not many implementation approaches available to us. In a language that has functions with local variables (usually implemented with a stack) a &lt;em&gt;batch lexer&lt;/em&gt; can be efficiently implemented with a function-based &lt;em&gt;recursive decent&lt;/em&gt; approach, where each token reduction (see our BNF-style language definition) is represented by a function that calls another function depending on the source character at hand.&lt;/p&gt;

&lt;p&gt;Here is pseudo-code implementing a recursive decent approach (this particular one is actually not recursive, but could very well become so), able to handle the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Text&lt;/code&gt; part of our syntax:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;class Lexer:
  next_char = nil
  input = &quot;&quot;
  input_offs = 0

  def ReadToken():
    return this.ReadExpression()

  def ReadExpression():
    if this.next_char == &quot;'&quot;:
      this.ReadNextChar() # Consume &quot;'&quot;
      return this.ReadText()
    else if ...

  def ReadText():
    token = {type = TEXT, value = &quot;&quot;}
    prev_was_escape = false
    while this.next_char:
      if prev_was_escape:
        prev_was_escape = false
        token.value = concat(token.value, this.next_char)
      else if this.next_char == &quot;\\&quot;:
        prev_was_escape = true
        continue
      else if this.next_char == &quot;'&quot;:
        break
      else:
        token.value = concat(token.value, this.next_char)
    this.ReadNextChar() # Consume &quot;'&quot;
    return token

  def ReadNextChar():
    this.next_char = this.input[this.input_offs++]

L = Lexer()
L.SetInput(&quot;'Hello world'&quot;)
L.ReadToken()  # -&amp;gt; {type=TEXT, value=&quot;Hello world&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This works fine for source input that is provided as one continuous sequence.
If we were to pause a batch lexer like this, it would either imply a very complex and probably inefficient code which records and stuffs away the current call stack (essentially co-routines or green threads), or abort and retry from the beginning again later.&lt;/p&gt;

&lt;p&gt;Say the source &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;'Hello world'&lt;/code&gt; arrives in two chunks and we try to apply the above batch lexer:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. SetInput(&quot;'Hello wo&quot;)
2. ReadToken()  # -&amp;gt; nil
3. # Some time passes...
4. SetInput(&quot;rld'&quot;)
5. ReadToken()  # -&amp;gt; something not a string
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReadText&lt;/code&gt; is called, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next_char&lt;/code&gt; will be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nil&lt;/code&gt; before the loop sees a terminating “’” character, and since all state is kept on the stack it will be lost when the function returns. Thus the second call at line 4 and 5 will begin reading with a reset state. No cigar.&lt;/p&gt;

&lt;p&gt;So we realized that the state of the lexer must be held by the lexer itself and in a way that can be represented persistently (e.g. as data in memory).&lt;/p&gt;

&lt;p&gt;Looking again at the pseudo code above for a batch lexer, we will look at what actually happens by unrolling the code:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The lexer is asked to read the next token&lt;/li&gt;
  &lt;li&gt;At this point the lexer has no context so the only thing it can do is to parse an “Expression”. Calling the “ReadExpression” function creates a new stack call entry. This is the state of what we are reading.&lt;/li&gt;
  &lt;li&gt;Okay, so we are reading an expression. Since we have no previous information about where in an expression we are, let’s look at the current character of the source code (it’s “’”)&lt;/li&gt;
  &lt;li&gt;Since the character is a “’” we know that a “Text” token is coming up. Call “ReadText” to enter a state of “reading text”.&lt;/li&gt;
  &lt;li&gt;Create a new token and store it into the variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;token&lt;/code&gt; that is kept on the stack. We need to keep track of the previous character since “\c” and “c” means different things. This is also kept as a variable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prev_was_escape&lt;/code&gt; living on the stack (or in the function’s scope, depending on the language we write this in, but whatever).&lt;/li&gt;
  &lt;li&gt;Look at the next character, look at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prev_was_escape&lt;/code&gt; and append &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next_char&lt;/code&gt; to the token value as we read.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Essentially each step is a certain code branch that flow into other code branches depending on certain branch-related values. So let’s move those values into a “lexer context” object which we instead pass around between readings.&lt;/p&gt;

&lt;p&gt;Let’s rewrite the previous batch lexer using this strategy.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;def Lexer():
  return {input = &quot;&quot;, input_offs = 0, token = nil, next_char = nil}

def ReadToken(L):
  result = nil
  while L.next_char:
    if L.token == nil:
      # Entry state
      if L.next_char == &quot;'&quot;:
        L.token = {type = TEXT, value = &quot;&quot;, prev_was_escape = false}
        ReadNextChar(L) # Consume &quot;'&quot;
      else:
        ...
    else if L.token.type == TEXT:
      if L.token.prev_was_escape:
        L.token.prev_was_escape = false
        token.value = concat(token.value, L.next_char)
      else if L.next_char == &quot;\\&quot;:
        L.token.prev_was_escape = true
      else if L.next_char == &quot;'&quot;:
        result = L.token
        delete result.prev_was_escape
        L.token = nil
      else:
        token.value = concat(token.value, L.next_char)
      ReadNextChar(L)
    else:
      ...
  return result

L = Lexer()
SetInput(L, &quot;'Hello wo&quot;)
ReadToken(L)  # -&amp;gt; nil
SetInput(L, &quot;rld'&quot;)
ReadToken(L)  # -&amp;gt; {type=TEXT, value=&quot;Hello world&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We simply moved the state into a structure (referenced to as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;L&lt;/code&gt; above) which we pass around instead of storing the state values on the stack. The function calls were replaced by logical code branches. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;token&lt;/code&gt; structure above is used to carry token code-branch specific state. This design not only performs better (in most languages) but it also meets our requirements of being able to be paused and resumed.&lt;/p&gt;

&lt;h3 id=&quot;a-javascript-implementation&quot;&gt;A JavaScript implementation&lt;/h3&gt;

&lt;p&gt;For this tutorial article series I’ve chosen JavaScript as it’s easily accessible, a very popular language, has built-in Unicode support (good since we are to be analyzing text) and runs almost anywhere.&lt;/p&gt;

&lt;p&gt;Before writing or running any code, install Node.js — a free, modern and efficient JavaScript environment that let’s you run JavaScript programs in a terminal session (just like Python, Ruby, Perl or any other regular program). It takes just a minute to download and install, so don’t hesitate: &lt;a href=&quot;http://nodejs.org/download/&quot;&gt;nodejs.org/download&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, let’s have a look at the lexer. It’s easiest if you &lt;a href=&quot;https://github.com/rsms/prog-lang-tutorial.git&quot;&gt;clone or fork the Git repository&lt;/a&gt; at &lt;a href=&quot;https://github.com/rsms/prog-lang-tutorial&quot;&gt;https://github.com/rsms/prog-lang-tutorial&lt;/a&gt; and have a look in the “01-lexer” directory. There is a file called &lt;em&gt;&lt;a href=&quot;https://github.com/rsms/prog-lang-tutorial/blob/master/01-lexer/lexer-demo.js&quot;&gt;lexer-demo.js&lt;/a&gt;&lt;/em&gt; — a simple program that imports our lexer and applies some sample source. Essentially it imports the Lexer module and does something like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var L = Lexer(), token;
L.appendSource('Foo (bar baz)');
while ((token = L.next(source_ended))) {
  console.log(Lexer.TOKEN_NAMES[token.type], token);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The interesting part is in the &lt;em&gt;&lt;a href=&quot;https://github.com/rsms/prog-lang-tutorial/blob/master/01-lexer/lib/mylang/Lexer.js&quot;&gt;lib/mylang/Lexer.js&lt;/a&gt;&lt;/em&gt; file, so let’s quickly look through the different sections of the Lexer code.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// Create a new Lexer object.
function Lexer() {
  return Object.create(Lexer.prototype, ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This function creates new Lexer objects with initial state. We call this function each time we start reading a new source stream.&lt;/p&gt;

&lt;p&gt;Next up is a set of token definitions. This is where we define each of the different token types that our language is constructed from.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var LINE                 = deftok('LINE');
var LEFT_PAREN           = deftok('LEFT_PAREN',           '(');
var RIGHT_PAREN          = deftok('RIGHT_PAREN',          ')');
var LEFT_SQUARE_BRACKET  = deftok('LEFT_SQUARE_BRACKET',  '[');
var RIGHT_SQUARE_BRACKET = deftok('RIGHT_SQUARE_BRACKET', ']');
var LEFT_CURLY_BRACKET   = deftok('LEFT_CURLY_BRACKET',   '{');
var RIGHT_CURLY_BRACKET  = deftok('RIGHT_CURLY_BRACKET',  '}');
var FULL_STOP            = deftok('FULL_STOP',            '.');
var COLON                = deftok('COLON',                ':');
var DECIMAL_NUMBER       = deftok('DECIMAL_NUMBER');
var HEX_NUMBER           = deftok('HEX_NUMBER');
var FRACTIONAL_NUMBER    = deftok('FRACTIONAL_NUMBER');
var SYMBOL               = deftok('SYMBOL');
var TEXT                 = deftok('TEXT');
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deftok&lt;/code&gt; helper function simply assigns the token a unique number identifier and if a second argument is given, associates that token id with a single character value (this is stored in the internal map &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SINGLE_TOKENS&lt;/code&gt;). The Lexer will be able to look up a character value in this map and if it’s there, immediately terminate any currently reading token. This is useful for single-character tokens which might appear immediately before or after for instance a symbol.&lt;/p&gt;

&lt;p&gt;The Lexer prototype is the prototype of the object returned by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lexer()&lt;/code&gt; function:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Lexer.prototype = {
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appendSource&lt;/code&gt; is used to set/append source input:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  // Add input source.
  // The `chunk` object need to have the following properties:
  //
  //  .charCodeAt(N)   A function that return the Unicode character value at
  //                   position N, or a NaN if N is out of bounds.
  //
  //  .substring(A, B) A function that returns another chunk object that
  //                   represents the Unicode characters in the range [A,B)
  //
  appendSource: function (chunk) { ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;makeToken&lt;/code&gt; is mean to be used only internally by other Lexer functions. This is called every time a new token is being read:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  // Create a new token of `type` based on the internal source location state
  makeToken: function (type) { ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flushToken&lt;/code&gt; is also meant as an internal function which is called each time a token is about to be returned as a result from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; function:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  // Returns the current token and clears the &quot;reading token&quot; state. This is
  // an appropriate place to perform some post processing on tokens before
  // they are returned to the caller of `next()`. If `terminated_by_eos` is
  // true, the token was terminated by end of source.
  flushToken: function (terminated_by_eos) { ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; is called to give control to the lexer and returns either when the lexer has read a token (a token is returned), when an error occurs (an exception is thrown) or the input source ended (null is returned).&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  // Reads the next token. If `source_ended` is true, then no more source is
  // expected to arrive and thus EOS acts as a token terminator.
  next: function (source_ended) { ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it for a summary of the Lexer design. I suggest you look through the code which is thoroughly documented.&lt;/p&gt;

&lt;p&gt;I’ve left one part unimplemented for you to write: Reading Text literals. Run the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lexer-demo.js&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ node lexer-demo.js
read_tokens(L)
L.next() -&amp;gt; SYMBOL 'Hello' at 0:0
L.next() -&amp;gt; SYMBOL '=' at 0:6
...
Error: Lesson 1: Implement reading of Text tokens
;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, the source is available at &lt;a href=&quot;https://github.com/rsms/prog-lang-tutorial&quot;&gt;https://github.com/rsms/prog-lang-tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the next article we will look at how semantic parsing fits into the evaluation pipeline.&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>Factorial and Fib in Hue</title>
    <link href="https://rsms.me/hue-factorial-fib"/>
    <updated>2012-05-29T00:00:00+00:00</updated>
    <id>https://rsms.me/hue-factorial-fib</id>
    <content type="html">&lt;p&gt;As I slowly make progress on my little functional programming language &lt;a href=&quot;https://github.com/rsms/hue&quot;&gt;Hue&lt;/a&gt;, I’d just wanted to share the “Hello World” of functional programming — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factorial&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fib&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Recursion_%28computer_science%29#Factorial&quot;&gt;factorial function&lt;/a&gt; calculates the factorial of a natural number:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3628800&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Recursion_%28computer_science%29#Fibonacci&quot;&gt;fib function&lt;/a&gt; computes Fibonacci numbers:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2178309&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hue compiles the above functions into very efficient &lt;a href=&quot;http://en.wikipedia.org/wiki/Tail_call&quot;&gt;tail calls&lt;/a&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factorial&lt;/code&gt; function is even unrolled, eliminating all but one call.&lt;/p&gt;

&lt;h2 id=&quot;function-result-type-inference-and-multiple-implementations&quot;&gt;Function result type inference and multiple implementations&lt;/h2&gt;

&lt;p&gt;Since Hue &lt;a href=&quot;https://github.com/rsms/hue/tree/94441d9b31157d712c078faa63c741d78ca3fba2/&quot;&gt;94441d9&lt;/a&gt; functions have their result types inferred, as well as the ability to define multiple implementations.&lt;/p&gt;

&lt;p&gt;To understand why the ability to provide multiple function implementations is interesting, let’s define a slightly more versatile &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factorial&lt;/code&gt; function:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0.0&lt;/span&gt;  &lt;span class=&quot;m&quot;&gt;1.0&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, we provide implementations for factorial to operate on both integers and floating point numbers. We can now invoke &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factorial&lt;/code&gt; with both Ints and Floats:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;    &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3628800&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;factorial&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10.0&lt;/span&gt;  &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3628800.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since Hue is strongly typed, simply providing a single implementation would only allow &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factorial&lt;/code&gt; to be available for either integers or floating point numbers (unless we gave the function different names, but that becomes awkward.)&lt;/p&gt;

&lt;p&gt;Result type inference is another important hygiene factor.&lt;/p&gt;

&lt;p&gt;This basically means that the parser will parse a function’s body before it finalizes the function’s result type. Since all functions in Hue return something, we know that whatever is returned is the result value of the function. If there’s any ambiguity the compiler will complain with an error, avoiding unexpected behavior at runtime.&lt;/p&gt;

&lt;p&gt;Consider the following trivial functions:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Defining the result type of these functions is &lt;em&gt;redundant&lt;/em&gt; and &lt;em&gt;unnecessary&lt;/em&gt;, since we can without a doubt say that “the result type of function F is the type of the value returned”. As Hue infers the type not only for functions, but for any other non-primary expression (like conditionals), when we after a decent-first reach the surface of an expression (i.e. the last expression of a function body), we will know the type of that expression, thus we can bubble the type upwards.&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As seen here above, we were able to write the same two functions in a more efficient manner.&lt;/p&gt;

&lt;p&gt;If a function references itself (i.e. is recursive), Hue will assume the type of the function based on other known types and later update those functions calls when the function’s result type has been finalized.&lt;/p&gt;

&lt;p&gt;Deferring the resolution of a recursive function type is possible since the only case where we are unable to do so, is the case where a recursive function is an infinite loop (which is currently not applicable to anything in Hue.) For instance:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;…would yield an error when compiled since it defines a function that is guaranteed to crash/block in all eternity. Any recursive function needs some kind of conditional, thus making our stupid &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; function a little more useful:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will compile, although the program will still crash when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; is given a value higher than 5. That’s the balance between being helpful and telling you what to do. In this example, the result type of the conditional (the “if..else”) is inferred from the one concrete branch (“n”), which in turn completes the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; function’s result type.&lt;/p&gt;

&lt;h2 id=&quot;tail-recursive-calls-ftw&quot;&gt;Tail recursive calls FTW&lt;/h2&gt;

&lt;p&gt;Let’s get all nerdy and look at the IR produced by Hue for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;factorial&lt;/code&gt; function example from the beginning of this article:&lt;/p&gt;

&lt;div class=&quot;language-llvm highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;nounwind&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readnone&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%tailrecurse.i&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;tailrecurse.i:&lt;/span&gt;                                    &lt;span class=&quot;c1&quot;&gt;; preds = %else.i, %0&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%accumulator.tr.i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;phi&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%multmp.i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%else.i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%n.tr.i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;phi&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%subtmp.i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%else.i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%eqtmp.i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;icmp&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;eq&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n.tr.i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%eqtmp.i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%&quot;hello:factorial$x$x.exit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%else.i&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;else.i:&lt;/span&gt;                                           &lt;span class=&quot;c1&quot;&gt;; preds = %tailrecurse.i&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%subtmp.i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n.tr.i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-1&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%multmp.i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mul&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%accumulator.tr.i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n.tr.i&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%tailrecurse.i&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;&quot;hello:factorial$x$x.exit&quot;:&lt;/span&gt;                       &lt;span class=&quot;c1&quot;&gt;; preds = %tailrecurse.i&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note how there’s actually &lt;em&gt;no function calls&lt;/em&gt; involved here. The compiler (mostly thanks to LLVM) were able to optimize the recursive call by unrolling the calls. The above code is very efficient.&lt;/p&gt;

&lt;p&gt;Let’s have look at what Hue does with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fib&lt;/code&gt; example function (from earlier in this article):&lt;/p&gt;

&lt;div class=&quot;language-llvm highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;nounwind&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readnone&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%fib_res&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@&quot;hello:fib$x$x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@&quot;hello:fib$x$x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;nounwind&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readnone&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%lttmp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;icmp&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;slt&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%lttmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%else&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;else:&lt;/span&gt;                                             &lt;span class=&quot;c1&quot;&gt;; preds = %0&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%subtmp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-1&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%fib_res&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@&quot;hello:fib$x$x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%subtmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%subtmp1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-2&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%fib_res2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@&quot;hello:fib$x$x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%subtmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%addtmp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%fib_res2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%fib_res&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%addtmp&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;endif:&lt;/span&gt;                                            &lt;span class=&quot;c1&quot;&gt;; preds = %0&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%n&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We didn’t get the royal unroll treatment, but the calls became tail recursive and the true-branch of the conditional expression was short-circuited into the end of the conditional (“endif”), saving us a “PHI” virtual instruction. This code is also very efficient and has linear time complexity.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/rsms/hue&quot;&gt;Hue&lt;/a&gt; continues to be my computer programming muse (and TV substitute) as a low intensity hobby project. The intention is to experiment with performant functional programming and to learn stuff, of course. Hue’s source code is free and open at &lt;a href=&quot;https://github.com/rsms/hue&quot;&gt;https://github.com/rsms/hue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See previous introduction to Hue: &lt;a href=&quot;http://rsms.me/2012/05/14/hue.html&quot;&gt;“Hue — a functional programming language for fun &amp;amp; play”&lt;/a&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
  <entry>
    <title>Hue — a functional programming language for fun &amp; play</title>
    <link href="https://rsms.me/hue-intro"/>
    <updated>2012-05-14T00:00:00+00:00</updated>
    <id>https://rsms.me/hue-intro</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/rsms/hue&quot;&gt;Hue&lt;/a&gt; is one of my latest hobby projects that didn’t die after a week. It’s a functional programming language, in a sense. There are no statements in this language, but everything is an expression. An expression does something funky and returns something—hopefully—even funkier. That includes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if..then..else&lt;/code&gt; as well as logical tests and functions.&lt;/p&gt;

&lt;p&gt;Anyhow, this hobby language of mine is still very much in flux and I’ll probably change its syntax and behavior a few times before I’m really happy with it. Haskell, Erlang and Clojure all have some pretty cool features but I’ve never been friends with their syntaxes. Me wants something closer to Python. Me write language.&lt;/p&gt;

&lt;p&gt;A programming language is in its essence a Human-Computer Interface. I’ve done these things in the past, for example the &lt;a href=&quot;https://github.com/rsms/move&quot;&gt;Move programming language&lt;/a&gt;. This time I wanted to write everything myself, starting at the instructions that the computer executes and all the way up to the runtime library, idioms, design opinions and concepts.&lt;/p&gt;

&lt;p&gt;So far I’ve spent evenings and weekends during the last five weeks hacking on this, bust more so I’ve been reading conceptual stuff, like Joe Armstrong’s thesis paper “&lt;a href=&quot;http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf&quot;&gt;Making reliable distributed systems in the presence of software errors&lt;/a&gt;” (chapters 1 and 2), where Joe dissects the inherent problems with trying to model the real world using a non-1:1 mapping (e.g. imperative programming that fakes concurrency) and so forth.&lt;/p&gt;

&lt;h2 id=&quot;from-hue-to-target-assembly&quot;&gt;From Hue to target assembly&lt;/h2&gt;

&lt;p&gt;A simple and completely useless program that contains a function which multiplies two integers with 9 and each other, then divides that with 4 and returns the result:&lt;/p&gt;

&lt;div class=&quot;language-rb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
                       &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 8550&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note a few things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Whitespace is significant. Like in the Python programming language, a colon “:” character denotes that a block of expressions follow. When the line indentation level drops from whatever level the expression that owns the “:” character is at, the block is terminated. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo&lt;/code&gt; function’s block contains two expressions.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Types are inferred. The language is strongly typed and in case the compiler is unable to infer the type, it will yield a compilation error. No types are inferred at runtime, which means that very few—or even no—errors related to types and value passing can happen when the program is run.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Functions are expressions and not a “special” thing. Functions can be passed around just like any other value.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Variables are actually just aliases and usually “folded” (removed and their values is just put in place) by the compiler.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s compile this program:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;hue hello.hue hello.ll
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And look at the &lt;a href=&quot;http://llvm.org/&quot;&gt;LLVM&lt;/a&gt; IR code that the Hue compiler generates:&lt;/p&gt;

&lt;div class=&quot;language-llvm highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;nounwind&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;                               &lt;span class=&quot;c1&quot;&gt;; 1&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%foo_res&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@&quot;hello$foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;950&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;c1&quot;&gt;; 2&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;                                                 &lt;span class=&quot;c1&quot;&gt;; 3&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;vg&quot;&gt;@&quot;hello$foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;nounwind&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;; 4&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%multmp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mul&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%y&lt;/span&gt;                                  &lt;span class=&quot;c1&quot;&gt;; 5&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%multmp1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mul&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%multmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;9&lt;/span&gt;                             &lt;span class=&quot;c1&quot;&gt;; 6&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;%divtmp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sdiv&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%multmp1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;                            &lt;span class=&quot;c1&quot;&gt;; 7&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;i64&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;%divtmp&lt;/span&gt;                                           &lt;span class=&quot;c1&quot;&gt;; 8&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Hue compiler generates LLVM &lt;a href=&quot;http://llvm.org/docs/LangRef.html&quot;&gt;intermediate representation code&lt;/a&gt;. Similar to what is output by e.g. Java and .NET compilers when an object file/program is built. LLVM is an amazing piece of compiler infrastructure software that enables a whole slew of features like native machine code generation, code optimization, etc. Going back to the above IR code, we see what actually happened to our program. I’ve given the lines above numbers, which we are referring to here:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;@main() is the entry point of our module. Or program in this case.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We call the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello$foo&lt;/code&gt; with two 64-bit integer values &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt;. We expect a return value that is a single 64-bit integer value, which we give the alias “%foo_res”. Notice how the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a = 19&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(5*10*a)&lt;/code&gt; expressions where &lt;em&gt;folded&lt;/em&gt; into 950 (“i64 950” in the IR above). Because values are constant, the compiler can “execute” obvious isolated parts of the program.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Our module returns control, with the 64-bit integer value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, to whatever called it (in this case, our program exists with status &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;This is where our function lives. “private” means that the function is only used inside this module, and “i64” means it returns a 64-bit integer value (Hue’s “Int” type is a 64-bit integer). The function takes two parameterized arguments which both are 64-bit integers and gives those parameters the aliases “%x” and “%y”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We ask the computer to multiply the two values behind the aliases “%x” and “%y” and give the resulting value an alias of “%multmp”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Again, we instruct the computer (these are so called “instructions”) to multiply two values: The result of multiplying “%x” and “%y”, which we did at line 5, with the number &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;9&lt;/code&gt; and alias the result as “%multmp1”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We divide the “%multmp1” value with the number &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4&lt;/code&gt; and alias the result as “%divtmp”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We return the value behind “%divtmp” to the caller.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we generate assembly for x86_64 (basically machine instructions), we get roughly the following:&lt;/p&gt;

&lt;div class=&quot;language-armasm highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;__TEXT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;__text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;regular&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pure_instructions&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;globl&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;_main&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;align&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x90&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;_main&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt;                          &lt;span class=&quot;c&quot;&gt;; 1&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;pushq&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rax&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;movl&lt;/span&gt;    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;edi&lt;/span&gt;              &lt;span class=&quot;c&quot;&gt;; 2 (1/4)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;movl&lt;/span&gt;    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;950&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;esi&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;; 2 (1/4)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;callq&lt;/span&gt;   &lt;span class=&quot;nv&quot;&gt;L_hello&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;$foo&lt;/span&gt;           &lt;span class=&quot;c&quot;&gt;; 2 (1/4)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;xorl&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;eax&lt;/span&gt;            &lt;span class=&quot;c&quot;&gt;; 3 (2/3)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;popq&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rdx&lt;/span&gt;                  &lt;span class=&quot;c&quot;&gt;; 3 (3/3)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;ret&lt;/span&gt;                           &lt;span class=&quot;c&quot;&gt;; 3 (4/3) ...&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;align&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x90&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;L_hello&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;$foo&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;imulq&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rsi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rdi&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;leaq&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;(%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rdi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rdi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rcx&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;movq&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rcx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rax&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;sarq&lt;/span&gt;    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;63&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rax&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;shrq&lt;/span&gt;    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;62&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rax&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;addq&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rcx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rax&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;sarq&lt;/span&gt;    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;rax&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Yeah, I know. This code gets scarier and scarier, but we can see how closely LLVM IR maps to target assembly, but we also understand the complexity of modeling something simple as the initial Hue program on x86_64 assembler.&lt;/p&gt;

&lt;p&gt;We can run our program, which by the way doesn’t really do anything, either straight through LLVM as JIT-ed code using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lli hello.ll&lt;/code&gt; or generate an object file and link it as a program:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;llvm-as -o=- hello.ll | llvm-ld -native -o=hello -
./hello
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Functional programming has for a long time been the toolbox of mathematicians and CS ninjas with beards (Johan and Erik — I’m lookin’ at you). My guess is that math people—clever fellas—invented these things and created syntaxes that fell natural to them. I never really payed attention to math in school and have no math education beyond the very basics, like multiplication, yet I have come to realize the awesomeness of math and its concepts. So how about we take the awesomeness of functional programming—high modularity and code re-use, testability, stability, etc—to us programming peasants of Python, JavaScript, BASIC and Java? Perhaps this project will be an attempt on that, or perhaps not.&lt;/p&gt;

&lt;h2 id=&quot;a-performant-immutable--persistent-vector-implementation&quot;&gt;A performant immutable &amp;amp; persistent vector implementation&lt;/h2&gt;

&lt;p&gt;Besides rambling about some yet-another-hobby-language, I wanted to talk about this one awesome, concrete thing that has come out of this project: An immutable persistent vector inspired by and partly ported from &lt;a href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt;’s PersistentVector. With this approach, you can freely manipulate a vector data structure concurrently without locking and more importantly without causing imperative situations where expected state is different depending on outside, out-of-our-control circumstances.&lt;/p&gt;

&lt;p&gt;Impressive numbers: Starting with the empty vector and appending one single item at a time until we reach one million takes roughly 200ms on a single 3.4 GHz i7 core. That is an average of 200 nanoseconds per append operation. Keep in mind that an append operation effectively creates a new vector — this data structure is in fact immutable, so we have to create a new, derived structure every time we “modify” it. With a traditional array-style structure, where we have N items in a uniform sequence, is cheap to copy when N is reasonably small (like 100 or so), but becomes a real bottleneck (and a problem for concurrent operations) when N grows.&lt;/p&gt;

&lt;p&gt;Now, writing to and updating vectors are usually less common that accessing items in them. Pretty convenient then that this implementation offers almost-constant time random access. Technically is a little less than constant, but it’s negligible in my opinion (see comments in &lt;a href=&quot;https://github.com/rsms/hue/blob/master/src/runtime/Vector.h&quot;&gt;Vector.h&lt;/a&gt; for more info).&lt;/p&gt;

&lt;p&gt;The source for this implementation is available from the &lt;a href=&quot;https://github.com/rsms/hue&quot;&gt;Hue GitHub repository&lt;/a&gt; together with some unit tests (look in the “test” directory or run the “test” make target).&lt;/p&gt;

&lt;p&gt;Numbers from running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make clean test_vector_perf&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;N = 100 (this run takes the unfortunate initial impact of lazy-loaded symbols)
    &lt;ul&gt;
      &lt;li&gt;Inserting 100 values: 0.028 ms (avg 280 ns/insert)&lt;/li&gt;
      &lt;li&gt;Accessing all 100 values: 0.002 ms (avg 20 ns/access)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;N = 100 000
    &lt;ul&gt;
      &lt;li&gt;Inserting 100000 values: 20.722 ms (avg 207.22 ns/insert)&lt;/li&gt;
      &lt;li&gt;Accessing all 100000 values: 0.531 ms (avg 5.31 ns/access)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;N = 1 000 000
    &lt;ul&gt;
      &lt;li&gt;Inserting 1000000 values: 204.391 ms (avg 204.391 ns/insert)&lt;/li&gt;
      &lt;li&gt;Accessing all 1000000 values: 5.171 ms (avg 5.171 ns/access)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;N = 10 000 000
    &lt;ul&gt;
      &lt;li&gt;Inserting 10000000 values: 2002.78 ms (avg 200.278 ns/insert)&lt;/li&gt;
      &lt;li&gt;Accessing all 10000000 values: 59.592 ms (avg 5.9592 ns/access)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;N = 100 000 000
    &lt;ul&gt;
      &lt;li&gt;Inserting 100000000 values: 19741.9 ms (avg 197.419 ns/insert)&lt;/li&gt;
      &lt;li&gt;Accessing all 100000000 values: 674.349 ms (avg 6.74349 ns/access)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can reason that for N up to at least 100 million, both insertion and random access is close to constant time complexity. It’s not nearly as fast as a traditional mutable vector which grows uniform regions of memory (e.g. std::vector or a plain C array), but given it’s immutable property, this is very good.&lt;/p&gt;

&lt;p&gt;Source code and other goodies are available at &lt;a href=&quot;https://github.com/rsms/hue&quot;&gt;github.com/rsms/hue&lt;/a&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Rasmus Andersson</name>
      <uri>https://rsms.me/about/</uri>
    </author>
  </entry>
  
</feed>