diff options
author | Loïc Hoguin <[email protected]> | 2017-10-03 13:39:41 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2017-10-03 13:39:41 +0200 |
commit | b5d4cb91f80c833795a2d87050c3674bb7aecdc5 (patch) | |
tree | 62bf0ad8326006fcd3407fcb7c34c844c0dc0874 /articles/xerl-0.3-atomic-expressions | |
parent | 1f8d51dd2692fc3978080419987bbe4d49a41a90 (diff) | |
download | ninenines.eu-b5d4cb91f80c833795a2d87050c3674bb7aecdc5.tar.gz ninenines.eu-b5d4cb91f80c833795a2d87050c3674bb7aecdc5.tar.bz2 ninenines.eu-b5d4cb91f80c833795a2d87050c3674bb7aecdc5.zip |
Update Hugo, docs
Diffstat (limited to 'articles/xerl-0.3-atomic-expressions')
-rw-r--r-- | articles/xerl-0.3-atomic-expressions/index.html | 398 |
1 files changed, 225 insertions, 173 deletions
diff --git a/articles/xerl-0.3-atomic-expressions/index.html b/articles/xerl-0.3-atomic-expressions/index.html index f3042180..b49b5613 100644 --- a/articles/xerl-0.3-atomic-expressions/index.html +++ b/articles/xerl-0.3-atomic-expressions/index.html @@ -7,7 +7,7 @@ <meta name="description" content=""> <meta name="author" content="Loïc Hoguin based on a design from (Soft10) Pol Cámara"> - <meta name="generator" content="Hugo 0.17" /> + <meta name="generator" content="Hugo 0.26" /> <title>Nine Nines: Xerl: atomic expressions</title> @@ -74,153 +74,153 @@ </p> </header> -<div class="paragraph"><p>We will be adding atomic integer expressions to our language.
-These look as follow in Erlang:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #993399">42</span><span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>And the result of this expression is of course 42.</p></div>
-<div class="paragraph"><p>We will be running this expression at compile time, since we
-don’t have the means to run code at runtime yet. This will of
-course result in no module being compiled, but that’s OK, it will
-allow us to discuss a few important things we’ll have to plan for
-later on.</p></div>
-<div class="paragraph"><p>First, we must of course accept integers in the tokenizer.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>{<span style="color: #009900">D</span>}<span style="color: #990000">+</span> <span style="color: #990000">:</span> {<span style="color: #FF6600">token</span>, {<span style="font-weight: bold"><span style="color: #000080">integer</span></span>, <span style="color: #009900">TokenLine</span>, <span style="font-weight: bold"><span style="color: #000080">list_to_integer</span></span>(<span style="color: #009900">TokenChars</span>)}}<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>We must then accept atomic integer expressions in the parser.
-This is a simple change. The integer token is terminal so we need
-to add it to the list of terminals, and then we only need to add
-it as a possible expression.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #FF6600">expr</span> <span style="color: #990000">-></span> <span style="color: #FF6600">integer</span> <span style="color: #990000">:</span> <span style="color: #FF6600">'$1'</span><span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>A file containing only the number 42 (with no terminating dot)
-will give the following result when parsing it. This is incidentally
-the same result as when tokenizing.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>[{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">42</span>}]</tt></pre></div></div>
-<div class="paragraph"><p>We must then evaluate it. We’re going to interpret it for now.
-Since the result of this expression is not stored in a variable,
-we are going to simply print it on the screen and discard it.</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-weight: bold"><span style="color: #000000">execute</span></span>(<span style="color: #009900">Filename</span>, [{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>, <span style="color: #990000">_</span>, <span style="color: #009900">Int</span>}|<span style="color: #009900">Tail</span>], <span style="color: #009900">Modules</span>) <span style="color: #990000">-></span>
- <span style="font-weight: bold"><span style="color: #000000">io:format</span></span>(<span style="color: #FF0000">"integer ~p~n"</span>, [<span style="color: #009900">Int</span>]),
- <span style="font-weight: bold"><span style="color: #000000">execute</span></span>(<span style="color: #009900">Filename</span>, <span style="color: #009900">Tail</span>, <span style="color: #009900">Modules</span>)<span style="color: #990000">.</span></tt></pre></div></div>
-<div class="paragraph"><p>You might think by now that what we’ve done so far this time
-is useless. It brings up many interesting questions though.</p></div>
-<div class="ulist"><ul>
-<li>
-<p>
-What happens if a file contains two integers?
-</p>
-</li>
-<li>
-<p>
-Can we live without expression separators?
-</p>
-</li>
-<li>
-<p>
-Do we need an interpreter for the compile step?
-</p>
-</li>
-</ul></div>
-<div class="paragraph"><p>This is what happens when we create a file that contains two
-integers on two separate lines:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>[{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">42</span>},{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">2</span>,<span style="color: #993399">43</span>}]</tt></pre></div></div>
-<div class="paragraph"><p>And on the same lines:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>[{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">42</span>},{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">43</span>}]</tt></pre></div></div>
-<div class="paragraph"><p>Does this mean we do not need separators between expressions?
-Not quite. The <code>+</code> and <code>-</code> operators are an
-example of why we can’t have nice things. They are ambiguous. They
-have two different meanings: make an atomic integer positive or
-negative, or perform an addition or a substraction between two
-integers. Without a separator you won’t be able to know if the
-following snippet is one or two expressions:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #993399">42</span> <span style="color: #990000">-</span> <span style="color: #993399">12</span></tt></pre></div></div>
-<div class="paragraph"><p>Can we use the line ending as an expression separator then?
-Some languages make whitespace important, often the line
-separator becomes the expression separator. I do not think this
-is the best idea, it can lead to errors. For example the following
-snippet would be two expressions:</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.8
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="color: #009900">Var</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">some_module:some_function</span></span>() <span style="color: #990000">+</span> <span style="font-weight: bold"><span style="color: #000000">some_module:other_function</span></span>()
- <span style="color: #990000">+</span> <span style="font-weight: bold"><span style="color: #000000">another_module:another_function</span></span>()</tt></pre></div></div>
-<div class="paragraph"><p>It is not obvious what would happen unless you are a veteran
-of the language, and so we will not go down that road. We will use
-an expression separator just like in Erlang: the comma. We will
-however allow a trailing comma to make copy pasting code easier,
-even if this means some old academics guy will go nuts about it
-later on. This trailing comma will be optional and simply discarded
-by the parser when encountered. We will implement this next.</p></div>
-<div class="paragraph"><p>The question as to how we will handle running expressions
-remains. We have two choices here: we can write an interpreter,
-or we can compile the code and run it. Writing an interpreter
-would require us to do twice the work, and we are lazy, so we will
-not do that.</p></div>
-<div class="paragraph"><p>You might already know that Erlang does not use the same code
-for compiling and for evaluating commands in the shell. The main
-reason for this is that in Erlang everything isn’t an expression.
-Indeed, the compiler compiles forms which contain expressions,
-but you can’t have forms in the shell.</p></div>
-<div class="paragraph"><p>How are we going to compile the code that isn’t part of a module
-then? What do we need to run at compile-time, anyway? The body of
-the file itself, of course. The body of module declarations. That’s
-about it.</p></div>
-<div class="paragraph"><p>For the file itself, we can simply compile it as a big function
-that will be executed. Then, everytime we encounter a module
-declaration, we will run the compiler on its body, making its body
-essentially a big function that will be executed. The same mechanism
-will be applied when we encounter a module declaration at runtime.</p></div>
-<div class="paragraph"><p>At runtime there’s nothing else for us to do, the result of this
-operation will load all the compiled modules. At compile time we
-will also want to save them to a file. We’ll see later how we can
-do that.</p></div>
-<div class="ulist"><ul>
-<li>
-<p>
-<a href="https://github.com/extend/xerl/blob/0.3/">View the source</a>
-</p>
-</li>
-</ul></div>
+<div class="paragraph"><p>We will be adding atomic integer expressions to our language. +These look as follow in Erlang:</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt><span style="color: #993399">42</span><span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>And the result of this expression is of course 42.</p></div> +<div class="paragraph"><p>We will be running this expression at compile time, since we +don’t have the means to run code at runtime yet. This will of +course result in no module being compiled, but that’s OK, it will +allow us to discuss a few important things we’ll have to plan for +later on.</p></div> +<div class="paragraph"><p>First, we must of course accept integers in the tokenizer.</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt>{<span style="color: #009900">D</span>}<span style="color: #990000">+</span> <span style="color: #990000">:</span> {<span style="color: #FF6600">token</span>, {<span style="font-weight: bold"><span style="color: #000080">integer</span></span>, <span style="color: #009900">TokenLine</span>, <span style="font-weight: bold"><span style="color: #000080">list_to_integer</span></span>(<span style="color: #009900">TokenChars</span>)}}<span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>We must then accept atomic integer expressions in the parser. +This is a simple change. The integer token is terminal so we need +to add it to the list of terminals, and then we only need to add +it as a possible expression.</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt><span style="color: #FF6600">expr</span> <span style="color: #990000">-></span> <span style="color: #FF6600">integer</span> <span style="color: #990000">:</span> <span style="color: #FF6600">'$1'</span><span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>A file containing only the number 42 (with no terminating dot) +will give the following result when parsing it. This is incidentally +the same result as when tokenizing.</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt>[{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">42</span>}]</tt></pre></div></div> +<div class="paragraph"><p>We must then evaluate it. We’re going to interpret it for now. +Since the result of this expression is not stored in a variable, +we are going to simply print it on the screen and discard it.</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt><span style="font-weight: bold"><span style="color: #000000">execute</span></span>(<span style="color: #009900">Filename</span>, [{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>, <span style="color: #990000">_</span>, <span style="color: #009900">Int</span>}|<span style="color: #009900">Tail</span>], <span style="color: #009900">Modules</span>) <span style="color: #990000">-></span> + <span style="font-weight: bold"><span style="color: #000000">io:format</span></span>(<span style="color: #FF0000">"integer ~p~n"</span>, [<span style="color: #009900">Int</span>]), + <span style="font-weight: bold"><span style="color: #000000">execute</span></span>(<span style="color: #009900">Filename</span>, <span style="color: #009900">Tail</span>, <span style="color: #009900">Modules</span>)<span style="color: #990000">.</span></tt></pre></div></div> +<div class="paragraph"><p>You might think by now that what we’ve done so far this time +is useless. It brings up many interesting questions though.</p></div> +<div class="ulist"><ul> +<li> +<p> +What happens if a file contains two integers? +</p> +</li> +<li> +<p> +Can we live without expression separators? +</p> +</li> +<li> +<p> +Do we need an interpreter for the compile step? +</p> +</li> +</ul></div> +<div class="paragraph"><p>This is what happens when we create a file that contains two +integers on two separate lines:</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt>[{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">42</span>},{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">2</span>,<span style="color: #993399">43</span>}]</tt></pre></div></div> +<div class="paragraph"><p>And on the same lines:</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt>[{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">42</span>},{<span style="font-weight: bold"><span style="color: #000080">integer</span></span>,<span style="color: #993399">1</span>,<span style="color: #993399">43</span>}]</tt></pre></div></div> +<div class="paragraph"><p>Does this mean we do not need separators between expressions? +Not quite. The <code>+</code> and <code>-</code> operators are an +example of why we can’t have nice things. They are ambiguous. They +have two different meanings: make an atomic integer positive or +negative, or perform an addition or a substraction between two +integers. Without a separator you won’t be able to know if the +following snippet is one or two expressions:</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt><span style="color: #993399">42</span> <span style="color: #990000">-</span> <span style="color: #993399">12</span></tt></pre></div></div> +<div class="paragraph"><p>Can we use the line ending as an expression separator then? +Some languages make whitespace important, often the line +separator becomes the expression separator. I do not think this +is the best idea, it can lead to errors. For example the following +snippet would be two expressions:</p></div> +<div class="listingblock"> +<div class="content"><!-- Generator: GNU source-highlight 3.1.8 +by Lorenzo Bettini +http://www.lorenzobettini.it +http://www.gnu.org/software/src-highlite --> +<pre><tt><span style="color: #009900">Var</span> <span style="color: #990000">=</span> <span style="font-weight: bold"><span style="color: #000000">some_module:some_function</span></span>() <span style="color: #990000">+</span> <span style="font-weight: bold"><span style="color: #000000">some_module:other_function</span></span>() + <span style="color: #990000">+</span> <span style="font-weight: bold"><span style="color: #000000">another_module:another_function</span></span>()</tt></pre></div></div> +<div class="paragraph"><p>It is not obvious what would happen unless you are a veteran +of the language, and so we will not go down that road. We will use +an expression separator just like in Erlang: the comma. We will +however allow a trailing comma to make copy pasting code easier, +even if this means some old academics guy will go nuts about it +later on. This trailing comma will be optional and simply discarded +by the parser when encountered. We will implement this next.</p></div> +<div class="paragraph"><p>The question as to how we will handle running expressions +remains. We have two choices here: we can write an interpreter, +or we can compile the code and run it. Writing an interpreter +would require us to do twice the work, and we are lazy, so we will +not do that.</p></div> +<div class="paragraph"><p>You might already know that Erlang does not use the same code +for compiling and for evaluating commands in the shell. The main +reason for this is that in Erlang everything isn’t an expression. +Indeed, the compiler compiles forms which contain expressions, +but you can’t have forms in the shell.</p></div> +<div class="paragraph"><p>How are we going to compile the code that isn’t part of a module +then? What do we need to run at compile-time, anyway? The body of +the file itself, of course. The body of module declarations. That’s +about it.</p></div> +<div class="paragraph"><p>For the file itself, we can simply compile it as a big function +that will be executed. Then, everytime we encounter a module +declaration, we will run the compiler on its body, making its body +essentially a big function that will be executed. The same mechanism +will be applied when we encounter a module declaration at runtime.</p></div> +<div class="paragraph"><p>At runtime there’s nothing else for us to do, the result of this +operation will load all the compiled modules. At compile time we +will also want to save them to a file. We’ll see later how we can +do that.</p></div> +<div class="ulist"><ul> +<li> +<p> +<a href="https://github.com/extend/xerl/blob/0.3/">View the source</a> +</p> +</li> +</ul></div> </article> </div> @@ -229,55 +229,107 @@ do that.</p></div> <h3>More articles</h3> <ul id="articles-nav" class="extra_margin"> - <li><a href="https://ninenines.eu/articles/cowboy-2.0.0-rc.2/">Cowboy 2.0 release candidate 2</a></li> + + <li><a href="https://ninenines.eu/articles/cowboy-2.0.0-rc.2/">Cowboy 2.0 release candidate 2</a></li> + - <li><a href="https://ninenines.eu/articles/cowboy-2.0.0-rc.1/">Cowboy 2.0 release candidate 1</a></li> + + <li><a href="https://ninenines.eu/articles/cowboy-2.0.0-rc.1/">Cowboy 2.0 release candidate 1</a></li> + - <li><a href="https://ninenines.eu/articles/the-elephant-in-the-room/">The elephant in the room</a></li> + + <li><a href="https://ninenines.eu/articles/the-elephant-in-the-room/">The elephant in the room</a></li> + - <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don't let it crash</a></li> + + <li><a href="https://ninenines.eu/articles/dont-let-it-crash/">Don't let it crash</a></li> + - <li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li> + + <li><a href="https://ninenines.eu/articles/cowboy-2.0.0-pre.4/">Cowboy 2.0 pre-release 4</a></li> + - <li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li> + + <li><a href="https://ninenines.eu/articles/ranch-1.3/">Ranch 1.3</a></li> + - <li><a href="https://ninenines.eu/articles/ml-archives/">Mailing list archived</a></li> + + <li><a href="https://ninenines.eu/articles/ml-archives/">Mailing list archived</a></li> + - <li><a href="https://ninenines.eu/articles/website-update/">Website update</a></li> + + <li><a href="https://ninenines.eu/articles/website-update/">Website update</a></li> + - <li><a href="https://ninenines.eu/articles/erlanger-playbook-september-2015-update/">The Erlanger Playbook September 2015 Update</a></li> + + <li><a href="https://ninenines.eu/articles/erlanger-playbook-september-2015-update/">The Erlanger Playbook September 2015 Update</a></li> + - <li><a href="https://ninenines.eu/articles/erlanger-playbook/">The Erlanger Playbook</a></li> + + <li><a href="https://ninenines.eu/articles/erlanger-playbook/">The Erlanger Playbook</a></li> + - <li><a href="https://ninenines.eu/articles/erlang-validate-utf8/">Validating UTF-8 binaries with Erlang</a></li> + + <li><a href="https://ninenines.eu/articles/erlang-validate-utf8/">Validating UTF-8 binaries with Erlang</a></li> + - <li><a href="https://ninenines.eu/articles/on-open-source/">On open source</a></li> + + <li><a href="https://ninenines.eu/articles/on-open-source/">On open source</a></li> + - <li><a href="https://ninenines.eu/articles/the-story-so-far/">The story so far</a></li> + + <li><a href="https://ninenines.eu/articles/the-story-so-far/">The story so far</a></li> + - <li><a href="https://ninenines.eu/articles/cowboy2-qs/">Cowboy 2.0 and query strings</a></li> + + <li><a href="https://ninenines.eu/articles/cowboy2-qs/">Cowboy 2.0 and query strings</a></li> + - <li><a href="https://ninenines.eu/articles/january-2014-status/">January 2014 status</a></li> + + <li><a href="https://ninenines.eu/articles/january-2014-status/">January 2014 status</a></li> + - <li><a href="https://ninenines.eu/articles/farwest-funded/">Farwest got funded!</a></li> + + <li><a href="https://ninenines.eu/articles/farwest-funded/">Farwest got funded!</a></li> + - <li><a href="https://ninenines.eu/articles/erlang.mk-and-relx/">Build Erlang releases with Erlang.mk and Relx</a></li> + + <li><a href="https://ninenines.eu/articles/erlang.mk-and-relx/">Build Erlang releases with Erlang.mk and Relx</a></li> + - <li><a href="https://ninenines.eu/articles/xerl-0.5-intermediate-module/">Xerl: intermediate module</a></li> + + <li><a href="https://ninenines.eu/articles/xerl-0.5-intermediate-module/">Xerl: intermediate module</a></li> + - <li><a href="https://ninenines.eu/articles/xerl-0.4-expression-separator/">Xerl: expression separator</a></li> + + <li><a href="https://ninenines.eu/articles/xerl-0.4-expression-separator/">Xerl: expression separator</a></li> + - <li><a href="https://ninenines.eu/articles/erlang-scalability/">Erlang Scalability</a></li> + + <li><a href="https://ninenines.eu/articles/erlang-scalability/">Erlang Scalability</a></li> + - <li><a href="https://ninenines.eu/articles/xerl-0.3-atomic-expressions/">Xerl: atomic expressions</a></li> + + <li><a href="https://ninenines.eu/articles/xerl-0.3-atomic-expressions/">Xerl: atomic expressions</a></li> + - <li><a href="https://ninenines.eu/articles/xerl-0.2-two-modules/">Xerl: two modules</a></li> + + <li><a href="https://ninenines.eu/articles/xerl-0.2-two-modules/">Xerl: two modules</a></li> + - <li><a href="https://ninenines.eu/articles/xerl-0.1-empty-modules/">Xerl: empty modules</a></li> + + <li><a href="https://ninenines.eu/articles/xerl-0.1-empty-modules/">Xerl: empty modules</a></li> + - <li><a href="https://ninenines.eu/articles/ranch-ftp/">Build an FTP Server with Ranch in 30 Minutes</a></li> + + <li><a href="https://ninenines.eu/articles/ranch-ftp/">Build an FTP Server with Ranch in 30 Minutes</a></li> + - <li><a href="https://ninenines.eu/articles/tictactoe/">Erlang Tic Tac Toe</a></li> + + <li><a href="https://ninenines.eu/articles/tictactoe/">Erlang Tic Tac Toe</a></li> + + + </ul> |