<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Tim Johns</title>
        <link>https://timjohns.ca</link>
        <description><![CDATA[Blog]]></description>
        <atom:link href="https://timjohns.ca/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Wed, 06 Dec 2023 00:00:00 UT</lastBuildDate>
        <item>
    <title>TypeScript's Hidden Feature: Subtypes</title>
    <link>https://timjohns.ca/typescripts-hidden-feature-subtypes.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        TypeScript's Hidden Feature: Subtypes
      </h1>
      <p class="writing">Dec  6, 2023</p>
      
    </header>
	<img class="post-image" alt="" src="./images/blog/typescript_subtypes.png" />
    <section class="content writing">
	  <p>This is a really cool thing in TypeScript I’ve been exploring recently. It turns out you can make <strong>subtypes</strong> without any extra libraries or tools! And the code to do it is <em>really easy</em>.</p>
<p>Imagine you could finally have types for <strong>positive integers</strong> or <strong>non-empty strings</strong> where you need them:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> PositiveInteger <span class="op">=</span> <span class="op">???</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> NonEmptyString <span class="op">=</span> <span class="op">???</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Product <span class="op">=</span> {</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  name<span class="op">:</span> NonEmptyString</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  description<span class="op">:</span> <span class="dt">string</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  priceCents<span class="op">:</span> PositiveInteger</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> addToCart <span class="op">=</span> (product<span class="op">:</span> Product<span class="op">,</span> quantity<span class="op">:</span> PositiveInteger<span class="op">,</span> cart<span class="op">:</span> Cart) <span class="kw">=&gt;</span> Cart {</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>  <span class="co">// add a product, not having to worry about the quantity being a negative number or 0</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Then you wouldn’t have to handle weird edge-cases like a product with an empty name, or a quantity that’s fractional or negative.</p>
<p>You could even strictly accept pre-validated parameters:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ValidName <span class="op">=</span> <span class="op">???</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ValidBirthYear <span class="op">=</span> <span class="op">???</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="co">// This function will only accept a valid name and birth year.</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> register <span class="op">=</span> (name<span class="op">:</span> ValidName<span class="op">,</span> birthYear<span class="op">:</span> ValidBirthYear)<span class="op">:</span> <span class="dt">void</span> <span class="kw">=&gt;</span> {</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Registering user &quot;</span><span class="sc">${</span>name<span class="sc">}</span><span class="vs">&quot; born in </span><span class="sc">${</span>birthYear<span class="sc">}</span><span class="vs">.`</span>)</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h1 id="what-are-subtypes">What are subtypes?</h1>
<p>In simple terms, a subtype is when you narrow down a type to be more specific.</p>
<p>In logical terms, <em>B</em> is a subtype of <em>A</em> when all <em>Bs</em> are <em>As</em>. For example, all cats are mammals. So, <em>Cat</em> is a subtype of <em>Mammal</em>. And <em>Mammal</em> is a subtype of <em>Animal</em>. <em>Prime number</em> is a subtype of <em>Natural number</em>. You get the picture.</p>
<p>You can think of making a subtype of type <em>A</em> by choosing a certain property that some <em>As</em> may have. This means <em>B</em> is a subtype of <em>A</em> defined by some predicate over <em>A</em>. In other words, any value of type <em>A</em> can be of type <em>B</em> if it has that chosen property. If this sounds complicated, don’t worry—it will make more sense in a moment.</p>
<h1 id="-the-code-">✨ The code ✨</h1>
<h2 id="subtype-positive-number">Subtype: Positive Number</h2>
<p>Starting with an example, this is how you can make a subtype for positive numbers:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> A <span class="op">=</span> <span class="dt">number</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> PositiveNumber <span class="op">=</span> A <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isPositiveNumber <span class="op">=</span> (x<span class="op">:</span> A)<span class="op">:</span> x <span class="kw">is</span> PositiveNumber <span class="kw">=&gt;</span> {</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> x <span class="op">&gt;=</span> <span class="dv">1</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> x<span class="op">:</span> A <span class="op">=</span> <span class="dv">2</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isPositiveNumber</span>(x)) {</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> y<span class="op">:</span> PositiveNumber <span class="op">=</span> x</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;y:&#39;</span><span class="op">,</span> y)</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Looks weird, right? I’ll break it down line by line.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> A <span class="op">=</span> <span class="dt">number</span></span></code></pre></div>
<p>You don’t really need this line; I added it for clarity. This is just making <code>A</code> a type alias for <code>number</code>. When you’re making a subtype of some custom type (instead of a primitive type), <code>A</code> would be that custom type.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> PositiveNumber <span class="op">=</span> A <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span></code></pre></div>
<p>This is the weirdest line you have to write. This makes a new type <code>PositiveNumber</code>, defined as the type <code>A</code> along with a new property with a unique symbol. Everything about the added property is to prevent you from being able to make a value of type <code>PositiveNumber</code> directly, while retaining the original properties of type <code>A</code>.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> You don’t need to worry about exactly how this works. The cool thing is, this line doesn’t change! Anytime you make a subtype, you can write this line the same way (substituting <code>A</code> for the (super)type of your choice). Notice that this line doesn’t actually say anything about what a positive number is; it just gives the subtype a name. This line should always be paired with a predicate function:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isPositiveNumber <span class="op">=</span> (x<span class="op">:</span> A)<span class="op">:</span> x <span class="kw">is</span> PositiveNumber <span class="kw">=&gt;</span> {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> x <span class="op">&gt;=</span> <span class="dv">1</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>This is where the meaning of <code>PositiveNumber</code> is actually defined. More than that, without this function, you can’t even make a <code>PositiveNumber</code> value!<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> This is using TypeScript’s feature of <a href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates">type predicates</a>. You can think of this function as returning a normal boolean value, though TypeScript gives it special treatment that brings this all together:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> x<span class="op">:</span> A <span class="op">=</span> <span class="dv">2</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isPositiveNumber</span>(x)) {</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> y<span class="op">:</span> PositiveNumber <span class="op">=</span> x</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;y:&#39;</span><span class="op">,</span> y)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>This is where things get really interesting. Like I said, the only way to make a <code>PositiveNumber</code> value is to invoke the <code>isPositiveNumber</code> predicate function on some value <code>x</code> of type <code>A</code>. And the only place where TypeScript will accept that you can actually have a <code>PositiveNumber</code> value is in the scope where <code>isPositiveNumber(x)</code> returned <code>true</code>. The way I think of it, you need to use the predicate function to provide a <strong>proof</strong> that you have a value of your subtype. After all, your subtype is defined by that predicate. So in this code, <code>y</code> is allowed to be of type <code>PositiveNumber</code> if you set it to <code>x</code> in scope of where <code>isPositiveNumber(x)</code> returned <code>true</code>.</p>
<h2 id="shorter-version">Shorter Version</h2>
<p>In practice, I would write and use the <code>PositiveNumber</code> subtype a little differently:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> PositiveNumber <span class="op">=</span> <span class="dt">number</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isPositiveNumber <span class="op">=</span> (x<span class="op">:</span> A)<span class="op">:</span> x <span class="kw">is</span> PositiveNumber <span class="kw">=&gt;</span> {</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> x <span class="op">&gt;=</span> <span class="dv">1</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> x<span class="op">:</span> A <span class="op">=</span> <span class="dv">2</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isPositiveNumber</span>(x)) {</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;x:&#39;</span><span class="op">,</span> x)</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>All I’ve done is remove the superfluous <code>A</code> type alias and the <code>y</code> variable. In the scope where <code>x</code> has been proven to be a positive number, <code>x</code> itself can be of type <code>PositiveNumber</code>. In fact, <code>x</code> can be treated as being a <code>number</code> or a <code>PositiveNumber</code> within that context.</p>
<h2 id="general-subtype-template">General Subtype Template</h2>
<p>The general structure for making and using a subtype looks like this:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> A <span class="op">=</span> {} <span class="co">// some specific type</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> B <span class="op">=</span> A <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isB <span class="op">=</span> (x<span class="op">:</span> A)<span class="op">:</span> x <span class="kw">is</span> B <span class="kw">=&gt;</span> {</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="co">// return a boolean value</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="kw">true</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> x<span class="op">:</span> A <span class="op">=</span> {} <span class="co">// some value of type A</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isB</span>(x)) {</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> y<span class="op">:</span> B <span class="op">=</span> x</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;y:&#39;</span><span class="op">,</span> y)</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h1 id="why-does-this-matter">Why does this matter?</h1>
<p>If you’re not yet convinced of the usefulness of subtypes, reflect on why you’re using TypeScript in the first place: you want to have a type checker catch any obvious mistakes during compile-time as opposed to you discovering them later during runtime. You want to make sure the data you’re working with conforms to the types you’ve decided it should. Why not extend that notion to even more useful types? Do you really think a general <strong>number</strong> type is the best case for any numeric scenario? Surely a <strong>non-negative number</strong> or a <strong>whole number</strong> would be better for many cases.</p>
<p>And if you’re <em>still</em> not convinced, maybe the next two sections will change your mind.</p>
<h1 id="you-can-test-subtypes">You can test subtypes!</h1>
<p>Maybe you’re worried your predicate function doesn’t define your subtype correctly. Not a problem! You can always treat the predicate function as if it returns a normal boolean and write tests for it.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ValidBirthYear <span class="op">=</span> <span class="dt">number</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isValidBirthYear <span class="op">=</span> (year<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> year <span class="kw">is</span> ValidBirthYear <span class="kw">=&gt;</span> {</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> thisYear<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="kw">new</span> <span class="bu">Date</span>()<span class="op">.</span><span class="fu">getFullYear</span>()</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> year <span class="op">&gt;=</span> <span class="dv">1900</span> <span class="op">&amp;&amp;</span> year <span class="op">&lt;=</span> thisYear</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;Tests for ValidBirthYear:&#39;</span>)</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">isValidBirthYear</span>(<span class="dv">1900</span>))</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="op">!</span><span class="fu">isValidBirthYear</span>(<span class="dv">1800</span>))</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">isValidBirthYear</span>(<span class="dv">2023</span>))</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="op">!</span><span class="fu">isValidBirthYear</span>(<span class="dv">2100</span>))</span></code></pre></div>
<h1 id="more-examples">More examples</h1>
<p>I want to finish off with a bunch of pragmatic examples to show some different ways of how you might use subtypes in your own projects.</p>
<h2 id="nonnegativeinteger">NonNegativeInteger</h2>
<div class="sourceCode" id="cb11"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> NonNegativeInteger <span class="op">=</span> <span class="dt">number</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isNonNegativeInteger <span class="op">=</span> (x<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> x <span class="kw">is</span> NonNegativeInteger <span class="kw">=&gt;</span> {</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">!</span>(x <span class="op">&lt;</span> <span class="dv">0</span>) <span class="op">&amp;&amp;</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">floor</span>(x) <span class="op">===</span> x</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> betterRepeat <span class="op">=</span> (s<span class="op">:</span> <span class="dt">string</span><span class="op">,</span> n<span class="op">:</span> NonNegativeInteger)<span class="op">:</span> <span class="dt">string</span> <span class="kw">=&gt;</span> {</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> s<span class="op">.</span><span class="fu">repeat</span>(n)</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> ex1<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="dv">3</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isNonNegativeInteger</span>(ex1)) {</span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>  <span class="co">// This will run.</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">betterRepeat</span>(<span class="st">&#39;hello&#39;</span><span class="op">,</span> ex1))</span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> ex2<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="fl">3.1</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isNonNegativeInteger</span>(ex2)) {</span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a>  <span class="co">// This won&#39;t run.</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">betterRepeat</span>(<span class="st">&#39;hello&#39;</span><span class="op">,</span> ex2))</span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> ex3<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="op">-</span><span class="dv">3</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isNonNegativeInteger</span>(ex3)) {</span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a>  <span class="co">// This won&#39;t run.</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">betterRepeat</span>(<span class="st">&#39;hello&#39;</span><span class="op">,</span> ex3))</span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>In the third example usage, where <code>ex3</code> is <code>-3</code>, normally giving a negative number to the String.prototype.repeat() function would produce a runtime error. Instead, we caught it in compile-time and prevented it from happening at all!</p>
<h2 id="nonemptyarray">NonEmptyArray</h2>
<p>Non-empty arrays are very useful in functional programming.</p>
<p>Normally, functions like head() and last() would return <code>undefined</code> when given an empty array, breaking the type rules:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> head <span class="op">=</span> <span class="op">&lt;</span>T<span class="op">&gt;</span>(xs<span class="op">:</span> <span class="bu">Array</span><span class="op">&lt;</span>T<span class="op">&gt;</span>)<span class="op">:</span> T <span class="kw">=&gt;</span> xs[<span class="dv">0</span>]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> last <span class="op">=</span> <span class="op">&lt;</span>T<span class="op">&gt;</span>(xs<span class="op">:</span> <span class="bu">Array</span><span class="op">&lt;</span>T<span class="op">&gt;</span>)<span class="op">:</span> T <span class="kw">=&gt;</span> xs[xs<span class="op">.</span><span class="at">length</span> <span class="op">-</span> <span class="dv">1</span>]</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> arrEmpty<span class="op">:</span> <span class="bu">Array</span><span class="op">&lt;</span><span class="dt">number</span><span class="op">&gt;</span> <span class="op">=</span> []</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;head(arrEmpty):&#39;</span><span class="op">,</span> <span class="fu">head</span>(arrEmpty)) <span class="co">// undefined</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;last(arrEmpty):&#39;</span><span class="op">,</span> <span class="fu">last</span>(arrEmpty)) <span class="co">// undefined</span></span></code></pre></div>
<p>We can make better versions with a <code>NonEmptyArray</code> subtype:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> NonEmptyArray<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">=</span> <span class="bu">Array</span><span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isNonEmptyArray <span class="op">=</span> <span class="op">&lt;</span>T<span class="op">&gt;</span>(xs<span class="op">:</span> <span class="bu">Array</span><span class="op">&lt;</span>T<span class="op">&gt;</span>)<span class="op">:</span> xs <span class="kw">is</span> NonEmptyArray<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="kw">=&gt;</span> {</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> xs<span class="op">.</span><span class="at">length</span> <span class="op">&gt;=</span> <span class="dv">1</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> head <span class="op">=</span> <span class="op">&lt;</span>T<span class="op">&gt;</span>(xs<span class="op">:</span> NonEmptyArray<span class="op">&lt;</span>T<span class="op">&gt;</span>)<span class="op">:</span> T <span class="kw">=&gt;</span> xs[<span class="dv">0</span>]</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> last <span class="op">=</span> <span class="op">&lt;</span>T<span class="op">&gt;</span>(xs<span class="op">:</span> NonEmptyArray<span class="op">&lt;</span>T<span class="op">&gt;</span>)<span class="op">:</span> T <span class="kw">=&gt;</span> xs[xs<span class="op">.</span><span class="at">length</span> <span class="op">-</span> <span class="dv">1</span>]</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> arr1<span class="op">:</span> <span class="bu">Array</span><span class="op">&lt;</span><span class="dt">number</span><span class="op">&gt;</span> <span class="op">=</span> [<span class="dv">1</span>]</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> arrEmpty<span class="op">:</span> <span class="bu">Array</span><span class="op">&lt;</span><span class="dt">number</span><span class="op">&gt;</span> <span class="op">=</span> []</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isNonEmptyArray</span>(arr1)) {</span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;head(arr1):&#39;</span><span class="op">,</span> <span class="fu">head</span>(arr1))</span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;last(arr1):&#39;</span><span class="op">,</span> <span class="fu">last</span>(arr1))</span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isNonEmptyArray</span>(arrEmpty)) {</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a>  <span class="co">// None of this will run.</span></span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;head(arrEmpty):&#39;</span><span class="op">,</span> <span class="fu">head</span>(arrEmpty))</span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;last(arrEmpty):&#39;</span><span class="op">,</span> <span class="fu">last</span>(arrEmpty))</span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 id="validwardrobe">ValidWardrobe<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></h2>
<p>I like this example because it shows how far you can stretch the predicate function. Which, it turns out, is as far as you want! As long as it returns a boolean in the end, you’re good.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Colour <span class="op">=</span> <span class="st">&#39;white&#39;</span> <span class="op">|</span> <span class="st">&#39;cream&#39;</span> <span class="op">|</span> <span class="st">&#39;blue&#39;</span> <span class="op">|</span> <span class="st">&#39;navy&#39;</span> <span class="co">// ...</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Wardrobe <span class="op">=</span> {</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  owner<span class="op">:</span> {</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    name<span class="op">:</span> <span class="dt">string</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    age<span class="op">:</span> <span class="dt">number</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>  tops<span class="op">:</span> Colour[]</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>  pants<span class="op">:</span> Colour[]</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  shorts<span class="op">:</span> Colour[]</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>  skirts<span class="op">:</span> Colour[]</span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>  desiredNumberOfOutfits<span class="op">:</span> <span class="dt">number</span></span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ValidWardrobe <span class="op">=</span> Wardrobe <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isValidWardrobe <span class="op">=</span> (wardrobe<span class="op">:</span> Wardrobe)<span class="op">:</span> wardrobe <span class="kw">is</span> ValidWardrobe <span class="kw">=&gt;</span> {</span>
<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> numOutfits<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span></span>
<span id="cb14-19"><a href="#cb14-19" aria-hidden="true" tabindex="-1"></a>    wardrobe<span class="op">.</span><span class="at">tops</span><span class="op">.</span><span class="at">length</span> <span class="op">*</span> wardrobe<span class="op">.</span><span class="at">pants</span><span class="op">.</span><span class="at">length</span></span>
<span id="cb14-20"><a href="#cb14-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">+</span> wardrobe<span class="op">.</span><span class="at">tops</span><span class="op">.</span><span class="at">length</span> <span class="op">*</span> wardrobe<span class="op">.</span><span class="at">shorts</span><span class="op">.</span><span class="at">length</span></span>
<span id="cb14-21"><a href="#cb14-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">+</span> wardrobe<span class="op">.</span><span class="at">tops</span><span class="op">.</span><span class="at">length</span> <span class="op">*</span> wardrobe<span class="op">.</span><span class="at">skirts</span><span class="op">.</span><span class="at">length</span></span>
<span id="cb14-22"><a href="#cb14-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-23"><a href="#cb14-23" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> numOutfits <span class="op">&gt;=</span> wardrobe<span class="op">.</span><span class="at">desiredNumberOfOutfits</span></span>
<span id="cb14-24"><a href="#cb14-24" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb14-25"><a href="#cb14-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-26"><a href="#cb14-26" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> suggestOutfits <span class="op">=</span> (wardrobe<span class="op">:</span> ValidWardrobe)<span class="op">:</span> <span class="dt">void</span> <span class="kw">=&gt;</span> {</span>
<span id="cb14-27"><a href="#cb14-27" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Printing suggested outfits for </span><span class="sc">${</span>wardrobe<span class="op">.</span><span class="at">owner</span><span class="op">.</span><span class="at">name</span><span class="sc">}</span><span class="vs">...`</span>)</span>
<span id="cb14-28"><a href="#cb14-28" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Do stuff here, knowing that wardrobe has already been validated.</span></span>
<span id="cb14-29"><a href="#cb14-29" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb14-30"><a href="#cb14-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-31"><a href="#cb14-31" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> ex1<span class="op">:</span> Wardrobe <span class="op">=</span> {</span>
<span id="cb14-32"><a href="#cb14-32" aria-hidden="true" tabindex="-1"></a>  owner<span class="op">:</span> {</span>
<span id="cb14-33"><a href="#cb14-33" aria-hidden="true" tabindex="-1"></a>    name<span class="op">:</span> <span class="st">&#39;Alice&#39;</span><span class="op">,</span></span>
<span id="cb14-34"><a href="#cb14-34" aria-hidden="true" tabindex="-1"></a>    age<span class="op">:</span> <span class="dv">22</span></span>
<span id="cb14-35"><a href="#cb14-35" aria-hidden="true" tabindex="-1"></a>  }<span class="op">,</span></span>
<span id="cb14-36"><a href="#cb14-36" aria-hidden="true" tabindex="-1"></a>  tops<span class="op">:</span> [<span class="st">&#39;blue&#39;</span><span class="op">,</span> <span class="st">&#39;white&#39;</span><span class="op">,</span> <span class="st">&#39;cream&#39;</span>]<span class="op">,</span></span>
<span id="cb14-37"><a href="#cb14-37" aria-hidden="true" tabindex="-1"></a>  pants<span class="op">:</span> [<span class="st">&#39;navy&#39;</span><span class="op">,</span> <span class="st">&#39;blue&#39;</span>]<span class="op">,</span></span>
<span id="cb14-38"><a href="#cb14-38" aria-hidden="true" tabindex="-1"></a>  shorts<span class="op">:</span> [<span class="st">&#39;navy&#39;</span>]<span class="op">,</span></span>
<span id="cb14-39"><a href="#cb14-39" aria-hidden="true" tabindex="-1"></a>  skirts<span class="op">:</span> [<span class="st">&#39;navy&#39;</span><span class="op">,</span> <span class="st">&#39;blue&#39;</span>]<span class="op">,</span></span>
<span id="cb14-40"><a href="#cb14-40" aria-hidden="true" tabindex="-1"></a>  desiredNumberOfOutfits<span class="op">:</span> <span class="dv">15</span></span>
<span id="cb14-41"><a href="#cb14-41" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb14-42"><a href="#cb14-42" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="fu">isValidWardrobe</span>(ex1)) {</span>
<span id="cb14-43"><a href="#cb14-43" aria-hidden="true" tabindex="-1"></a>  <span class="fu">suggestOutfits</span>(ex1)</span>
<span id="cb14-44"><a href="#cb14-44" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 id="validated-form-input">Validated Form Input</h2>
<p>Let’s say you have some input from a user registration form. And you have a <code>register</code> function whose job is to save this user data somewhere. Rather than clouding the concerns of <code>register</code> by validating the user data within the function, you can have it only accept data that has been previously validated!</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ValidName <span class="op">=</span> <span class="dt">string</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isValidName <span class="op">=</span> (name<span class="op">:</span> <span class="dt">string</span>)<span class="op">:</span> name <span class="kw">is</span> ValidName <span class="kw">=&gt;</span> name<span class="op">.</span><span class="fu">trim</span>()<span class="op">.</span><span class="at">length</span> <span class="op">&gt;</span> <span class="dv">0</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ValidBirthYear <span class="op">=</span> <span class="dt">number</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isValidBirthYear <span class="op">=</span> (year<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> year <span class="kw">is</span> ValidBirthYear <span class="kw">=&gt;</span> {</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> thisYear<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="kw">new</span> <span class="bu">Date</span>()<span class="op">.</span><span class="fu">getFullYear</span>()</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> year <span class="op">&gt;=</span> <span class="dv">1900</span> <span class="op">&amp;&amp;</span> year <span class="op">&lt;=</span> thisYear</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> register <span class="op">=</span> (name<span class="op">:</span> ValidName<span class="op">,</span> birthYear<span class="op">:</span> ValidBirthYear)<span class="op">:</span> <span class="dt">void</span> <span class="kw">=&gt;</span> {</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Registering user with name &quot;</span><span class="sc">${</span>name<span class="sc">}</span><span class="vs">&quot; born in </span><span class="sc">${</span>birthYear<span class="sc">}</span><span class="vs">`</span>)</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> nameInput<span class="op">:</span> <span class="dt">string</span> <span class="op">=</span> <span class="st">&#39;test&#39;</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> birthYearInput<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="dv">1800</span></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> (<span class="op">!</span><span class="fu">isValidName</span>(nameInput)) {</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;Name cannot be empty&#39;</span>)</span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a>} <span class="cf">else</span> <span class="cf">if</span> (<span class="op">!</span><span class="fu">isValidBirthYear</span>(birthYearInput)) {</span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;Invalid birth year&#39;</span>)</span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a>} <span class="cf">else</span> {</span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a>  <span class="fu">register</span>(nameInput<span class="op">,</span> birthYearInput)</span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h2 id="positiveinteger-nonemptystring">PositiveInteger, NonEmptyString</h2>
<p>You can nest subtypes in other types, too.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> PositiveInteger <span class="op">=</span> <span class="dt">number</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isPositiveInteger <span class="op">=</span> (x<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> x <span class="kw">is</span> PositiveInteger <span class="kw">=&gt;</span> {</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> x <span class="op">&gt;=</span> <span class="dv">1</span> <span class="op">&amp;&amp;</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">floor</span>(x) <span class="op">===</span> x</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> NonEmptyString <span class="op">=</span> <span class="dt">string</span> <span class="op">&amp;</span> { <span class="kw">readonly</span> __type<span class="op">:</span> unique <span class="dt">symbol</span> }</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isNonEmptyString <span class="op">=</span> (s<span class="op">:</span> <span class="dt">string</span>)<span class="op">:</span> s <span class="kw">is</span> NonEmptyString <span class="kw">=&gt;</span> {</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> s<span class="op">.</span><span class="fu">trim</span>()<span class="op">.</span><span class="at">length</span> <span class="op">&gt;</span> <span class="dv">0</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Product <span class="op">=</span> {</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>  name<span class="op">:</span> NonEmptyString</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>  description<span class="op">:</span> <span class="dt">string</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>  priceCents<span class="op">:</span> PositiveInteger</span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Cart <span class="op">=</span> {} <span class="co">// Use your imagination</span></span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> addToCart <span class="op">=</span> (product<span class="op">:</span> Product<span class="op">,</span> quantity<span class="op">:</span> PositiveInteger<span class="op">,</span> cart<span class="op">:</span> Cart)<span class="op">:</span> Cart <span class="kw">=&gt;</span> {</span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Add a product to the cart, not having to worry about the quantity being a negative number or 0.</span></span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> cart</span>
<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h1 id="footnotes">Footnotes</h1>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>TypeScript intersections between primitives and objects are enabled to allow for making “branded primitives”, which is intended to allow for nominal typing. See <a href="https://github.com/microsoft/TypeScript/wiki/FAQ#can-i-make-a-type-alias-nominal">TypeScript FAQ</a>. With subtypes, we’re leveraging that feature for an entirely different purpose.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Without using type assertions, which would bypass the type checker altogether.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>Based off of my partner’s <a href="https://github.com/Lzduque/personal-stylist">Personal Stylist</a> app.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Wed, 06 Dec 2023 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/typescripts-hidden-feature-subtypes.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>The Dangers of Learning to Code With Training Wheels</title>
    <link>https://timjohns.ca/the-dangers-of-learning-to-code-with-training-wheels.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        The Dangers of Learning to Code With Training Wheels
      </h1>
      <p class="writing">Oct 14, 2023</p>
      
    </header>
	<img class="post-image" alt="A drawing of a laptop combined with a bicycle." src="./images/blog/training_wheels.jpg" />
    <section class="content writing">
	  <p>Did you know it’s not recommended to learn how to ride a bicycle using training wheels anymore?<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> It’s true!<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> What people found is that using training wheels don’t enable the rider to learn the crucial skill of balancing on a bicycle. So, while training wheels do lower the stakes when falling, they also remove the activity’s essential components.</p>
<p>As a teacher, I’ve noticed the same sort of problem can come up with people learning to code. The problem is, if you learn with “training wheels” on, at some point you have to take them off. And that can be a rough transition. And, if you don’t know you’re using training wheels in your learning, you may not even know what skills you’re missing out on.</p>
<p>What do I mean by “training wheels” in learning to code? Well, they can come in different forms:</p>
<ul>
<li><strong>Online editors</strong></li>
<li><strong>Custom libraries, frameworks, or languages designed for teaching</strong></li>
<li><strong>Code-along video tutorials</strong></li>
</ul>
<p>For example, the ever-popular site <a href="https://www.freecodecamp.org">freeCodeCamp</a> provides coding lessons paired with a custom-built <strong>online editor</strong>. That means you’re typing code in a <strong>sandbox environment</strong>. If you make a mistake in your code, you’re given a kind of error message that’s different from anything a professional developer would see. You’re also not able to <strong>experiment</strong> and try things that you would be able to do if you simply ran your code on your own computer, which is a huge part of being a programmer! Now, I’m not saying freeCodeCamp is bad, but you should be aware that this is a very different environment than any practicing developer uses. On freeCodeCamp, you’re having your hand held so tightly that you can’t find your balance on your own.</p>
<p>What I find is, by the end of a student taking a course with a sandbox environment, they’re lost as to how to code on their own computer. They don’t know how to <strong>set up a project</strong>, how to <strong>debug</strong> their code when things go wrong, or how to <strong>share</strong> their finished app with other people. These are all essential skills for any developer.</p>
<p>The story is similar when a student learns to code using a <strong>custom library, framework, or language</strong>. After they’re finished the course, they don’t know where the course’s <strong>custom material ends</strong> and the stuff they can use in the <strong>real world begins</strong>. With frustration, they ask themselves, “How do I make an app <em>without</em> using the course tools?”</p>
<p>When it comes to <strong>code-along video tutorials</strong>, you’re not free to <strong>make your own mistakes</strong>. So you never really get a sense of what to do when things go wrong. Believe me, in programming, things go wrong <em>all the time</em>. That’s part of the fun! Figuring out what went wrong and <em>why</em> it’s happening, then solving the problem is one of the <em>biggest</em> and <em>best</em> parts of programming. If you’re just copying down someone else’s thoughts, you’re not learning how to think on your own.</p>
<p>Now, I’m not saying this to discourage readers from using certain resources. I just think you should be aware of <strong>when</strong> you’re using training wheels and whether there may be a <strong>better option</strong>.</p>
<p>When I wrote <a href="https://intuitivejs.info/">Intuitive JavaScript</a>, I purposefully left the exercises as plain *.js files to encourage the student to save the code and run their solutions on their own computer. This is closer to how a professional developer works. Getting used to the tools of the industry, like <a href="https://code.visualstudio.com/">Visual Studio Code</a> and <a href="https://nodejs.org/en">Node.js</a>, is essential for anyone who wants to become a working developer, and probably easier than you think!</p>
<h1 id="footnotes">Footnotes</h1>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://www.twowheelingtots.com/training-wheels-faq/">https://www.twowheelingtots.com/training-wheels-faq/</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p><a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8834827/">https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8834827/</a><a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Sat, 14 Oct 2023 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/the-dangers-of-learning-to-code-with-training-wheels.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>Implementing a Genetic Algorithm in TypeScript</title>
    <link>https://timjohns.ca/implementing-a-genetic-algorithm-in-typescript.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        Implementing a Genetic Algorithm in TypeScript
      </h1>
      <p class="writing">Aug 11, 2023</p>
      
    </header>
	<img class="post-image" alt="A brain with a DNA strand overlaid in the middle." src="./images/blog/genetic_algorithm_typescript.jpg" />
    <section class="content writing">
	  <hr />
<h1 id="overview">Overview</h1>
<p>In my <a href="file:///build-your-own-genetic-algorithm.html#implementing-step-1-planning">previous post</a>, I described how to build a genetic algorithm in any programming language. Here, I want to give an example of a complete implementation in TypeScript. This is a brain dump style of post—just something to give you an idea of how I approach solving this problem. I have to admit, it’s not entirely accurate because I’m not including all the mistakes and backtracking along the way. Since this is a written post, and not a video, it makes it seem like my process is linear when it really isn’t. I would normally create functions with gaps to be filled, going back and forth between them a lot.</p>
<p>Also important to note is that standard JavaScript/TypeScript is lacking in basic utility functions, so I will be making references to useful generic functions that I put in a separate module (<a href="https://github.com/SlimTim10/genetic-algorithm-math-string/blob/main/typescript/src/util.ts">util.ts</a>).</p>
<p>If you want to skip this post and just see the code (with comments), here’s a link to the repo:</p>
<p><a href="https://github.com/SlimTim10/genetic-algorithm-math-string">https://github.com/SlimTim10/genetic-algorithm-math-string</a></p>
<h1 id="problem">Problem</h1>
<p>Given a target number, find a string of single-digit numbers and basic arithmetic operators that equals that number. For example, if the target number is 10, some solutions would be:</p>
<ul>
<li><code>5 + 5</code></li>
<li><code>5 * 2</code></li>
<li><code>5 + 5 + 1 - 1 - 5 - 5 + 1 + 9 * 1 / 1</code></li>
</ul>
<p>The strings will be evaluated using the standard order of operations. So, <code>2 + 2 * 3 = 8</code>.</p>
<h1 id="implementation">Implementation</h1>
<p><em>See my <a href="file:///build-your-own-genetic-algorithm.html#implementing-step-1-planning">previous post</a> for a detailed plan that serves as the basis for this implementation.</em></p>
<h2 id="implementing-step-1-planning">Implementing Step 1. Planning</h2>
<p>I like to start by planning the essential pieces in terms of types.</p>
<p>Going from big to small…</p>
<p>An organism is made up of one chromosome and has a fitness number.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Organism <span class="op">=</span> {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  chromosome<span class="op">:</span> Chromosome<span class="op">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  fitness<span class="op">:</span> <span class="dt">number</span><span class="op">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>A chromosome is a collection of genes, so I’m going to make it an array. I could define it as a tuple of genes if I wanted to hard-code the length of each chromosome, but I want their length to be variable so I can tweak it on different runs of the algorithm.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Chromosome <span class="op">=</span> Gene[]<span class="op">;</span></span></code></pre></div>
<p>A gene is a container for information. For my implementation, I’ve decided that every gene can either be a number gene or an operator gene. So I’m going to use a union type.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Gene <span class="op">=</span> NumberGene <span class="op">|</span> OperatorGene<span class="op">;</span></span></code></pre></div>
<p>For the number genes, I can use four bits to represent any single-digit number (0 through 9), with a few junk alleles left over.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> NumberGene <span class="op">=</span> [Bit<span class="op">,</span> Bit<span class="op">,</span> Bit<span class="op">,</span> Bit]<span class="op">;</span></span></code></pre></div>
<div class="table-container">

<table>
<thead>
<tr class="header">
<th>allele</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>0000</code></td>
<td><code>0</code></td>
</tr>
<tr class="even">
<td><code>0001</code></td>
<td><code>1</code></td>
</tr>
<tr class="odd">
<td><code>0010</code></td>
<td><code>2</code></td>
</tr>
<tr class="even">
<td><code>0011</code></td>
<td><code>3</code></td>
</tr>
<tr class="odd">
<td><code>0100</code></td>
<td><code>4</code></td>
</tr>
<tr class="even">
<td><code>0101</code></td>
<td><code>5</code></td>
</tr>
<tr class="odd">
<td><code>0110</code></td>
<td><code>6</code></td>
</tr>
<tr class="even">
<td><code>0111</code></td>
<td><code>7</code></td>
</tr>
<tr class="odd">
<td><code>1000</code></td>
<td><code>8</code></td>
</tr>
<tr class="even">
<td><code>1001</code></td>
<td><code>9</code></td>
</tr>
<tr class="odd">
<td><code>1010</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="even">
<td><code>1011</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="odd">
<td><code>1100</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="even">
<td><code>1101</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="odd">
<td><code>1110</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="even">
<td><code>1111</code></td>
<td><code>(junk)</code></td>
</tr>
</tbody>
</table>
</div>

<p>For the four basic math operators (+, -, *, /), I only need two bits.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> OperatorGene <span class="op">=</span> [Bit<span class="op">,</span> Bit]<span class="op">;</span></span></code></pre></div>
<p>A bit, of course, is either 1 or 0.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Bit <span class="op">=</span> <span class="dv">0</span> <span class="op">|</span> <span class="dv">1</span><span class="op">;</span></span></code></pre></div>
<p>I’m going to encode all the possible number alleles for the digits 0 through 9. This way, for any gene I’m working with, I can check what its allele represents.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> numberAlleles<span class="op">:</span> NumberGene[] <span class="op">=</span> [</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="co">// 0</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">,</span> <span class="co">// 1</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="co">// 2</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">,</span> <span class="co">// 3</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="co">// 4</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">,</span> <span class="co">// 5</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="co">// 6</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">,</span> <span class="co">// 7</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="co">// 8</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">,</span> <span class="co">// 9</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>]<span class="op">;</span></span></code></pre></div>
<p>And the same for operators.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> operatorAlleles<span class="op">:</span> OperatorGene[] <span class="op">=</span> [</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="co">// +</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">,</span> <span class="co">// -</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="co">// *</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  [<span class="dv">1</span><span class="op">,</span> <span class="dv">1</span>]<span class="op">,</span> <span class="co">// /</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>]<span class="op">;</span></span></code></pre></div>
<p>Now I can make a function to convert any gene to its corresponding value. For this, I’ll collect all the possible values with a union type and make a function that takes a gene and returns its represented value.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> Value</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">=</span> <span class="st">&quot;0&quot;</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;1&quot;</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;2&quot;</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;3&quot;</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;4&quot;</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;5&quot;</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;6&quot;</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;7&quot;</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;8&quot;</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;9&quot;</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;+&quot;</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;-&quot;</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;*&quot;</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;/&quot;</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="st">&quot;(junk)&quot;</span><span class="op">;</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a><span class="co">// Predicate for number genes.</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isNumber <span class="op">=</span> (gene<span class="op">:</span> Gene)<span class="op">:</span> gene <span class="kw">is</span> NumberGene <span class="kw">=&gt;</span> {</span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> numberAlleles<span class="op">.</span><span class="fu">some</span>((x<span class="op">:</span> NumberGene) <span class="kw">=&gt;</span> <span class="fu">eqArrays</span>(x<span class="op">,</span> gene))<span class="op">;</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a><span class="co">// Predicate for operator genes.</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isOperator <span class="op">=</span> (gene<span class="op">:</span> Gene)<span class="op">:</span> gene <span class="kw">is</span> OperatorGene <span class="kw">=&gt;</span> {</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> operatorAlleles<span class="op">.</span><span class="fu">some</span>((x<span class="op">:</span> OperatorGene) <span class="kw">=&gt;</span> <span class="fu">eqArrays</span>(x<span class="op">,</span> gene))<span class="op">;</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a><span class="co">// Take a gene and return its represented value.</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> geneValue <span class="op">=</span> (gene<span class="op">:</span> Gene)<span class="op">:</span> Value <span class="kw">=&gt;</span> {</span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Numbers</span></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (<span class="fu">isNumber</span>(gene)) {</span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>])) <span class="cf">return</span> <span class="st">&quot;0&quot;</span><span class="op">;</span></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>])) <span class="cf">return</span> <span class="st">&quot;1&quot;</span><span class="op">;</span></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span>])) <span class="cf">return</span> <span class="st">&quot;2&quot;</span><span class="op">;</span></span>
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span>])) <span class="cf">return</span> <span class="st">&quot;3&quot;</span><span class="op">;</span></span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>])) <span class="cf">return</span> <span class="st">&quot;4&quot;</span><span class="op">;</span></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>])) <span class="cf">return</span> <span class="st">&quot;5&quot;</span><span class="op">;</span></span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">0</span>])) <span class="cf">return</span> <span class="st">&quot;6&quot;</span><span class="op">;</span></span>
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">1</span>])) <span class="cf">return</span> <span class="st">&quot;7&quot;</span><span class="op">;</span></span>
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>])) <span class="cf">return</span> <span class="st">&quot;8&quot;</span><span class="op">;</span></span>
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>])) <span class="cf">return</span> <span class="st">&quot;9&quot;</span><span class="op">;</span></span>
<span id="cb9-42"><a href="#cb9-42" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb9-43"><a href="#cb9-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Operators</span></span>
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (<span class="fu">isOperator</span>(gene)) {</span>
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>])) <span class="cf">return</span> <span class="st">&quot;+&quot;</span><span class="op">;</span></span>
<span id="cb9-47"><a href="#cb9-47" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">0</span><span class="op">,</span> <span class="dv">1</span>])) <span class="cf">return</span> <span class="st">&quot;-&quot;</span><span class="op">;</span></span>
<span id="cb9-48"><a href="#cb9-48" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">0</span>])) <span class="cf">return</span> <span class="st">&quot;*&quot;</span><span class="op">;</span></span>
<span id="cb9-49"><a href="#cb9-49" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">eqArrays</span>(gene<span class="op">,</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">1</span>])) <span class="cf">return</span> <span class="st">&quot;/&quot;</span><span class="op">;</span></span>
<span id="cb9-50"><a href="#cb9-50" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb9-51"><a href="#cb9-51" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-52"><a href="#cb9-52" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Any other value is junk</span></span>
<span id="cb9-53"><a href="#cb9-53" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="st">&quot;(junk)&quot;</span><span class="op">;</span></span>
<span id="cb9-54"><a href="#cb9-54" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>And now I have all the pieces needed to get an organism’s phenotype. With a function that takes in an organism, I can convert each gene to its value and join them into a space-separated string.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> phenotype <span class="op">=</span> (organism<span class="op">:</span> Organism)<span class="op">:</span> <span class="dt">string</span> <span class="kw">=&gt;</span> {</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> organism<span class="op">.</span><span class="at">chromosome</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">map</span>(geneValue)</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">join</span>(<span class="st">&quot; &quot;</span>)<span class="op">;</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>Since a phenotype can contain junk, I also want a way to get an organism’s cleaned-up phenotype, which will be safe to evaluate. That means I first need a way to clean the genes of a chromosome, in accordance with the <a href="file:///build-your-own-genetic-algorithm.html#implementing-step-1-planning">plan</a>: remove any junk genes along with their immediately preceeding gene.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> cleanChromosome <span class="op">=</span> (chromosome<span class="op">:</span> Chromosome)<span class="op">:</span> Chromosome <span class="kw">=&gt;</span> {</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Add a &quot;plus&quot; gene to the beginning so I can deal with pairs safely.</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> genes<span class="op">:</span> Gene[] <span class="op">=</span> [ [<span class="dv">0</span><span class="op">,</span> <span class="dv">0</span>]<span class="op">,</span> <span class="op">...</span>chromosome]<span class="op">;</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> pairs <span class="op">=</span> <span class="fu">chunksOf</span>(<span class="dv">2</span><span class="op">,</span> genes)<span class="op">;</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> pairs</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">filter</span>(pair <span class="kw">=&gt;</span> pair<span class="op">.</span><span class="at">length</span> <span class="op">===</span> <span class="dv">2</span>)</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">filter</span>(([_<span class="op">,</span> num]) <span class="kw">=&gt;</span> <span class="fu">geneValue</span>(num) <span class="op">!==</span> <span class="st">&quot;(junk)&quot;</span>)</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">reduce</span>((acc<span class="op">,</span> pair) <span class="kw">=&gt;</span> [<span class="op">...</span>acc<span class="op">,</span> <span class="op">...</span>pair]<span class="op">,</span> [])</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)<span class="op">;</span> <span class="co">// Remove the initial &quot;plus&quot; gene.</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>And now, I can easily apply the chromosome cleaning operation to an organism as a whole.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> cleanPhenotype <span class="op">=</span> (organism<span class="op">:</span> Organism)<span class="op">:</span> <span class="dt">string</span> <span class="kw">=&gt;</span> {</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="fu">phenotype</span>({</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">...</span>organism<span class="op">,</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    chromosome<span class="op">:</span> <span class="fu">cleanChromosome</span>(organism<span class="op">.</span><span class="at">chromosome</span>)</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  })<span class="op">;</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>To evaluate the phenotype of an organism as a math string, I’m going to take the easy route and use the built-in eval function, with the assumption that the string is already cleaned. But I need to be careful here! For one, I need to be aware that using this evaluation method means the standard order of operations is being applied. That’s what I want, so that’s fine. But also, it’s possible for the result to be <code>NaN</code> or <code>Infinity</code> if a division by 0 happens. I’ll have to remember to handle these special cases when doing fitness evaluation.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> evaluateMath <span class="op">=</span> (mathStr<span class="op">:</span> <span class="dt">string</span>)<span class="op">:</span> <span class="dt">number</span> <span class="kw">=&gt;</span> <span class="bu">Number</span>(<span class="pp">eval</span>(mathStr))<span class="op">;</span></span></code></pre></div>
<p>Now to evaluate the fitness of an organism. This part is a bit tricky because I want organisms to have their fitness stored as part of their data. If an organism is a chromosome along with fitness, I can’t have my fitness evaluating function take in an organism. I need to deal with chromosomes directly. The resulting fitness score will be a number between 0 and 1, with 1 being perfect fitness. I can combine a chromosome and its fitness score into an organism somewhere else.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> evaluateFitness <span class="op">=</span> (chromosome<span class="op">:</span> Chromosome<span class="op">,</span> target<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> <span class="dt">number</span> <span class="kw">=&gt;</span> {</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> mathStr <span class="op">=</span> <span class="fu">cleanChromosome</span>(chromosome)</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">map</span>(geneValue)</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">join</span>(<span class="st">&quot; &quot;</span>)<span class="op">;</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> n <span class="op">=</span> <span class="fu">evaluateMath</span>(mathStr)<span class="op">;</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (<span class="pp">isNaN</span>(n) <span class="op">||</span> n <span class="op">===</span> <span class="kw">Infinity</span>) {</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// This is as far from the target number as it can be, so let&#39;s just say the fitness is 0.</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  } <span class="cf">else</span> {</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">1</span> <span class="op">/</span> (<span class="bu">Math</span><span class="op">.</span><span class="fu">abs</span>(target <span class="op">-</span> n) <span class="op">+</span> <span class="dv">1</span>)<span class="op">;</span></span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<h2 id="implementing-step-2-setting-parameters">Implementing Step 2. Setting parameters</h2>
<p>For running the algorithm, I’m going to make a main function with the tweakable parameters. For this specific application, I need a couple extra parameters: the chromosome length for each organism and the target number.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> runAlgorithm <span class="op">=</span> (</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  populationSize<span class="op">:</span> <span class="dt">number</span><span class="op">,</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  crossoverRate<span class="op">:</span> <span class="dt">number</span><span class="op">,</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  mutationRate<span class="op">:</span> <span class="dt">number</span><span class="op">,</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  generationLimit<span class="op">:</span> <span class="dt">number</span><span class="op">,</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  chromosomeLength<span class="op">:</span> <span class="dt">number</span><span class="op">,</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>  target<span class="op">:</span> <span class="dt">number</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>)<span class="op">:</span> <span class="dt">void</span> <span class="kw">=&gt;</span> {</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">...</span></span></code></pre></div>
<p>From here on, writing the code is not linear. I’m going to fill in the steps of the algorithm as needed.</p>
<h2 id="implementing-step-3-create-initial-population">Implementing Step 3. Create initial population</h2>
<p>Since fitness evaluation is to be done in batch, I’m going to make a population of chromosomes instead of organisms.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside runAlgorithm()</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> initialChromPopulation<span class="op">:</span> Chromosome[] <span class="op">=</span> <span class="fu">buildArray</span>(populationSize)</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">map</span>(_ <span class="kw">=&gt;</span> <span class="fu">randomChromosome</span>(chromosomeLength))<span class="op">;</span></span></code></pre></div>
<p>And the helpers to create random chromosomes can go outside the main function…</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Create a randomized chromosome of a desired length.</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> randomChromosome <span class="op">=</span> (length<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> Chromosome <span class="kw">=&gt;</span> {</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> numberGenes<span class="op">:</span> Gene[] <span class="op">=</span> <span class="fu">buildArray</span>(<span class="bu">Math</span><span class="op">.</span><span class="fu">floor</span>(length <span class="op">/</span> <span class="dv">2</span>))</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">map</span>(_ <span class="kw">=&gt;</span> <span class="fu">randomGene</span>(<span class="st">&quot;number&quot;</span>))<span class="op">;</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> operatorGenes<span class="op">:</span> Gene[] <span class="op">=</span> <span class="fu">buildArray</span>(<span class="bu">Math</span><span class="op">.</span><span class="fu">floor</span>(length <span class="op">/</span> <span class="dv">2</span> <span class="op">-</span> <span class="dv">1</span>))</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">map</span>(_ <span class="kw">=&gt;</span> <span class="fu">randomGene</span>(<span class="st">&quot;operator&quot;</span>))<span class="op">;</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="fu">zip</span>(numberGenes<span class="op">,</span> operatorGenes)</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">flat</span>()</span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">concat</span>([<span class="fu">last</span>(numberGenes)])<span class="op">;</span></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> NumberOrOperator <span class="op">=</span> <span class="st">&quot;number&quot;</span> <span class="op">|</span> <span class="st">&quot;operator&quot;</span><span class="op">;</span></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a><span class="co">// Create a randomized number or operator gene.</span></span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> randomGene <span class="op">=</span> (numberOrOperator<span class="op">:</span> NumberOrOperator)<span class="op">:</span> Gene <span class="kw">=&gt;</span> {</span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a>  <span class="cf">switch</span> (numberOrOperator) {</span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="st">&quot;number&quot;</span><span class="op">:</span></span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [<span class="fu">randomBit</span>()<span class="op">,</span> <span class="fu">randomBit</span>()<span class="op">,</span> <span class="fu">randomBit</span>()<span class="op">,</span> <span class="fu">randomBit</span>()]<span class="op">;</span></span>
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="st">&quot;operator&quot;</span><span class="op">:</span></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [<span class="fu">randomBit</span>()<span class="op">,</span> <span class="fu">randomBit</span>()]<span class="op">;</span></span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb17-22"><a href="#cb17-22" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span>
<span id="cb17-23"><a href="#cb17-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-24"><a href="#cb17-24" aria-hidden="true" tabindex="-1"></a><span class="co">// Generate a random bit (0 or 1).</span></span>
<span id="cb17-25"><a href="#cb17-25" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> randomBit <span class="op">=</span> ()<span class="op">:</span> Bit <span class="kw">=&gt;</span> (<span class="bu">Math</span><span class="op">.</span><span class="fu">random</span>() <span class="op">&lt;</span> <span class="fl">0.5</span>) <span class="op">?</span> <span class="dv">0</span> <span class="op">:</span> <span class="dv">1</span><span class="op">;</span></span></code></pre></div>
<h2 id="the-main-loop">The main loop</h2>
<p>Now I’m going to set up the main loop as a recursive function. This will consist of Steps 4 through 8; fitness evaluation, selection, crossover, mutation, and replacing the population. Each iteration will produce a new generation.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside runAlgorithm()</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> generationalStep <span class="op">=</span> (chromPopulation<span class="op">:</span> Chromosome[]<span class="op">,</span> generation<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> Chromosome[] <span class="kw">=&gt;</span> {</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Check for the stopping condition.</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (generation <span class="op">&gt;=</span> generationLimit) {</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> chromPopulation<span class="op">;</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">...</span></span></code></pre></div>
<h2 id="implementing-step-4-fitness-evaluation">Implementing Step 4. Fitness evaluation</h2>
<p>Since I’ve already made the fitness evaluation function, here I simply need to apply it to the entire population of chromosomes, turning it into a population of organisms.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside generationalStep()</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> population<span class="op">:</span> Organism[] <span class="op">=</span> chromPopulation<span class="op">.</span><span class="fu">map</span>(chromosome <span class="kw">=&gt;</span> ({</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  chromosome<span class="op">,</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>  fitness<span class="op">:</span> <span class="fu">evaluateFitness</span>(chromosome<span class="op">,</span> target)</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>}))<span class="op">;</span></span></code></pre></div>
<h2 id="implementing-step-5-selection">Implementing Step 5. Selection</h2>
<p>This is the first step in the reproduction process. I need to select two organisms from the population using the <a href="file:///build-your-own-genetic-algorithm.html#step-5-selection">roulette wheel strategy</a>.</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside generationalStep()</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> reproduce <span class="op">=</span> ()<span class="op">:</span> [Chromosome<span class="op">,</span> Chromosome] <span class="kw">=&gt;</span> {</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> parent1 <span class="op">=</span> <span class="fu">rouletteWheelSelection</span>(population)<span class="op">;</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> parent2 <span class="op">=</span> <span class="fu">rouletteWheelSelection</span>(population)<span class="op">;</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">...</span></span></code></pre></div>
<p>And the roulette wheel selection function can live outside the main function.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Select an organism from a population using the roulette wheel strategy.</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> rouletteWheelSelection <span class="op">=</span> (population<span class="op">:</span> Organism[])<span class="op">:</span> Organism <span class="kw">=&gt;</span> {</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> fitnesses<span class="op">:</span> <span class="dt">number</span>[] <span class="op">=</span> population<span class="op">.</span><span class="fu">map</span>(({fitness}) <span class="kw">=&gt;</span> fitness)<span class="op">;</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> totalFitness<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="fu">sum</span>(fitnesses)<span class="op">;</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> cumulFitnesses<span class="op">:</span> <span class="dt">number</span>[] <span class="op">=</span> <span class="fu">scan</span>((x<span class="op">:</span> <span class="dt">number</span><span class="op">,</span> y<span class="op">:</span> <span class="dt">number</span>) <span class="kw">=&gt;</span> x <span class="op">+</span> y<span class="op">,</span> fitnesses[<span class="dv">0</span>]<span class="op">,</span> fitnesses)<span class="op">;</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> withCumulativeFitnesses<span class="op">:</span> [Organism<span class="op">,</span> <span class="dt">number</span>][] <span class="op">=</span> <span class="fu">zip</span>(population<span class="op">,</span> cumulFitnesses)<span class="op">;</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> r<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">random</span>() <span class="op">*</span> totalFitness<span class="op">;</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> found<span class="op">:</span> [Organism<span class="op">,</span> <span class="dt">number</span>] <span class="op">|</span> <span class="dt">undefined</span> <span class="op">=</span> withCumulativeFitnesses<span class="op">.</span><span class="fu">find</span>(([_<span class="op">,</span> cf]) <span class="kw">=&gt;</span> cf <span class="op">&gt;=</span> r)<span class="op">;</span></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (found <span class="op">===</span> <span class="kw">undefined</span>) {</span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// In case an organism is not found, return the last one.</span></span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> population[population<span class="op">.</span><span class="at">length</span> <span class="op">-</span> <span class="dv">1</span>]<span class="op">;</span></span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a>  } <span class="cf">else</span> {</span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> [organism<span class="op">,</span> _] <span class="op">=</span> found<span class="op">;</span></span>
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> organism<span class="op">;</span></span>
<span id="cb21-15"><a href="#cb21-15" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb21-16"><a href="#cb21-16" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<h2 id="implementing-step-6-crossover">Implementing Step 6. Crossover</h2>
<p>The next step for reproduction is crossing over the two previously selected organisms. At this point, I’m going to deal with chromosomes instead of organisms, since their fitnesses won’t be evaluated until later.</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside reproduce()</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> [chrom1<span class="op">,</span> chrom2] <span class="op">=</span> <span class="fu">crossover</span>(parent1<span class="op">.</span><span class="at">chromosome</span><span class="op">,</span> parent2<span class="op">.</span><span class="at">chromosome</span><span class="op">,</span> crossoverRate)<span class="op">;</span></span></code></pre></div>
<p>Again, I can write the crossover function outside the main function.</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Crossover (or clone) two chromosomes.</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> crossover <span class="op">=</span> (x<span class="op">:</span> Chromosome<span class="op">,</span> y<span class="op">:</span> Chromosome<span class="op">,</span> crossoverRate<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> [Chromosome<span class="op">,</span> Chromosome] <span class="kw">=&gt;</span> {</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> r<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">random</span>()<span class="op">;</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (r <span class="op">&lt;=</span> crossoverRate) {</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> position<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">floor</span>(<span class="bu">Math</span><span class="op">.</span><span class="fu">random</span>() <span class="op">*</span> x<span class="op">.</span><span class="at">length</span>)<span class="op">;</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> xNew <span class="op">=</span> [<span class="op">...</span>x<span class="op">.</span><span class="fu">slice</span>(<span class="dv">0</span><span class="op">,</span> position)<span class="op">,</span> <span class="op">...</span>y<span class="op">.</span><span class="fu">slice</span>(position)]<span class="op">;</span></span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> yNew <span class="op">=</span> [<span class="op">...</span>y<span class="op">.</span><span class="fu">slice</span>(<span class="dv">0</span><span class="op">,</span> position)<span class="op">,</span> <span class="op">...</span>x<span class="op">.</span><span class="fu">slice</span>(position)]<span class="op">;</span></span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> [xNew<span class="op">,</span> yNew]<span class="op">;</span></span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>  } <span class="cf">else</span> {</span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> [x<span class="op">,</span> y]<span class="op">;</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<h2 id="implementing-step-7-mutation">Implementing Step 7. Mutation</h2>
<p>And now for the last step for reproduction: mutating those two chromosomes. After being mutated, the chromosomes can be returned as the pair of produced offspring to end the function.</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside reproduce()</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> chrom1Mutated <span class="op">=</span> <span class="fu">mutate</span>(chrom1<span class="op">,</span> mutationRate)<span class="op">;</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> chrom2Mutated <span class="op">=</span> <span class="fu">mutate</span>(chrom2<span class="op">,</span> mutationRate)<span class="op">;</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> [chrom1Mutated<span class="op">,</span> chrom2Mutated]<span class="op">;</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a><span class="co">// This ends reproduce()</span></span></code></pre></div>
<p>Once more, the code for mutating can be outside the main function.</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Flip a bit from 0 to 1, or 1 to 0.</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> flipBit <span class="op">=</span> (bit<span class="op">:</span> Bit)<span class="op">:</span> Bit <span class="kw">=&gt;</span> bit <span class="op">===</span> <span class="dv">0</span> <span class="op">?</span> <span class="dv">1</span> <span class="op">:</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a><span class="co">// Mutate a chromosome.</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> mutate <span class="op">=</span> (chromosome<span class="op">:</span> Chromosome<span class="op">,</span> mutationRate<span class="op">:</span> <span class="dt">number</span>)<span class="op">:</span> Chromosome <span class="kw">=&gt;</span> {</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Mutate a bit.</span></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> mutateBit <span class="op">=</span> (bit<span class="op">:</span> Bit)<span class="op">:</span> Bit <span class="kw">=&gt;</span> {</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> r<span class="op">:</span> <span class="dt">number</span> <span class="op">=</span> <span class="bu">Math</span><span class="op">.</span><span class="fu">random</span>()<span class="op">;</span></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> r <span class="op">&lt;=</span> mutationRate</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>      <span class="op">?</span> <span class="fu">flipBit</span>(bit)</span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">:</span> bit<span class="op">;</span></span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>  }<span class="op">;</span></span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a>  <span class="co">// Mutate each gene.</span></span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> chromosome<span class="op">.</span><span class="fu">map</span>(gene <span class="kw">=&gt;</span> {</span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">isNumber</span>(gene)) {</span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> [a<span class="op">,</span> b<span class="op">,</span> c<span class="op">,</span> d] <span class="op">=</span> gene<span class="op">;</span></span>
<span id="cb25-18"><a href="#cb25-18" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [<span class="fu">mutateBit</span>(a)<span class="op">,</span> <span class="fu">mutateBit</span>(b)<span class="op">,</span> <span class="fu">mutateBit</span>(c)<span class="op">,</span> <span class="fu">mutateBit</span>(d)]<span class="op">;</span></span>
<span id="cb25-19"><a href="#cb25-19" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb25-20"><a href="#cb25-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-21"><a href="#cb25-21" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">isOperator</span>(gene)) {</span>
<span id="cb25-22"><a href="#cb25-22" aria-hidden="true" tabindex="-1"></a>      <span class="kw">const</span> [a<span class="op">,</span> b] <span class="op">=</span> gene<span class="op">;</span></span>
<span id="cb25-23"><a href="#cb25-23" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [<span class="fu">mutateBit</span>(a)<span class="op">,</span> <span class="fu">mutateBit</span>(b)]<span class="op">;</span></span>
<span id="cb25-24"><a href="#cb25-24" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb25-25"><a href="#cb25-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-26"><a href="#cb25-26" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> gene<span class="op">;</span></span>
<span id="cb25-27"><a href="#cb25-27" aria-hidden="true" tabindex="-1"></a>  })<span class="op">;</span></span>
<span id="cb25-28"><a href="#cb25-28" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<h2 id="implementing-step-8-replace-population">Implementing Step 8. Replace population</h2>
<p>That finishes the <code>reproduce()</code> function, but I’m not done with <code>generationalStep()</code> yet! I need to make use of the reproduction to make a new population of chromosomes, which will replace the old one.</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside generationalStep()</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> newChromPopulation<span class="op">:</span> Chromosome[] <span class="op">=</span> <span class="fu">buildArray</span>(<span class="bu">Math</span><span class="op">.</span><span class="fu">floor</span>(populationSize <span class="op">/</span> <span class="dv">2</span>))</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">map</span>(reproduce)</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">flat</span>()<span class="op">;</span></span></code></pre></div>
<h2 id="implementing-step-9-repeat-until-the-stopping-condition-is-met">Implementing Step 9. Repeat until the stopping condition is met</h2>
<p>To repeat the generation cycle, I can simply call <code>generationalStep()</code> recursively, passing in the new population and increasing the generation counter.</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside generationalStep()</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="fu">generationalStep</span>(newChromPopulation<span class="op">,</span> generation <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a><span class="co">// This ends generationalStep()</span></span></code></pre></div>
<h2 id="implementing-step-10-pick-the-winner">Implementing Step 10. Pick the winner</h2>
<p>Time for the last step! This is where I need to trigger the generational cycle to start, with the initial population of chromosomes, and let it run until the final population.</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside runAlgorithm()</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> finalChromPopulation<span class="op">:</span> Chromosome[] <span class="op">=</span> <span class="fu">generationalStep</span>(initialChromPopulation<span class="op">,</span> <span class="dv">0</span>)<span class="op">;</span></span></code></pre></div>
<p>Then evaluate the fitness of each chromosome so I have a population of organisms.</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside runAlgorithm()</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> finalPopulation<span class="op">:</span> Organism[] <span class="op">=</span> finalChromPopulation<span class="op">.</span><span class="fu">map</span>(chromosome <span class="kw">=&gt;</span> ({</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>  chromosome<span class="op">,</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>  fitness<span class="op">:</span> <span class="fu">evaluateFitness</span>(chromosome<span class="op">,</span> target)</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>}))<span class="op">;</span></span></code></pre></div>
<p>And finally, pick the chromosome with the best fitness!</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside runAlgorithm()</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> winner <span class="op">=</span> finalPopulation<span class="op">.</span><span class="fu">reduce</span>((best<span class="op">,</span> organism) <span class="kw">=&gt;</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>  (organism<span class="op">.</span><span class="at">fitness</span> <span class="op">&gt;</span> best<span class="op">.</span><span class="at">fitness</span>) <span class="op">?</span> organism <span class="op">:</span> best)<span class="op">;</span></span></code></pre></div>
<p>I want to print the winner’s information in detail so I can see if the algorithm is producing good results.</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Inside runAlgorithm()</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>()<span class="op">;</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`The winner is...`</span>)<span class="op">;</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Phenotype: </span><span class="sc">${</span><span class="fu">phenotype</span>(winner)<span class="sc">}</span><span class="vs">`</span>)<span class="op">;</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Clean phenotype: </span><span class="sc">${</span><span class="fu">cleanPhenotype</span>(winner)<span class="sc">}</span><span class="vs">`</span>)<span class="op">;</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Result: </span><span class="sc">${</span><span class="fu">evaluateMath</span>(<span class="fu">cleanPhenotype</span>(winner))<span class="sc">}</span><span class="vs">`</span>)<span class="op">;</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`Fitness: </span><span class="sc">${</span><span class="fu">evaluateFitness</span>(winner<span class="op">.</span><span class="at">chromosome</span><span class="op">,</span> target)<span class="sc">}</span><span class="vs">`</span>)<span class="op">;</span></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a><span class="co">// This ends runAlgorithm()</span></span></code></pre></div>
<h2 id="running-the-algorithm">Running the algorithm</h2>
<p>After playing with the parameters, I found that these values gave pretty consistently interesting results, and relatively fast.</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> populationSize <span class="op">=</span> <span class="dv">200</span><span class="op">;</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> crossoverRate <span class="op">=</span> <span class="fl">0.6</span><span class="op">;</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> mutationRate <span class="op">=</span> <span class="fl">0.05</span><span class="op">;</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> generationLimit <span class="op">=</span> <span class="dv">20</span><span class="op">;</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> chromosomeLength <span class="op">=</span> <span class="dv">20</span><span class="op">;</span></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> target <span class="op">=</span> <span class="dv">42</span><span class="op">;</span></span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a><span class="fu">runAlgorithm</span>(</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>  populationSize<span class="op">,</span></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>  crossoverRate<span class="op">,</span></span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>  mutationRate<span class="op">,</span></span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>  generationLimit<span class="op">,</span></span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>  chromosomeLength<span class="op">,</span></span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a>  target)<span class="op">;</span></span></code></pre></div>
<p>Try it out yourself! What happens when you change the values of the parameters? Can you make it accurate <em>and</em> fast?</p>
<p><a href="https://github.com/SlimTim10/genetic-algorithm-math-string">https://github.com/SlimTim10/genetic-algorithm-math-string</a></p>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Fri, 11 Aug 2023 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/implementing-a-genetic-algorithm-in-typescript.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>Build Your Own Genetic Algorithm</title>
    <link>https://timjohns.ca/build-your-own-genetic-algorithm.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        Build Your Own Genetic Algorithm
      </h1>
      <p class="writing">Jun  5, 2023</p>
      
    </header>
	<img class="post-image" alt="Digital drawing of DNA surrounded by binary code." src="./images/blog/genetic_algorithm.jpg" />
    <section class="content writing">
	  <hr />
<p><em>I’m extremely grateful to <a href="https://neckdeep.dev/">Danny Fekete</a> and his wife, Carolyn Piccinin, for their indispensable help with editing and vetting the bulk of this work for accuracy. And my partner, <a href="https://lzduque.github.io/">Leticia Duque</a>, for her patience in reviewing and her valuable insights.</em></p>
<hr />
<h1 id="overview">Overview</h1>
<p>Years ago, I stumbled upon <a href="http://www.ai-junkie.com/ga/intro/gat1.html">a tutorial</a> on genetic algorithms that ended up being one of the most interesting coding exercises I’ve ever done. I still think about it often to this day and I want to bring that same joy to others by providing my own explanation of the subject. This tutorial is meant to be approachable by anyone who knows at least one programming language, beginners and experts alike. Doing this exercise is a great a way to practice a new programming language you’re learning, improve with one you’re already familiar with, or rekindle your passion for programming. Even better, it will also give you a deeper understanding of how evolution works in the real world after simulating it in code.</p>
<p>I’m going to start by explaining the general steps of a standard genetic algorithm. Afterwards, and this is the fun part, I’m going to outline a problem to solve so you can start coding right away! Your resulting program only needs to take a single number as input and print a string as output, so it can have a simple command-line user interface or you can make a fancy web UI—it’s up to you how far you want to take it.</p>
<p>Throughout this tutorial, I’ll be using terms from the topics of natural selection and genetics. You do not need to understand the terms in depth in order to follow along. If you want to learn more about how these things work in the real world, check out <a href="https://neckdeep.dev/blog/2023-06-05-the-non-computer-science-behind-genetic-algorithms/">this article</a> by <a href="https://neckdeep.dev/">Danny Fekete</a>.</p>
<h1 id="a-standard-genetic-algorithm">A Standard Genetic Algorithm</h1>
<p>Very broadly, <strong>genetic algorithms</strong> attempt to mimic principles of natural selection and genetics to find optimal solutions to problems. The overall idea is, given a target problem, we’re going to encode potential solutions to the problem. Thinking of these potential solutions as <strong>organisms</strong>, we’ll simulate natural selection, allowing them to evolve into better solutions, and then hopefully leaving us with the kind of great solution we were looking for.</p>
<p>The kinds of problems genetic algorithms are well-suited for are problems in which we know what a good solution would look like, but can’t easily come up with one ourselves. Some use-cases are: the <a href="https://en.wikipedia.org/wiki/Travelling_salesman_problem">travelling salesman problem</a>, employee shift scheduling (e.g., the <a href="https://en.wikipedia.org/wiki/Nurse_scheduling_problem">nurse scheduling problem</a>), and <a href="https://en.wikipedia.org/wiki/List_of_genetic_algorithm_applications">many more</a>.</p>
<p>In this tutorial, I’m going to describe a <em>standard</em> genetic algorithm, which is easy to code and also recommended by experts. The idea is, once you understand how to code this version of a genetic algorithm, when you have a new problem to solve, you can attempt to apply this algorithm as-is or make modifications to the steps as needed.</p>
<blockquote>
<p>Start by using an “off the shelf” GA (genetic algorithm). It is pointless developing a complex GA, if your problem can be solved using a simple and standard implementation.</p>
<p>– Sastry, K., Goldberg, D., Kendall, G. (2005). <a href="https://doi.org/10.1007/0-387-28356-0_4">Genetic Algorithms</a>.</p>
</blockquote>
<p>Before we dive into details, here’s a high-level overview of the steps of the algorithm:</p>
<ul>
<li><strong>Planning:</strong> Before writing any code, we need to answer the question: <em>How do we encode a potential solution to the target problem?</em></li>
<li><strong>Setting parameters:</strong> There are a few key parameters that need to be set, which will heavily influence the performance of the algorithm each time we run it.</li>
<li><strong>Create initial population:</strong> The first population of organisms is created.</li>
<li><strong>Fitness evaluation:</strong> The fitness of each organism in the entire population is evaluated.</li>
<li><strong>Selection:</strong> Two organisms are selected as parents to reproduce.</li>
<li><strong>Crossover:</strong> The parents produce two offspring by potentially undergoing <em>crossover</em>.</li>
<li><strong>Mutation:</strong> Some genes in the offspring might get mutated.</li>
<li><strong>Replace population:</strong> When there’s enough offspring to form a new population, the old population gets replaced.</li>
<li><strong>Pick the winner:</strong> The fittest organism in the remaining population is your solution!</li>
</ul>
<div class="center">
<p><img src="images/blog/genetic_algorithm/genetic_algorithm_flow.svg" /></p>
</div>
<h2 id="step-1-planning">Step 1. Planning</h2>
<p>The first step towards building your own genetic algorithm for a target problem is to plan how potential solutions to the problem will be encoded as organisms. More specifically, how to represent genes and chromosomes, and how to evaluate the fitness of an organism.</p>
<p>Breaking it down from the top, each <strong>organism</strong> will only be made up of a single <strong>chromosome</strong>, so the two terms are often interchangeable. (This also means an organism’s entire genome and DNA will be encoded in its one-and-only chromosome, which makes things much simpler than with most real organisms.) All of the information for a potential solution must be encoded in this chromosome.</p>
<p>As in nature, a chromosome is made up of <strong>genes</strong>, which are like numbered containers for information. In this algorithm, and unlike in nature, chromosomes should all be the same length (i.e., they should contain the same number of genes). This is necessary in order for the <em>crossover</em> step to work as it is described in Step 6.</p>
<p>Each gene’s information only has so many possible variations. A particular variant of a gene is called an <strong>allele</strong>. Breaking down this last piece, an allele is made up of <strong>nucleotides</strong> (the building blocks of DNA), which are essentially units of information. In our code, each nucleotide will be represented by one <strong>bit</strong> (<code>0</code> or <code>1</code>), since this is the smallest piece of information on a computer.</p>
<p>Genes, each having their own position in a chromosome, can be different sizes. To determine the size of a particular gene, we need to decide on the number of possible alleles needed for the target problem at that gene. For example, if you choose a gene to be 3 bits in size, that gives</p>
<div class="center">
<p><strong>(size of bit)<sup>(size of gene)</sup> = 2<sup>3</sup> = 8</strong></p>
</div>
<p>different possible variants of the gene. (The size of a bit is always 2, since there are only two possible values: <code>0</code> or <code>1</code>.)</p>
<p>Each organism should represent a potential solution to the operating problem. An organism’s representation is called its <strong>phenotype</strong>. For instance, if the expected solution to an operating problem is an English word, each gene in that organism could be expressed as a letter (e.g., “d”). The combined result of its genes would be its phenotype: a string of letters (e.g., “dwnlode”). In this example, we only need one kind of gene because each part of a chromosome is a letter all the same.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<p>To allow for 26 (lowercase) letters, we would need genes to be at least 5 bits in length (2<sup>5</sup> would give us the necessary headroom of 32 possible alleles):</p>
<div class="table-container">

<table>
<thead>
<tr class="header">
<th>allele</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>00001</code></td>
<td><code>a</code></td>
</tr>
<tr class="even">
<td><code>00010</code></td>
<td><code>b</code></td>
</tr>
<tr class="odd">
<td><code>00011</code></td>
<td><code>c</code></td>
</tr>
<tr class="even">
<td>…</td>
<td>…</td>
</tr>
<tr class="odd">
<td><code>11010</code></td>
<td><code>z</code></td>
</tr>
</tbody>
</table>
</div>

<p>Here’s a breakdown of an example chromosome that could be used for that kind of word-based operating problem:</p>
<div class="center">
<p><img src="images/blog/genetic_algorithm/chromosome_explanation.svg" /></p>
</div>
<p>The first gene in the above chromosome has the allele that represents the value “a”.</p>
<p>Now for fitness. For whatever problem we want our algorithm to solve, we need to know what a good solution looks like because we need some way of knowing which organisms are better than others. The idea here is to come up with a way to <strong>evaluate</strong> each organism and give it a <strong>fitness</strong> score (a decimal number). The higher the fitness score, the closer the organism is to an ideal solution. It’s difficult to be more descriptive than this because fitness evaluation varies a lot depending on the problem, so I’ll explain by example.</p>
<p>Let’s say the target problem is to find the best values for <code>a</code>, <code>b</code>, <code>c</code>, and <code>d</code> in the equation <code>a + 2b + 3c + 4d = 30</code>.<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> Each organism’s phenotype is its particular values for <code>a</code>, <code>b</code>, <code>c</code>, and <code>d</code>. The fitness evaluation for this problem could be:</p>
<div class="center">
<pre class="example"><code>1 / (abs((a + 2b + 3c + 4d) - 30) + 1)
</code></pre>
</div>
<p>Where <code>abs</code> gives the absolute value of a number. This evaluation is designed to give a higher fitness score for better values, with 1 being a perfect score. The range is <code>(0, 1]</code>, meaning from 0 (exclusive) to 1 (inclusive).</p>
<p>So, an organism with the values <code>a = 0</code>, <code>b = 0</code>, <code>c = 10</code>, and <code>d = 0</code> would have a fitness of 1…</p>
<div class="center">
<pre class="example"><code>1 / (((a + 2b + 3c + 4d) - 30) + 1)
= 1 / (((0 + 2(0) + 3(10) + 4(0)) - 30) + 1)
= 1 / (0 + 1)
= 1
</code></pre>
</div>
<p>…which is a perfect score! This makes sense, because these values perfectly satisfy the target equation.</p>
<div class="center">
<pre class="example"><code>a + 2b + 3c + 4d = 30
0 + 2(0) + 3(10) + 4(0) = 30
30 = 30
</code></pre>
</div>
<h2 id="step-2" id="step-2-setting-parameters">Step 2. Setting parameters</h2>
<p>The algorithm has four major parameters that must be set. These will affect how well the algorithm performs each time it runs on a target problem. Once you’ve finished implementing your algorithm, these are the parameters you’ll want to play with and see how it performs differently.</p>
<h3 id="population-size">Population size</h3>
<p>This is the number of organisms in the population for each generation. We’ll call this parameter <code>populationSize</code>.</p>
<p>A good starting point is <code>populationSize = 50</code>.</p>
<h3 id="crossover-rate">Crossover rate</h3>
<p>As pairs of organisms are selected to reproduce for the next generation, they may produce exact copies or be combined (like sexual reproduction in the real world). The crossover rate is the <strong>probability</strong> that each pair of selected organisms will be crossed over, which will be explained in Step 6. We’ll call this parameter <code>crossoverRate</code>.</p>
<p>A good starting point is <code>crossoverRate = 0.6</code>.</p>
<h3 id="mutation-rate">Mutation rate</h3>
<p>Every bit of information in every chromosome has a (low) chance to be mutated, which will be explained in Step 7. Mutations can spark new traits that can then be carried to future generations, adding diversity to the population. We’ll call this parameter <code>mutationRate</code>.</p>
<p>A good starting point is <code>mutationRate = 0.05</code>.</p>
<h3 id="stopping-condition">Stopping condition</h3>
<p>At some point, the algorithm has to stop, otherwise you’ve created an infinite loop! The easiest stopping condition to implement is to set a limit on the <strong>number of generations</strong>. When the limit is reached, take the organism with the highest fitness from the last generation’s population and you have a solution!</p>
<p>Alternately, you could let the stopping condition be a <strong>fitness threshold</strong>. When a organism’s fitness meets the threshold, halt and deem it the winner!</p>
<h2 id="step-3-create-initial-population">Step 3. Create initial population</h2>
<p>The first generation of organisms needs to come from somewhere. A good way to make the first population is to randomly generate every bit of information in every organism’s chromosome until the number of organisms is equal to <code>populationSize</code>. That way, all the organisms in the population will have completely random genes.</p>
<h2 id="step-4-fitness-evaluation">Step 4. Fitness evaluation</h2>
<p>Let the games begin! Evaluate the fitness of every organism in the population and store this information to be used in the next step.<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></p>
<h2 id="step-5-selection">Step 5. Selection</h2>
<p>This step begins the reproduction process (along with the next two steps). The current population needs to be used to form a new population (the next generation). Essentially, we’re going to select pairs of organisms from the current population and have them reproduce to form offspring. Each pair will produce two offspring, and once we have enough offspring (determined by <code>populationSize</code>), they will replace the current population.</p>
<p>Since the goal of the algorithm is to work towards a better solution, this step is where we simulate competition. In nature, not all members will reproduce equally—some will thrive and have lots of offspring while others will be less successful by comparison (due to death, inability to find a mate, etc.). Instead of just selecting organisms at random, the probability that an organism is selected should be proportional to its fitness. After all, this is the purpose of an organism’s fitness! It should be more likely for high-performing organisms to be selected for reproduction than their lower-performing peers. For this, we’re going to use the <strong>roulette wheel</strong> strategy.</p>
<p>Let’s say we have a population of five organisms:</p>
<div class="table-container">

<table>
<thead>
<tr class="header">
<th>Organism</th>
<th>Chromosome</th>
<th>Fitness</th>
<th>Percent of population fitness</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><span style="color:#9933FF">&#9632;</span> 1</td>
<td><code>0011 0110</code></td>
<td>0.23</td>
<td>9.9%</td>
</tr>
<tr class="even">
<td><span style="color:#333333">&#9632;</span> 2</td>
<td><code>0001 1010</code></td>
<td>0.68</td>
<td>29.2%</td>
</tr>
<tr class="odd">
<td><span style="color:#61C0FF">&#9632;</span> 3</td>
<td><code>1001 1011</code></td>
<td>0.1</td>
<td>4.3%</td>
</tr>
<tr class="even">
<td><span style="color:#17C22E">&#9632;</span> 4</td>
<td><code>1010 0111</code></td>
<td>0.95</td>
<td>40.8%</td>
</tr>
<tr class="odd">
<td><span style="color:#EB0000">&#9632;</span> 5</td>
<td><code>0101 0010</code></td>
<td>0.37</td>
<td>15.9%</td>
</tr>
</tbody>
</table>
</div>

<p>(Don’t pay much attention to the chromosome values in this example. I made them up randomly.)</p>
<p>At a casino, every segment of a roulette wheel is equal in size. But our goal is to make a rigged roulette wheel where the segments are proportional to their fitness:</p>
<div class="center">
<p><img src="images/blog/genetic_algorithm/genetic_algorithm_roulette.png" /></p>
</div>
<p>Now, when we spin the wheel to select an organism, it’s obvious there will be a bigger chance to land on <strong>organism 4</strong> than any other organism.</p>
<p>If you want more direct instructions on implementing the roulette wheel strategy in code, click/tap below. Or, you can enjoy devising the algorithm on your own!</p>
<details>
<summary>Show roulette wheel instructions</summary>

<p>To implement roulette wheel selection in code, this is what you need to do:</p>
<ul>
<li>(Your organisms must be kept in order. The way they’re ordered doesn’t matter, so long as the order doesn’t change.)</li>
<li>Calculate the total fitness of the population (sum the fitnesses of all organisms).</li>
<li>Calculate the cumulative fitness of each organism. The cumulative fitness of an organism is its fitness plus the sum of the fitnesses of all the organisms before it.</li>
<li>Generate a random number, <code>r</code>, between 0 (exclusive) and the total fitness (inclusive).</li>
<li>Find the first organism whose cumulative fitness is greater than or equal to <code>r</code>.</li>
</ul>
<p>For example, if we calculate the cumulative fitnesses of our organisms…</p>
<div class="table-container">

<table>
<thead>
<tr class="header">
<th>Organism</th>
<th>Chromosome</th>
<th>Fitness</th>
<th>Cumulative fitness</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>1</td>
<td><code>0011 0110</code></td>
<td>0.23</td>
<td>0.23</td>
</tr>
<tr class="even">
<td>2</td>
<td><code>0001 1010</code></td>
<td>0.68</td>
<td>0.91</td>
</tr>
<tr class="odd">
<td>3</td>
<td><code>1001 1011</code></td>
<td>0.1</td>
<td>1.01</td>
</tr>
<tr class="even">
<td>4</td>
<td><code>1010 0111</code></td>
<td>0.95</td>
<td>1.96</td>
</tr>
<tr class="odd">
<td>5</td>
<td><code>0101 0010</code></td>
<td>0.37</td>
<td>2.33</td>
</tr>
</tbody>
</table>
</div>

<p>…and if <code>r</code> turns out to be 1.89, that means we select <strong>organism 4</strong>.</p>
<div class="center">
<p><img src="images/blog/genetic_algorithm/roulette_wheel_cumulative.svg" /></p>
</div>
</details>

<p>We have now met the overall goal of this step: to <strong>select two organisms while accounting for their fitness</strong>, which will be used in the next step to produce a pair of offspring.<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a></p>
<h2 id="step-6-crossover">Step 6. Crossover</h2>
<p>The purpose of this step is to involve an important aspect of natural selection: heredity. Offspring tend to resemble some combination of their parents (and diminishingly, their more distant ancestors). We’re going to achieve this through reproduction by breeding or cloning. The offspring of the two previously selected organisms will either inherit a combination of their traits (genes from both parents) or be clones of the parents.</p>
<p>To check if a crossover should happen, generate a random number, <code>r</code>, between 0 and 1. If <code>r</code> is less than or equal to <code>crossoverRate</code>, perform a crossover. Otherwise, let the offspring be exact copies of the parents (put simply, the parents become the offspring).</p>
<p>To crossover two organisms, pick a random position between the genes of a chromosome and swap all the alleles to the right in the first chromosome with the corresponding alleles in the second chromosome. (Remember, our chromosomes are supposed to contain the same number of genes, so this makes it easy to line them up and cut them at the same spot.)</p>
<div class="center">
<p><img src="images/blog/genetic_algorithm/crossover.svg" /></p>
</div>
<h2 id="step-7-mutation">Step 7. Mutation</h2>
<p>Due to mutation in nature, novel or modified characteristics occasionally show up that do not appear to have belonged to an ancestor, but can still be passed on to offspring like any other trait. Combined with heredity, this suggests that a population has a capacity for change beyond just an endless recombination of preexisting traits. And due to fitness-based selection, occasionally a novel trait will arise that confers a competitive advantage (e.g., the organism that has that new trait is better able to survive and reproduce because of it). These traits will then enter and proliferate across the population through subsequent generations.</p>
<p>To simulate genetic mutation in code, we allow the newly formed offspring the potential to mutate. For each bit in each offspring’s chromosome:</p>
<ul>
<li>Generate a random number, <code>r</code>, between 0 and 1.</li>
<li>If <code>r</code> is less than or equal to <code>mutationRate</code>, mutate the bit. To mutate, simply flip the bit (<code>0</code> to <code>1</code>, or <code>1</code> to <code>0</code>).</li>
</ul>
<h2 id="step-8-replace-population">Step 8. Replace population</h2>
<p>Steps 5 to 7 (selection, crossover, and mutation) taken as a cycle together form the reproduction process. Each cycle produces two offspring. We need to repeat the cycle until we get enough offspring to form a new population (<code>populationSize</code>), which immediately replaces the old population. The old population won’t be needed anymore (everything dies…). (For practical purposes, this means offspring never reproduce with the previous generation.)</p>
<h2 id="step-9-repeat-until-the-stopping-condition-is-met">Step 9. Repeat until the stopping condition is met</h2>
<p>As the gods of this artificial world of digital organisms, we decide when the simulation ends.</p>
<p>Steps 4 to 8 form the main loop of the algorithm. Each iteration of that loop is one generation. The planned stopping condition marks the end of the loop, which leaves us with the last generation’s population. If the stopping condition is a limit on the number of generations, say 100, then we simply stop after repeating 100 iterations.</p>
<h2 id="step-10-pick-the-winner">Step 10. Pick the winner</h2>
<p>In the remaining population, pick the organism with the highest fitness. There’s your solution!</p>
<h1 id="a-target-problem">A Target Problem</h1>
<p>Just reading about genetic algorithms won’t be enough to grasp this concept; you need to try implementing a genetic algorithm on your own. But first, you need the right kind of problem to solve. Lucky for you, I’ve got that part covered! In this section, I’m going to outline a problem and give you all the necessary details so you can start coding in any programming language you want. In other words, I’m going to cover <strong>Step 1</strong> (planning) and you have to do the rest.</p>
<h2 id="the-problem">The Problem</h2>
<p>Given a target number, find a human-readable string of single-digit numbers and basic arithmetic operators that equals that number. For example, if the target number is 10, some solutions would be:</p>
<ul>
<li><code>5 + 5</code></li>
<li><code>5 * 2</code></li>
<li><code>5 + 5 + 1 - 1 - 5 - 5 + 1 + 9 * 1 / 1</code></li>
</ul>
<p><strong>Note:</strong> Because the solutions should take the form of math strings, you should decide how those strings get evaluated. For example, they could be evaluated left-to-right or use the standard order of operations (multiplication &gt; division &gt; addition &gt; subtraction). So, <code>2 + 2 * 3 = 8</code> or <code>2 + 2 * 3 = 12</code>. Feel free to choose whichever evaluation method is easier for you to implement.</p>
<h2 id="implementing-step-1-planning">Implementing Step 1. Planning</h2>
<p>Since all of the example solutions (above) equal 10 exactly, in a genetic algorithm they would all be ideal matches with perfect fitness. Of course, there are many possible solutions to reach any target number and our genetic algorithm may not discover <em>any</em> of them in the limited time it has to run. So, the true goal of our genetic algorithm is to give us the <em>best</em> candidate after a certain number of generations. After all, genetic algorithms aren’t guaranteed to give perfect solutions every time.</p>
<p>In this problem, a potential solution is to be a string of single-digit numbers and arithmetic operators, so that is exactly what an organism’s chromosome should represent. The genes, being pieces of a chromosome, should therefore each express a single-digit number or an arithmetic operator. More specifically, we want strings that alternate between numbers and operators (<em>number</em> <em>operator</em> <em>number</em> <em>operator</em> …). So, let’s have two kinds of genes: a number gene and an operator gene.</p>
<p>To determine gene size, we need to know how many possible alleles are necessary. For number genes, the required values are single-digit numbers: <code>0</code>, <code>1</code>, <code>2</code>, <code>3</code>, <code>4</code>, <code>5</code>, <code>6</code>, <code>7</code>, <code>8</code>, and <code>9</code>. That’s ten possible alleles in total, so we need a minimum of four bits per gene (giving us 2<sup>4</sup> = 16 different possible alleles). We’ll have a few alleles left over, but we can consider them junk if they turn up in the resulting chromosome. So, our alleles for number genes are:</p>
<div class="table-container">

<table>
<thead>
<tr class="header">
<th>allele</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>0000</code></td>
<td><code>0</code></td>
</tr>
<tr class="even">
<td><code>0001</code></td>
<td><code>1</code></td>
</tr>
<tr class="odd">
<td><code>0010</code></td>
<td><code>2</code></td>
</tr>
<tr class="even">
<td><code>0011</code></td>
<td><code>3</code></td>
</tr>
<tr class="odd">
<td><code>0100</code></td>
<td><code>4</code></td>
</tr>
<tr class="even">
<td><code>0101</code></td>
<td><code>5</code></td>
</tr>
<tr class="odd">
<td><code>0110</code></td>
<td><code>6</code></td>
</tr>
<tr class="even">
<td><code>0111</code></td>
<td><code>7</code></td>
</tr>
<tr class="odd">
<td><code>1000</code></td>
<td><code>8</code></td>
</tr>
<tr class="even">
<td><code>1001</code></td>
<td><code>9</code></td>
</tr>
<tr class="odd">
<td><code>1010</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="even">
<td><code>1011</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="odd">
<td><code>1100</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="even">
<td><code>1101</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="odd">
<td><code>1110</code></td>
<td><code>(junk)</code></td>
</tr>
<tr class="even">
<td><code>1111</code></td>
<td><code>(junk)</code></td>
</tr>
</tbody>
</table>
</div>

<p>For operator genes, we need to represent four basic math operators: <code>+</code>, <code>-</code>, <code>*</code>, and <code>/</code>. Conveniently, we can use two bits for exactly four different possible values:</p>
<div class="table-container">

<table>
<thead>
<tr class="header">
<th>allele</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>00</code></td>
<td><code>+</code></td>
</tr>
<tr class="even">
<td><code>01</code></td>
<td><code>-</code></td>
</tr>
<tr class="odd">
<td><code>10</code></td>
<td><code>*</code></td>
</tr>
<tr class="even">
<td><code>11</code></td>
<td><code>/</code></td>
</tr>
</tbody>
</table>
</div>

<p>As an example, we could have the following organism’s chromosome and its phenotype:</p>
<div class="center">
<p><img src="images/blog/genetic_algorithm/problem_chromosome_explanation.svg" /></p>
</div>
<p>When evaluating a math string (an organism’s phenotype), we’ll have to clean up any junk it may have. Let’s say, for any junk in the string, ignore the junk gene and its immediately preceeding gene (which should be an operator).</p>
<p>Here’s an example with clean-up:</p>
<div class="center">
<pre class="example"><code>[0101 10 0010 00 1010 01 0001 00 1000 11 1111 00 0010]
= 5 * 2 + (junk) - 1 + 8 / (junk) + 2
= 5 * 2 - 1 + 8 + 2
= 19
</code></pre>
</div>
<p>Now we need to decide how the fitness of an organism should be evaluated. Recall that we need an evaluation function which produces a higher number for organisms that are closer to the ideal solution. Ideally, we should fit the fitness number into the range <code>(0, 1]</code>, since this makes the roulette wheel selection easier. Try to come up with this function yourself, or click/tap to see my suggestion below (there’s more than one right answer!).</p>
<details>
<summary>Show fitness function</summary>

<p><code>fitness(phenotype) = 1 / abs((target - phenotype) + 1)</code></p>
<p>Where <code>phenotype</code> is the evaluated expression of a given organism, <code>target</code> is the target number, and <code>abs</code> gives the absolute value of a number.</p>
</details>

<p><strong>Watch out!</strong> It is very possible for division by 0 to be part of a phenotype. I’ll leave it up to you to decide how to handle it, but do expect it to happen and think about your options.</p>
<h2 id="build-it">Build it!</h2>
<p>That’s it! Now you’re on your own to code this algorithm by implementing Steps 2 through 10. In the end, you should have a program which, given a target number, produces a math expression for that number. Remember, if you’re not getting good results, try tweaking the <a href="#step-2">parameters</a>.</p>
<h1 id="food-for-thought">Food for Thought</h1>
<h2 id="why-a-chance-of-crossover">Why a chance of crossover?</h2>
<p>Why is it important to have a chance of crossover <em>not</em> happening? Suppose we have two organisms, Alice and Bob, selected to be parents. Alice’s fitness is 99% and Bob’s is 80%. If Alice and Bob are to produce offspring who inherit from both of them, the offspring are almost guaranteed to have a lower fitness than Alice’s 99%. A preferable outcome would be for Alice’s offspring to <em>exclusively</em> contain her genes—without any crossover with Bob—resulting in a clone. (That final percentage point of fitness might be then achieved with a lucky mutation.)</p>
<h2 id="can-organisms-breed-with-themselves">Can organisms breed with themselves?</h2>
<p>Did you notice, in the reproduction process, it’s possible for an organism to be paired with itself? The exact same organism can be <strong>selected</strong> twice in a row! Then, in the <strong>crossover</strong> step, whether a crossover happens or not, we’ll get two identical offspring. So really, one organism can be taken from the current population to produce <em>two</em> of itself for the next population. What are the possible implications of this when the algorithm runs?</p>
<h2 id="what-does-cloning-represent">What does cloning represent?</h2>
<p>When a crossover doesn’t occur, the offspring are clones of the parents. What does it mean to produce clones? Are we simulating an organism that reproduces both sexually <em>and</em> asexually? Or are we representing organisms that simply carry on living into the next generation?</p>
<h2 id="what-are-the-traits">What are the traits?</h2>
<p>In the real world, organisms can be described as having many traits. In the target problem described above, what are the traits of an organism? Do each of our organisms only have a single trait: its evaluated number? Or can we think of each expressed allele as a trait?</p>
<h2 id="when-does-crossover-help">When does crossover help?</h2>
<p>In the target problem described above, does crossing over two high-fitness organisms have a good chance of producing high-fitness offspring? Swapping genes seems likely to drastically, and almost randomly, change a organism’s phenotype. It seems more like mutating a chunk of a chromosome than inheriting traits.</p>
<h2 id="what-are-other-ways-of-representing-organisms-in-the-target-problem">What are other ways of representing organisms in the target problem?</h2>
<p>The plan I laid out for the target problem is only one of many options. What are some other ways you could define genes and chromosomes to build math strings? Do we need more than one kind of gene?</p>
<h1 id="footnotes">Footnotes</h1>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>For a problem that requires solutions with more structure, we could choose chromosomes’ genes to be different lengths. For example, chromosomes could be three genes in length, where the first gene holds 2 bits, the second gene holds 5 bits, and the third gene holds 4 bits. However many different kinds of genes we want to have, each one must have its own set of possible alleles.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Example borrowed from: Hermawanto, D. (2013). Genetic algorithm for solving simple mathematical equality problem. arXiv preprint <a href="https://arxiv.org/pdf/1308.4675.pdf">arXiv:1308.4675</a>.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>This is arguably an implementation detail pertaining to optimization via caching, but I see it as having conceptual importance. The fitness of an organism never changes because its genetics don’t change and the operating problem doesn’t change. This is different from how we might talk about people’s physical fitness, where you can become more fit by working out. Since we’re simulating natural selection and treating environmental factors as being constant, fitness is tied to the genetics of an organism, which are fixed. The only changes to genetics happen between generations (i.e., during reproduction). So, with fitness being an unchanging value of an organism, it should be evaluated exactly once per organism.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p>Note that this allows for the same organism to be selected more than once. That’s okay! Organisms with higher fitness being allowed to reproduce multiple times is part of natural selection. Less fit individuals may not be selected to breed at all, allowing their less-desirable traits to simply die out.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Mon, 05 Jun 2023 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/build-your-own-genetic-algorithm.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>When to use currying in JavaScript</title>
    <link>https://timjohns.ca/when-to-use-currying-in-javascript.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        When to use currying in JavaScript
      </h1>
      <p class="writing">Apr 11, 2023</p>
      
    </header>
	<img class="post-image" alt="Photo of a bowl of curry with a keyboard next to it." src="./images/blog/when_to_use_currying_in_javascript.jpg" />
    <section class="content writing">
	  <p>This post is about the concept of <strong>currying</strong>, from functional programming, and when you should use it in JavaScript.</p>
<p>I’m going to be honest. You probably don’t need to use currying in JavaScript. In fact, trying to fit it in your code is going to do more harm than good, unless it’s just for fun. Currying only becomes useful when you fully embrace functional programming, which, in JavaScript, means using a library like <a href="https://ramdajs.com/">Ramda</a> instead of the standard built-in functions.</p>
<p>In this article, I’m going to start by explaining what currying is, then show how it can be useful <strong>in a functional programming context</strong>.</p>
<h1 id="what-is-currying">What is currying?</h1>
<p>Currying is the concept that functions never need to take multiple arguments; every function only takes a single argument. If a function needs to <strong>behave</strong> as if it takes multiple arguments, it returns another function instead.</p>
<p>A regular, non-curried function is what you’re used to seeing:</p>
<div class="sourceCode" id="cb1" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> add <span class="op">=</span> (x<span class="op">,</span> y) <span class="kw">=&gt;</span> x <span class="op">+</span> y</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">add</span>(<span class="dv">2</span><span class="op">,</span> <span class="dv">3</span>) <span class="co">// 2 + 3</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>) <span class="co">// prints 5</span></span></code></pre></div>
<p>This is a simple function that takes two numbers and returns their sum.</p>
<p>A curried version of the same function looks like this:</p>
<div class="sourceCode" id="cb2" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> addCurried <span class="op">=</span> x <span class="kw">=&gt;</span> y <span class="kw">=&gt;</span> x <span class="op">+</span> y</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">addCurried</span>(<span class="dv">2</span>)(<span class="dv">3</span>) <span class="co">// 2 + 3</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>) <span class="co">// prints 5</span></span></code></pre></div>
<p>Instead of the function taking two arguments, it takes one argument, then returns <strong>another function</strong> that takes one argument and returns the sum. Notice how we have to pass the arguments to the function using more brackets, since the arguments are passed one at a time to each nested function.</p>
<p>We can have as many arguments as we want this way:</p>
<div class="sourceCode" id="cb3" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> addMore <span class="op">=</span> a <span class="kw">=&gt;</span> b <span class="kw">=&gt;</span> c <span class="kw">=&gt;</span> d <span class="kw">=&gt;</span> e <span class="kw">=&gt;</span> a <span class="op">+</span> b <span class="op">+</span> c <span class="op">+</span> d <span class="op">+</span> e</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">addMore</span>(<span class="dv">1</span>)(<span class="dv">2</span>)(<span class="dv">3</span>)(<span class="dv">4</span>)(<span class="dv">5</span>) <span class="co">// 1 + 2 + 3 + 4 + 5</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>) <span class="co">// prints 15</span></span></code></pre></div>
<p>Because of the way a curried function works, we can do something called <strong>partial application</strong>. This is when we give a function fewer arguments than it can take:</p>
<div class="sourceCode" id="cb4" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> addCurried <span class="op">=</span> x <span class="kw">=&gt;</span> y <span class="kw">=&gt;</span> x <span class="op">+</span> y</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">addCurried</span>(<span class="dv">2</span>) <span class="co">// y =&gt; 2 + y</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>) <span class="co">// [Function (anonymous)]</span></span></code></pre></div>
<p>If we only pass <code>addCurried</code> one argument, the result is a function that expects another argument. In other words, the <code>2</code> went into the <code>x</code> argument, so we’re left with <code>y =&gt; 2 + y</code>. If we want, we can store this partially applied function into a variable so we can use it after the fact:</p>
<div class="sourceCode" id="cb5" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> addCurried <span class="op">=</span> x <span class="kw">=&gt;</span> y <span class="kw">=&gt;</span> x <span class="op">+</span> y</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> add2 <span class="op">=</span> <span class="fu">addCurried</span>(<span class="dv">2</span>)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="co">// This is the same as:</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="co">// const add2 = y =&gt; 2 + y</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">add2</span>(<span class="dv">3</span>) <span class="co">// 2 + 3</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>) <span class="co">// prints 5</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">add2</span>(<span class="dv">10</span>) <span class="co">// 2 + 10</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>) <span class="co">// prints 12</span></span></code></pre></div>
<p>Now we have a function <code>add2</code>, which is expecting a single argument. Whatever we give it, it will add 2 to it.</p>
<h1 id="when-is-currying-useful">When is currying useful?</h1>
<p>Like I said, in a typical JavaScript codebase, it’s not. You can probably tell that the <code>addCurried</code> example is very contrived and doesn’t demonstrate any real benefit. But if you want to go deeper down the functional programming rabbit hole, let me show you how using curried functions can be even more elegant than the typical practice.</p>
<p>It’s all about composition.</p>
<p>In functional programming, <strong>composing</strong> functions is a fundamental concept. This means using <strong>one function after another</strong> on some data. It’s in using composition that curried functions really shine.</p>
<p>In JavaScript, the way to compose two functions looks like this:</p>
<div class="sourceCode" id="cb6" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> compose <span class="op">=</span> (f<span class="op">,</span> g) <span class="kw">=&gt;</span> x <span class="kw">=&gt;</span> <span class="fu">f</span>(<span class="fu">g</span>(x))</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> addCurried <span class="op">=</span> x <span class="kw">=&gt;</span> y <span class="kw">=&gt;</span> x <span class="op">+</span> y</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">compose</span>(<span class="fu">addCurried</span>(<span class="dv">2</span>)<span class="op">,</span> <span class="fu">addCurried</span>(<span class="dv">3</span>))(<span class="dv">10</span>) <span class="co">// 10 + 3 + 2 = 15</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>) <span class="co">// prints 15</span></span></code></pre></div>
<p>When using composition, you should read it as operations being done on some data from right to left. In the above example, the starting data is <code>10</code>, which goes through <code>adding 3</code>, followed by <code>adding 2</code>, resulting in <code>15</code>.</p>
<p>Let me show by example how composing a series of curried functions looks when compared to idiomatic functional JavaScript. I’m going to use an example based on a real problem I had to solve that doesn’t call for any particular programming style or language.</p>
<p>The objective is to make a function <code>cleanExpression</code> that takes in a basic math expression as a string (e.g., “1 + 10 / 2”) and returns a cleaned version of it. The cleaning process is to remove extra spaces and make sure the expression alternates numbers and operators (there should never be two numbers or two operators next to each other). We’re dealing with single-digit numbers only.</p>
<p>For example, “1    + 2 2 / 3 *” cleaned would be “1 + 2 / 3”.</p>
<p>The following is an idiomatic functional JavaScript solution. Let’s call this “functional-lite”.</p>
<div class="sourceCode" id="cb7" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Helper functions</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isOperator <span class="op">=</span> x <span class="kw">=&gt;</span> <span class="st">&quot;+-*/&quot;</span><span class="op">.</span><span class="fu">includes</span>(x)</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isDigit <span class="op">=</span> x <span class="kw">=&gt;</span> <span class="st">&quot;1234567890&quot;</span><span class="op">.</span><span class="fu">includes</span>(x)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> last <span class="op">=</span> xs <span class="kw">=&gt;</span> xs[xs<span class="op">.</span><span class="at">length</span> <span class="op">-</span> <span class="dv">1</span>]</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> init <span class="op">=</span> xs <span class="kw">=&gt;</span> xs<span class="op">.</span><span class="fu">slice</span>(<span class="dv">0</span><span class="op">,</span> <span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> intersperse <span class="op">=</span> (sep<span class="op">,</span> xs) <span class="kw">=&gt;</span> xs<span class="op">.</span><span class="fu">map</span>(x <span class="kw">=&gt;</span> [sep<span class="op">,</span> x])<span class="op">.</span><span class="fu">flat</span>()</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a><span class="co">// The main function</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> cleanExpression <span class="op">=</span> expr <span class="kw">=&gt;</span> {</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> parseNext <span class="op">=</span> ([acc<span class="op">,</span> shouldBe]<span class="op">,</span> x) <span class="kw">=&gt;</span> {</span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (shouldBe <span class="op">===</span> <span class="st">&#39;digit&#39;</span> <span class="op">&amp;&amp;</span> <span class="fu">isDigit</span>(x)) {</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [[<span class="op">...</span>acc<span class="op">,</span> x]<span class="op">,</span> <span class="st">&#39;operator&#39;</span>]</span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>    } <span class="cf">else</span> <span class="cf">if</span> (shouldBe <span class="op">===</span> <span class="st">&#39;operator&#39;</span> <span class="op">&amp;&amp;</span> <span class="fu">isOperator</span>(x)) {</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [[<span class="op">...</span>acc<span class="op">,</span> x]<span class="op">,</span> <span class="st">&#39;digit&#39;</span>]</span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>    } <span class="cf">else</span> {</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [acc<span class="op">,</span> shouldBe]</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> chars <span class="op">=</span> expr<span class="op">.</span><span class="fu">split</span>(<span class="st">&#39;&#39;</span>)</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> alternating <span class="op">=</span> chars<span class="op">.</span><span class="fu">reduce</span>(parseNext<span class="op">,</span> [<span class="st">&#39;&#39;</span><span class="op">,</span> <span class="st">&#39;digit&#39;</span>])[<span class="dv">0</span>]</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> cleaned <span class="op">=</span> <span class="fu">isOperator</span>(<span class="fu">last</span>(alternating)) <span class="op">?</span> <span class="fu">init</span>(alternating) <span class="op">:</span> alternating</span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="fu">intersperse</span>(<span class="st">&#39; &#39;</span><span class="op">,</span> cleaned)<span class="op">.</span><span class="fu">join</span>(<span class="st">&#39;&#39;</span>)</span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>  <span class="fu">cleanExpression</span>(<span class="st">&#39;1    + 2 2 / 3 *&#39;</span>)</span>
<span id="cb7-32"><a href="#cb7-32" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<p>And here is a more functional JavaScript solution using the <a href="https://ramdajs.com/">Ramda</a> library in-place of built-in functions:</p>
<div class="sourceCode" id="cb8" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> R <span class="op">=</span> <span class="pp">require</span>(<span class="st">&#39;ramda&#39;</span>)</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isOperator <span class="op">=</span> x <span class="kw">=&gt;</span> R<span class="op">.</span><span class="fu">includes</span>(x<span class="op">,</span> <span class="st">&quot;+-*/&quot;</span>)</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> isDigit <span class="op">=</span> x <span class="kw">=&gt;</span> R<span class="op">.</span><span class="fu">includes</span>(x<span class="op">,</span> <span class="st">&quot;1234567890&quot;</span>)</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> cleanExpression <span class="op">=</span> expr <span class="kw">=&gt;</span> {</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> parseNext <span class="op">=</span> ([acc<span class="op">,</span> shouldBe]<span class="op">,</span> x) <span class="kw">=&gt;</span> {</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (shouldBe <span class="op">===</span> <span class="st">&#39;digit&#39;</span> <span class="op">&amp;&amp;</span> <span class="fu">isDigit</span>(x)) {</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [acc <span class="op">+</span> x<span class="op">,</span> <span class="st">&#39;operator&#39;</span>]</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    } <span class="cf">else</span> <span class="cf">if</span> (shouldBe <span class="op">===</span> <span class="st">&#39;operator&#39;</span> <span class="op">&amp;&amp;</span> <span class="fu">isOperator</span>(x)) {</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [acc <span class="op">+</span> x<span class="op">,</span> <span class="st">&#39;digit&#39;</span>]</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>    } <span class="cf">else</span> {</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> [acc<span class="op">,</span> shouldBe]</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> R<span class="op">.</span><span class="fu">compose</span>(</span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>    R<span class="op">.</span><span class="fu">join</span>(<span class="st">&#39;&#39;</span>)<span class="op">,</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>    R<span class="op">.</span><span class="fu">intersperse</span>(<span class="st">&#39; &#39;</span>)<span class="op">,</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>    (xs <span class="kw">=&gt;</span> <span class="fu">isOperator</span>(R<span class="op">.</span><span class="fu">last</span>(xs)) <span class="op">?</span> R<span class="op">.</span><span class="fu">init</span>(xs) <span class="op">:</span> xs)<span class="op">,</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>    R<span class="op">.</span><span class="at">head</span><span class="op">,</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>    R<span class="op">.</span><span class="fu">reduce</span>(parseNext<span class="op">,</span> [<span class="st">&#39;&#39;</span><span class="op">,</span> <span class="st">&#39;digit&#39;</span>])<span class="op">,</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>    R<span class="op">.</span><span class="fu">split</span>(<span class="st">&#39;&#39;</span>)</span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>  )(expr)</span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a>  <span class="fu">cleanExpression</span>(<span class="st">&#39;1    + 2 2 / 3 *&#39;</span>)</span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<p>Fewer helper functions are needed because Ramda implements the others, but that’s not what’s important. The main lines to compare are in the body of <code>cleanExpression</code>:</p>
<div class="sourceCode" id="cb9" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="co">// functional-lite</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> chars <span class="op">=</span> expr<span class="op">.</span><span class="fu">split</span>(<span class="st">&#39;&#39;</span>)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> alternating <span class="op">=</span> chars<span class="op">.</span><span class="fu">reduce</span>(parseNext<span class="op">,</span> [<span class="st">&#39;&#39;</span><span class="op">,</span> <span class="st">&#39;digit&#39;</span>])[<span class="dv">0</span>]</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> cleaned <span class="op">=</span> <span class="fu">isOperator</span>(<span class="fu">last</span>(alternating)) <span class="op">?</span> <span class="fu">init</span>(alternating) <span class="op">:</span> alternating</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="fu">intersperse</span>(<span class="st">&#39; &#39;</span><span class="op">,</span> cleaned)<span class="op">.</span><span class="fu">join</span>(<span class="st">&#39;&#39;</span>)</span></code></pre></div>
<div class="sourceCode" id="cb10" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="co">// more functional</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> R<span class="op">.</span><span class="fu">compose</span>(</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  R<span class="op">.</span><span class="fu">join</span>(<span class="st">&#39;&#39;</span>)<span class="op">,</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  R<span class="op">.</span><span class="fu">intersperse</span>(<span class="st">&#39; &#39;</span>)<span class="op">,</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  (xs <span class="kw">=&gt;</span> <span class="fu">isOperator</span>(R<span class="op">.</span><span class="fu">last</span>(xs)) <span class="op">?</span> R<span class="op">.</span><span class="fu">init</span>(xs) <span class="op">:</span> xs)<span class="op">,</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>  R<span class="op">.</span><span class="at">head</span><span class="op">,</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  R<span class="op">.</span><span class="fu">reduce</span>(parseNext<span class="op">,</span> [<span class="st">&#39;&#39;</span><span class="op">,</span> <span class="st">&#39;digit&#39;</span>])<span class="op">,</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>  R<span class="op">.</span><span class="fu">split</span>(<span class="st">&#39;&#39;</span>)</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>)(expr)</span></code></pre></div>
<p>Ramda’s <code>compose</code> function extends function composition to any number of functions instead of only two. Still, it should be read from right to left (or bottom to top). The above example can be understood as:</p>
<ul>
<li>Feed in <code>expr</code> as the data to be operated on, which in this case should be a math expression as a string.</li>
<li>Split the string, turning it into an array of characters.</li>
<li>Use <code>reduce</code> to walk through the expression, building a new version that alternates digits and operators (beginning with a digit).</li>
<li>Take the first element of the previous result (because it returned a pair and we only need the new expression).</li>
<li>Remove the last character if it is an operator.</li>
<li>Intersperse the new expression with spaces.</li>
<li>Finally, Convert the new expression into a string.</li>
</ul>
<p>This way, we can think of the solution as processing some data through a pipeline (bottom to top). The output of each step feeds into the input of the next one until we reach the end, which gets returned as a final result.</p>
<p>The steps of the solution are the same in both versions, but the second version looks more linear and we can clearly see each step.</p>
<p>For the <strong>most functional</strong> version, here’s the same solution in Haskell, where all functions are curried by default and the composition operator is a dot (<code>.</code>) :</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">isOperator ::</span> <span class="dt">Char</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>isOperator x <span class="ot">=</span> x <span class="ot">`elem`</span> <span class="st">&quot;+-*/&quot;</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="fu">isDigit</span><span class="ot"> ::</span> <span class="dt">Char</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="fu">isDigit</span> x <span class="ot">=</span> x <span class="ot">`elem`</span> <span class="st">&quot;1234567890&quot;</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="ot">intersperse ::</span> <span class="dt">Char</span> <span class="ot">-&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>intersperse sep <span class="ot">=</span> <span class="fu">init</span> <span class="op">.</span> <span class="fu">concat</span> <span class="op">.</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> [x, sep])</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a><span class="ot">cleanExpression ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>cleanExpression <span class="ot">=</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>  intersperse <span class="ch">&#39; &#39;</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span> (\xs <span class="ot">-&gt;</span> <span class="kw">if</span> isOperator (<span class="fu">last</span> xs) <span class="kw">then</span> <span class="fu">init</span> xs <span class="kw">else</span> xs)</span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span> <span class="fu">fst</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span> <span class="fu">foldl</span> parseNext (<span class="st">&quot;&quot;</span>, <span class="st">&quot;digit&quot;</span>)</span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a><span class="ot">    parseNext ::</span> (<span class="dt">String</span>, <span class="dt">String</span>) <span class="ot">-&gt;</span> <span class="dt">Char</span> <span class="ot">-&gt;</span> (<span class="dt">String</span>, <span class="dt">String</span>)</span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a>    parseNext (acc, shouldBe) x</span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> shouldBe <span class="op">==</span> <span class="st">&quot;digit&quot;</span> <span class="op">&amp;&amp;</span> <span class="fu">isDigit</span> x <span class="ot">=</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a>        (acc <span class="op">++</span> [x], <span class="st">&quot;operator&quot;</span>)</span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> shouldBe <span class="op">==</span> <span class="st">&quot;operator&quot;</span> <span class="op">&amp;&amp;</span> isOperator x <span class="ot">=</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a>        (acc <span class="op">++</span> [x], <span class="st">&quot;digit&quot;</span>)</span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (acc, shouldBe)</span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> cleanExpression <span class="st">&quot;1    + 2 2 / 3 *&quot;</span> <span class="op">==</span> <span class="st">&quot;1 + 2 / 3&quot;</span></span></code></pre></div>
<h1 id="conclusion">Conclusion</h1>
<p>Currying is not a very complicated concept, but most people are unfamiliar with it because they have no use for it. And for good reason! It only shines when you decide to write <strong>very functional</strong> code and use composition everywhere. Languages like Haskell take advantage of this by defining all functions to be curried by default and having a very small operator for composing functions (like a dot).</p>
<p>For a fun exercise, try implementing Ramda’s <code>compose</code> function on your own! It should be able to compose any number of functions, not just two.</p>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Tue, 11 Apr 2023 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/when-to-use-currying-in-javascript.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>A Simple Sandwich, Part II</title>
    <link>https://timjohns.ca/a-simple-sandwich-part-ii.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        A Simple Sandwich, Part II
      </h1>
      <p class="writing">Jan 17, 2023</p>
      
    </header>
	<img class="post-image" alt="Drawing of a sandwich" src="./images/blog/a_simple_sandwich_ii.jpg" />
    <section class="content writing">
	  <p>(This is a continuation from <a href="./a-simple-sandwich-part-i.html">Part I</a>, a philosophical exploration about programming, with sandwiches. Go read it first, if you haven’t yet.)</p>
<p>In <a href="./a-simple-sandwich-part-i.html">Part I</a>, I talked about error handling, mutability and state, and programming paradigms. Now it’s time to look at a problem from the perspective of using <strong>type theory</strong>. My original plan was, after writing an idiomatic Haskell solution to making abstract sandwiches, to write a Haskell solution using type-level programming techniques. Writing an Agda solution was going to be the last step. Well, plans change. After some attempts at trying to write a meaningful type-level Haskell solution, I realized that Haskell’s type system is simply not equipped to express these kinds of ideas nearly as well as Agda’s.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> Let me explain.</p>
<h1 id="defining-a-sandwich-as-a-type">Defining a Sandwich as a Type</h1>
<p>At the end of <a href="./a-simple-sandwich-part-i.html">Part I</a>, I explained how it’s easily possible to make an impossible sandwich with the previously proposed solution. Let’s see how we can fix that.</p>
<p>In the context of this exploration, I’m going to define a sandwich as follows:</p>
<blockquote>
<p>A sandwich consists of a bottom and a top, which are both slices of bread. Neither the bottom or top can be smeared on the outside. At least one of the bottom or top must be smeared on the inside. A sandwich may be in one or more pieces (i.e., it can be cut).</p>
</blockquote>
<p>I know, this doesn’t cover nearly all the exotic sandwiches you have in mind. I want to keep the scope of this problem small so the code is easier to understand, so we’re just going to deal with peanut butter and/or jelly sandwiches. To be clear, the reason sandwiches can’t be smeared on the outside is it makes them icky to hold.</p>
<p>So, with that definition in mind, let’s look at the Haskell sandwich from <a href="./a-simple-sandwich-part-i.html">Part I</a> and see where it falls short.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Sandwich</span> <span class="ot">=</span> <span class="dt">Sandwich</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> bottom ::</span> <span class="dt">SliceOfBread</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> top ::</span> <span class="dt">SliceOfBread</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> pieces ::</span> <span class="dt">Integer</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>(This isn’t exactly what I had in <a href="./a-simple-sandwich-part-i.html">Part I</a>. Here, I’ve made a small change to simplify the problem: instead of keeping track of the pieces and their details, we’re only interested in the <em>number</em> of pieces.)</p>
<p>What we have here is a definition of a <code>Sandwich</code> <strong>type</strong> in Haskell. The concept of <strong>type theory</strong> is that there are <strong>types</strong> and <strong>values</strong> (also called <strong>terms</strong> or <strong>elements</strong>). A value belongs to a certain type. No value exists without a type. When we think or program in type theory, we define <strong>what something is</strong> by making a new type for it. Then, we can make values of that type. Just like I gave an English definition of a sandwich (<strong>type</strong>), I can now go make an actual sandwich (<strong>value</strong>) and say that it fits the definition. For object-oriented programmers, it can help to think of types as being like classes and values as being like instances of a class.</p>
<p>Taking our <code>Sandwich</code> type and reverse engineering it into English, we get:</p>
<blockquote>
<p>A sandwich consists of a bottom and a top, both slices of bread. (Off to a great start!) A sandwich may be in any number of pieces.</p>
</blockquote>
<p>Hmm. This doesn’t quite match our desired definition. First, there’s nothing about smearing. And, the sandwich can be in zero or even negative pieces! Now, to be fair, the smearing is included in the <code>SliceOfBread</code> type:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SliceOfBread</span> <span class="ot">=</span> <span class="dt">SliceOfBread</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> flavour ::</span> <span class="dt">BreadFlavour</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> top ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> bottom ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>This type says, “a slice of bread is of a certain flavour and may be smeared with a condiment on the top and/or bottom.”</p>
<p>So, there is something about smearing, but it doesn’t have the restriction we want, about the sandwich’s bottom and top being smeared only on the inside. In fact, with Haskell’s type system, we <em>can’t</em> represent that! Our only option is to leave the type as it is and handle the proper making of a sandwich in the logic of functions and thread error handling through all those functions (using <code>Either</code>). But, as we’ve seen (in <a href="./a-simple-sandwich-part-i.html">Part I</a>), that still leaves us with the ability to make improper sandwiches if we forego the use of those functions. For example:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Two plain slices of bread shouldn&#39;t be considered a sandwich.</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Not to mention it&#39;s in 0 pieces. What is this? An eaten sandwich?</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>badSandwich <span class="ot">=</span> <span class="dt">Sandwich</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  { bottom <span class="ot">=</span> <span class="dt">SliceOfBread</span> { flavour<span class="ot">=</span><span class="dt">Sourdough</span>, top<span class="ot">=</span><span class="dt">Nothing</span>, bottom<span class="ot">=</span><span class="dt">Nothing</span> }</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  , top <span class="ot">=</span> <span class="dt">SliceOfBread</span> { flavour<span class="ot">=</span><span class="dt">Sourdough</span>, top<span class="ot">=</span><span class="dt">Nothing</span>, bottom<span class="ot">=</span><span class="dt">Nothing</span> }</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  , pieces <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>The purpose of embedding our ideal definitions in types is to make it impossible to do things wrong. I don’t want it to be possible to make an improper sandwich, or even fail at any step along the way. That brings us to Agda.</p>
<p>Agda is a <strong>dependently typed</strong> programming language. Dependent types allow us to represent things intuitively. A dependent type is a type whose definition depends on a value. In the <code>Sandwich</code> type, its <code>bottom</code> has the type <code>SliceOfBread</code>, but that’s not enough information. We want it to be a <code>SliceOfBread</code> that is not smeared on its bottom. In other words, its type should be a <code>SliceOfBread</code> whose value looks something like this:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">SliceOfBread</span> { flavour<span class="op">=?</span>, top<span class="op">=?</span>, bottom<span class="ot">=</span><span class="dt">Nothing</span> }</span></code></pre></div>
<p>All this to say, the type of a sandwich’s bottom slice <strong>depends on its value</strong>.</p>
<p>In Agda, we can represent a sandwich like this:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Sandwich <span class="ot">:</span> Type <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    top <span class="ot">:</span> SliceOfBread</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    bottom <span class="ot">:</span> SliceOfBread</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    shellOk <span class="ot">:</span> checkShell top bottom</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    pieces <span class="ot">:</span> Σ n ꞉ ℕ , n ≥ <span class="dv">1</span></span></code></pre></div>
<p>In English, this means:</p>
<blockquote>
<p>A sandwich must have all of the following properties:</p>
<ul>
<li>a top, which is a slice of bread</li>
<li>a bottom, which is a slice of bread</li>
<li>a proof that the shell is OK</li>
<li>be cut into 1 or more pieces</li>
</ul>
</blockquote>
<p>Where’s the part about smearing? Well, that’s covered by the “proof that the shell is OK”. I’m calling the top and bottom slices of the sandwich its “shell”. The <code>checkShell</code> function looks like this:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>checkShell <span class="ot">:</span> SliceOfBread <span class="ot">→</span> SliceOfBread <span class="ot">→</span> Type</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>checkShell top bottom <span class="ot">=</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- The top slice is not smeared on its top</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  is-nothing <span class="ot">(</span>smearedTop top<span class="ot">)</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- and the bottom slice is not smeared on its bottom</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  × is-nothing <span class="ot">(</span>smearedBottom bottom<span class="ot">)</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- and either the bottom is smeared on its top or the top is smeared on its bottom (or both).</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  × <span class="ot">(</span>is-just <span class="ot">(</span>smearedBottom top<span class="ot">)</span> ∔ is-just <span class="ot">(</span>smearedTop bottom<span class="ot">))</span></span></code></pre></div>
<p>The type signature of this <code>checkShell</code> function says it takes in two slices of bread (a top and a bottom) and returns a <strong>type</strong>. Not a value of a specific type, like a boolean, but rather a value that is a type itself. A function returning a type as a value might seem like an odd thing, and it should, because it only makes sense in Agda-land. What does it mean? Why not return a boolean (true or false)? Well, if we return a boolean, we will have to check if the function returns <code>true</code> wherever we use it. But remember, we’re trying to make it impossible to build an improper sandwich. So, instead of checking that the function returned the right value, we can have a function that can <em>only</em> return a value if its arguments pass its validation check. This idea from type theory, often called “propositions as types”, is the idea that <strong>an element of a type is a proof of a theorem</strong>. In <code>checkShell</code>, the only elements of its resulting type are proofs that the top and bottom slices are smeared appropriately, as checked by the body of the function. Take a moment to digest this. Now, the <code>Sandwich</code> property <code>shellOk</code> has the type of <code>checkShell top bottom</code>, which means <code>shellOk</code> is a proof that the shell of the sandwich is OK! Anytime we want to make a value of the type <code>Sandwich</code>, we need to provide a proof that its shell is OK.</p>
<p>Altogether, this means we can only create a value of type <code>Sandwich</code> if it is a proper sandwich! And the type of <code>Sandwich</code> (together with <code>checkShell</code>) represents our original definition accurately:</p>
<blockquote>
<p>A sandwich consists of a bottom and a top, which are both slices of bread. Neither the bottom or top can be smeared on the outside. At least one of the bottom or top must be smeared on the inside. A sandwich may be in one or more pieces (i.e., it can be cut).</p>
</blockquote>
<h1 id="dependently-typed-utensils">Dependently Typed Utensils</h1>
<p>In <a href="./a-simple-sandwich-part-i.html">Part I</a>, I encoded utensils in Haskell like this:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Condiment</span> <span class="ot">=</span> <span class="dt">PeanutButter</span> <span class="op">|</span> <span class="dt">Jelly</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">UtensilShape</span> <span class="ot">=</span> <span class="dt">Knife</span> <span class="op">|</span> <span class="dt">Spoon</span> <span class="op">|</span> <span class="dt">Fork</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Utensil</span> <span class="ot">=</span> <span class="dt">Utensil</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> shape ::</span> <span class="dt">UtensilShape</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> loadedWith ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>These are type definitions. A utensil has a shape (knife, spoon, or fork) and may be loaded with a condiment. Now, the problem is, I <em>wanted</em> to say that a utensil has a shape and may be loaded with a condiment <em>if its shape is a knife</em>. But we can’t write that in Haskell because <code>loadedWith</code> would <strong>depend</strong> on the value of <code>shape</code>.</p>
<p>Since Agda is dependently typed, we can easily write this!</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- We only have peanut butter and jelly in the pantry.</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Condiment <span class="ot">:</span> Type <span class="kw">where</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  peanutButter jelly <span class="ot">:</span> Condiment</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> UtensilShape <span class="ot">:</span> Type <span class="kw">where</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  knife spoon fork <span class="ot">:</span> UtensilShape</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Utensil <span class="ot">:</span> Type <span class="kw">where</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>    shape <span class="ot">:</span> UtensilShape</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    loadedWith <span class="ot">:</span> Maybe <span class="ot">((</span>shape ≡ knife<span class="ot">)</span> × Condiment<span class="ot">)</span></span></code></pre></div>
<p>The <code>Maybe</code> type works the same as in Haskell, where the possible values of <code>Maybe a</code> are:</p>
<ul>
<li><code>nothing</code>, or</li>
<li><code>just x</code>, where <code>x</code> is a value of type <code>a</code>.</li>
</ul>
<p>The part <code>(shape ≡ knife) × Condiment</code> describes a pair of values <code>(x , y)</code>, where <code>x</code> is a proof that the shape is a knife and <code>y</code> is a condiment.</p>
<p>Now, the only possible values of <code>loadedWith</code> are:</p>
<ul>
<li><code>nothing</code></li>
<li><code>just (refl knife , peanutButter)</code></li>
<li><code>just (refl knife , jelly)</code></li>
</ul>
<p><code>refl knife</code> is a proof that the shape is a knife (when it is, in fact, a knife).</p>
<p>We can make a knife loaded with peanut butter like this:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>pbKnife <span class="ot">:</span> Utensil</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>pbKnife <span class="ot">=</span> utensil knife <span class="ot">(</span>just <span class="ot">(</span>refl knife , peanutButter<span class="ot">))</span></span></code></pre></div>
<p>If we try to make a fork loaded with peanut butter, we can’t:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>pbFork <span class="ot">:</span> Utensil</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>pbFork <span class="ot">=</span> utensil fork <span class="ot">(</span>just <span class="ot">(</span>? , peanutButter<span class="ot">))</span></span></code></pre></div>
<p>Nothing fits in the question mark! We would need to provide a proof that <code>fork ≡ knife</code>, which is obviously impossible. We can only make a fork that’s clean:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>cleanFork <span class="ot">:</span> Utensil</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>cleanFork <span class="ot">=</span> utensil fork nothing</span></code></pre></div>
<h1 id="dependently-typed-actions">Dependently Typed Actions</h1>
<p>Now, for the sake of exploration, I wanted to see how far I could take this. So far, I’ve only shown implementions for static things, like sandwiches and utensils, but there’s more to the problem. In the Haskell code from <a href="./a-simple-sandwich-part-i.html">Part I</a>, there’s a function to fetch a utensil of a specified shape:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fetchUtensil ::</span> <span class="dt">UtensilShape</span> <span class="ot">-&gt;</span> <span class="dt">Utensil</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>fetchUtensil s <span class="ot">=</span> <span class="dt">Utensil</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  { shape <span class="ot">=</span> s</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  , loadedWith <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>This function takes a utensil shape and returns a clean utensil of that shape. However, the type signature of the function only says it takes a utensil shape and returns a utensil. It doesn’t specify that the returned utensil will be the right shape or that it will be clean; that’s left to the body of the function. The common approach to making sure this function is implemented correctly is to write tests for it:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">testFetchUtensil ::</span> <span class="dt">IO</span> ()</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>testFetchUtensil <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> (fetchUtensil <span class="dt">Knife</span> <span class="op">==</span> <span class="dt">Utensil</span> { shape <span class="ot">=</span> <span class="dt">Knife</span>, loadedWith <span class="ot">=</span> <span class="dt">Nothing</span> })</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> (fetchUtensil <span class="dt">Fork</span> <span class="op">==</span> <span class="dt">Utensil</span> { shape <span class="ot">=</span> <span class="dt">Fork</span>, loadedWith <span class="ot">=</span> <span class="dt">Nothing</span> })</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> (fetchUtensil <span class="dt">Spoon</span> <span class="op">==</span> <span class="dt">Utensil</span> { shape <span class="ot">=</span> <span class="dt">Spoon</span>, loadedWith <span class="ot">=</span> <span class="dt">Nothing</span> })</span></code></pre></div>
<p>Now, if we accidentally wrote <code>fetchUtensil</code> to always return a knife,</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fetchUtensil ::</span> <span class="dt">UtensilShape</span> <span class="ot">-&gt;</span> <span class="dt">Utensil</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>fetchUtensil s <span class="ot">=</span> <span class="dt">Utensil</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  { shape <span class="ot">=</span> <span class="dt">Knife</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  , loadedWith <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>our tests would catch the mistake.</p>
<p>But there’s another approach we can take. Using dependent types in Agda, we can give the function the type of “taking a utensil shape and returning a clean utensil of that shape”, just like I wanted to describe it.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>fetchUtensil</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">:</span> <span class="ot">(</span>s <span class="ot">:</span> UtensilShape<span class="ot">)</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">→</span> Σ u ꞉ Utensil , <span class="ot">(</span>shape u ≡ s<span class="ot">)</span> × is-nothing <span class="ot">(</span>loadedWith u<span class="ot">)</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>fetchUtensil s <span class="ot">=</span> utensil s nothing , refl s , refl</span></code></pre></div>
<p>What this type really says is, “take a utensil shape and return a pair of values <code>(u , p)</code> where <code>u</code> is a utensil and <code>p</code> is a proof that <code>u</code> has the given shape and is clean.” Then, the function body has no choice but to implement exactly that type. If we implement it any other way, the code won’t compile! This is the difference: having our mistakes caught during <strong>compiling</strong> versus <strong>running</strong> the code. If the function’s meaning is encoded in its type, our code <em>won’t compile</em> unless the function’s body honors that type.</p>
<p>To be clear, I’m not advocating for all programs to be written in Agda. It’s not a programming language meant for producing general purpose applications. In fact, it’s only meant for writing (mathematical) proofs. But! It’s a great tool for discovering, planning, and expressing ideas rigorously. If the kids in the <a href="https://www.youtube.com/watch?v=FN2RM-CHkuI">Exact Instructions Challenge video</a> had planned the steps to making a sandwich in Agda, they would have left no room for their dad to make mistakes. Silly dad, dependent types are for kids!</p>
<p>Just for fun, here’s the most complex part of the sandwich solution in Agda versus in Haskell. Not for the faint of heart!</p>
<p>Haskell:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">loadFrom ::</span> <span class="dt">Utensil</span> <span class="ot">-&gt;</span> <span class="dt">CondimentJar</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">Utensil</span>, <span class="dt">CondimentJar</span>)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>loadFrom _ <span class="dt">CondimentJar</span>{lid<span class="ot">=</span><span class="dt">Closed</span>} <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is closed and knife-impermeable.&quot;</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>loadFrom _ <span class="dt">CondimentJar</span>{condiment<span class="ot">=</span><span class="dt">Nothing</span>} <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is empty. How disappointing.&quot;</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>loadFrom <span class="dt">Utensil</span>{shape<span class="ot">=</span><span class="dt">Fork</span>} _ <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;Forks aren&#39;t the right shape for condiments.&quot;</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>loadFrom u cj<span class="op">@</span><span class="dt">CondimentJar</span>{condiment<span class="ot">=</span><span class="dt">Just</span> c}</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Right</span> (u { loadedWith <span class="ot">=</span> <span class="dt">Just</span> c }, cj { condiment <span class="ot">=</span> <span class="dt">Nothing</span> })</span></code></pre></div>
<p>Agda:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- A Maybe value is left unchanged if we map it to the second value of a pair and project that second value.</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Needed to prove this for part of loadFrom (following).</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>map-pr₂-pair-refl</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">:</span> <span class="ot">{</span>A B <span class="ot">:</span> Type<span class="ot">}</span> <span class="ot">{</span>b <span class="ot">:</span> B<span class="ot">}</span> <span class="ot">(</span>ma <span class="ot">:</span> Maybe A<span class="ot">)</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  <span class="ot">→</span> ma ≡ map pr₂ <span class="ot">(</span>map <span class="ot">(λ</span> <span class="ot">(</span>a <span class="ot">:</span> A<span class="ot">)</span> <span class="ot">→</span> <span class="ot">(</span>b , a<span class="ot">))</span> ma<span class="ot">)</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>map-pr₂-pair-refl <span class="ot">{</span>A<span class="ot">}</span> <span class="ot">{</span>B<span class="ot">}</span> <span class="ot">{</span>b<span class="ot">}</span> <span class="ot">(</span>just x<span class="ot">)</span> <span class="ot">=</span> refl <span class="ot">(</span>just x<span class="ot">)</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>map-pr₂-pair-refl <span class="ot">{</span>A<span class="ot">}</span> <span class="ot">{</span>B<span class="ot">}</span> <span class="ot">{</span>b<span class="ot">}</span> nothing <span class="ot">=</span> refl nothing</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- Load a clean knife with a condiment from a jar that is open and full.</span></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- Take a utensil that is a knife and clean.</span></span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a><span class="co">-- Take a condiment jar that is full and open.</span></span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a><span class="co">-- Return the knife, now loaded with the condiment from the jar,</span></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a><span class="co">--   and the condiment jar, still open but now empty.</span></span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a>loadFrom</span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a>  <span class="ot">:</span> <span class="ot">(</span>uₛ <span class="ot">:</span> Σ u ꞉ Utensil , <span class="ot">(</span>shape u ≡ knife<span class="ot">)</span> × is-nothing <span class="ot">(</span>loadedWith u<span class="ot">))</span></span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a>    <span class="ot">(</span>cjₛ <span class="ot">:</span> Σ cj ꞉ CondimentJar , is-just <span class="ot">(</span>condiment cj<span class="ot">)</span> × <span class="ot">(</span>state cj ≡ open&#39;<span class="ot">))</span></span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a>  <span class="ot">→</span> Σ <span class="ot">(</span>u&#39; , cj&#39;<span class="ot">)</span> ꞉ Utensil × CondimentJar</span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a>    , <span class="ot">(</span>shape u&#39; ≡ shape <span class="ot">(</span>pr₁ uₛ<span class="ot">))</span> <span class="co">-- Same shape (*the* knife)</span></span>
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true" tabindex="-1"></a>      × <span class="ot">(</span>condiment <span class="ot">(</span>pr₁ cjₛ<span class="ot">)</span> ≡ map pr₂ <span class="ot">(</span>loadedWith u&#39;<span class="ot">))</span> <span class="co">-- Loaded with condiment from jar</span></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true" tabindex="-1"></a>      × <span class="ot">(</span>state cj&#39; ≡ state <span class="ot">(</span>pr₁ cjₛ<span class="ot">))</span> <span class="co">-- State unchanged (still open)</span></span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true" tabindex="-1"></a>      × is-nothing <span class="ot">(</span>condiment cj&#39;<span class="ot">)</span> <span class="co">-- Now empty</span></span>
<span id="cb17-22"><a href="#cb17-22" aria-hidden="true" tabindex="-1"></a>loadFrom</span>
<span id="cb17-23"><a href="#cb17-23" aria-hidden="true" tabindex="-1"></a>  <span class="ot">(</span>u , isKnife , notLoaded<span class="ot">)</span></span>
<span id="cb17-24"><a href="#cb17-24" aria-hidden="true" tabindex="-1"></a>  <span class="ot">(</span>cj , isFull , isOpen<span class="ot">)</span></span>
<span id="cb17-25"><a href="#cb17-25" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="ot">(</span><span class="kw">record</span> u <span class="ot">{</span> loadedWith <span class="ot">=</span> loadedWith&#39; <span class="ot">}</span> , <span class="kw">record</span> cj <span class="ot">{</span> condiment <span class="ot">=</span> nothing <span class="ot">})</span></span>
<span id="cb17-26"><a href="#cb17-26" aria-hidden="true" tabindex="-1"></a>    , refl <span class="ot">(</span>shape u<span class="ot">)</span> , isLoaded&#39; , refl <span class="ot">(</span>state cj<span class="ot">)</span> , refl</span>
<span id="cb17-27"><a href="#cb17-27" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb17-28"><a href="#cb17-28" aria-hidden="true" tabindex="-1"></a>  loadedWith&#39; <span class="ot">:</span> Maybe <span class="ot">((</span>shape u ≡ knife<span class="ot">)</span> × Condiment<span class="ot">)</span></span>
<span id="cb17-29"><a href="#cb17-29" aria-hidden="true" tabindex="-1"></a>  loadedWith&#39; <span class="ot">=</span> map <span class="ot">(λ</span> x <span class="ot">→</span> <span class="ot">(</span>isKnife , x<span class="ot">))</span> <span class="ot">(</span>condiment cj<span class="ot">)</span></span>
<span id="cb17-30"><a href="#cb17-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-31"><a href="#cb17-31" aria-hidden="true" tabindex="-1"></a>  isLoaded&#39; <span class="ot">:</span> condiment cj ≡ map pr₂ loadedWith&#39;</span>
<span id="cb17-32"><a href="#cb17-32" aria-hidden="true" tabindex="-1"></a>  isLoaded&#39; <span class="ot">=</span> map-pr₂-pair-refl <span class="ot">(</span>condiment cj<span class="ot">)</span></span></code></pre></div>
<h1 id="making-a-sandwich">Making a Sandwich</h1>
<p>Now that I’ve shown how static things and actions can be written in Agda, how about using these individual parts together to make a sandwich? Remember, the main goal of this whole exercise is to demonstrate what it would be like to program a computer to make a sandwich (without ending up with a real sandwich being squeezed out the USB port).</p>
<p>I’m going to show a few examples of attempts at making a sandwich and how mistakes are caught. To be clear, a failed attempt doesn’t mean something is wrong with the functions for making sandwiches; it’s the opposite! It’s showing how the code forces us to make proper sandwiches. In each of these attempts, I’m going to mock getting items from the kitchen by invoking fetching functions like <code>fetchUtensil</code>, but it should be understood that any method of creating a value of a certain type equates to fetching it in the real world (things don’t magically come into existence).</p>
<h2 id="attempt-1-forgot-to-open-the-jar-of-peanut-butter">Attempt 1: Forgot to open the jar of peanut butter</h2>
<p>This attempt didn’t result in a completed sandwich because we forgot to open the jar of peanut butter.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>sandwichAttempt1 <span class="ot">:</span> Sandwich</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>sandwichAttempt1 <span class="ot">=</span> <span class="ot">{!!}</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Get a knife with peanut butter.</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>  step1 <span class="ot">:</span> Σ <span class="ot">_</span> ꞉ Utensil × CondimentJar , <span class="ot">_</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  step1 <span class="ot">=</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>      newKnife <span class="ot">:</span> Utensil</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>      newKnife <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchUtensil knife<span class="ot">)</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>      pb <span class="ot">:</span> CondimentJar</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>      pb <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchCondimentJar peanutButter<span class="ot">)</span></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- Not possible because the pb jar isn&#39;t open!</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span> loadFrom <span class="ot">(</span>newKnife , <span class="ot">(</span>refl knife , refl<span class="ot">))</span> <span class="ot">(</span>pb , <span class="ot">((</span>peanutButter , refl<span class="ot">)</span> , <span class="ot">{!!}))</span> <span class="co">-- closed ≡ open&#39;</span></span></code></pre></div>
<p>In Agda, <code>{!!}</code> denotes a hole to be filled with some value of the expected type. When writing Agda code, it’s typical to have lots of holes, and the goal is to fill them all with appropriate types (and with interactive assistance of Agda, which is really cool!). The first hole, in <code>sandwichAttempt1 = {!!}</code> is expecting a value of type <code>Sandwich</code>. Since this is a failed attempt at making a sandwich, this hole will be left unfilled. The real evidence that this attempt isn’t going to work is on the last line:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>loadFrom <span class="ot">(</span>newKnife , <span class="ot">(</span>refl knife , refl<span class="ot">))</span> <span class="ot">(</span>pb , <span class="ot">((</span>peanutButter , refl<span class="ot">)</span> , <span class="ot">{!!}))</span></span></code></pre></div>
<p>The hole at the end of that line is expecting a value of the type <code>closed ≡ open'</code>, meaning a proof that <code>closed</code> is the same as <code>open</code>. It’s expecting this type because <code>loadFrom</code> takes an open condiment jar as its second argument and we’ve given it a closed one, <code>pb</code>. Obviously, we can’t supply a proof that the given jar is open because it’s not! So this hole <em>must</em> remain unfilled, and we’ll stay hungry.</p>
<h2 id="attempt-2-tried-to-make-a-sandwich-without-condiments">Attempt 2: Tried to make a sandwich without condiments</h2>
<div class="sourceCode" id="cb20"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>sandwichAttempt2 <span class="ot">:</span> Sandwich</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>sandwichAttempt2 <span class="ot">=</span> sandwich topSlice&#39; bottomSlice&#39; <span class="ot">(</span>refl , refl , <span class="ot">{!!})</span> <span class="ot">(</span><span class="dv">1</span> , ⋆<span class="ot">)</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Get a knife with peanut butter.</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>  step1 <span class="ot">:</span> Σ <span class="ot">_</span> ꞉ Utensil × CondimentJar , <span class="ot">_</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>  step1 <span class="ot">=</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>      newKnife <span class="ot">:</span> Utensil</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>      newKnife <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchUtensil knife<span class="ot">)</span></span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>      pb <span class="ot">:</span> CondimentJar</span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>      pb <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchCondimentJar peanutButter<span class="ot">)</span></span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span> loadFrom <span class="ot">(</span>newKnife , <span class="ot">(</span>refl knife , refl<span class="ot">))</span> <span class="ot">(</span>pr₁ <span class="ot">(</span>openJar pb<span class="ot">)</span> , <span class="ot">((</span>peanutButter , refl<span class="ot">)</span> , refl open&#39;<span class="ot">))</span></span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Get a couple slices of bread.</span></span>
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a>  topSlice&#39; <span class="ot">:</span> SliceOfBread</span>
<span id="cb20-16"><a href="#cb20-16" aria-hidden="true" tabindex="-1"></a>  topSlice&#39; <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchSliceOfBread wholeGrain<span class="ot">)</span></span>
<span id="cb20-17"><a href="#cb20-17" aria-hidden="true" tabindex="-1"></a>  bottomSlice&#39; <span class="ot">:</span> SliceOfBread</span>
<span id="cb20-18"><a href="#cb20-18" aria-hidden="true" tabindex="-1"></a>  bottomSlice&#39; <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchSliceOfBread sourdough<span class="ot">)</span></span></code></pre></div>
<p>This time, we got closer to making a proper sandwich! In <code>step1</code>, we got a knife and loaded it with peanut butter from a jar. Then, we got a couple slices of bread. We didn’t bother to use our knife or spread any condiments on either slice; we just left them plain. When we tried to make a sandwich out of these plain slices, we ended up with a hole:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>sandwich topSlice&#39; bottomSlice&#39; <span class="ot">(</span>refl , refl , <span class="ot">{!!})</span> <span class="ot">(</span><span class="dv">1</span> , ⋆<span class="ot">)</span></span></code></pre></div>
<p>This hole is expecting a value of the type <code>is-just (smearedBottom topSlice') ∔ is-just (smearedTop bottomSlice')</code>, which means a proof that the top slice is smeared on its bottom or the bottom slice is smeared on its top. Since our slices are plain, we can’t provide that!</p>
<h2 id="attempt-3-successful-sandwich-making">Attempt 3: Successful sandwich making!</h2>
<p>Okay, this is a long one. Hey, it takes a lot of work to make a proper sandwich!</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>sandwichAttempt3 <span class="ot">:</span> Sandwich</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>sandwichAttempt3 <span class="ot">=</span> sandwich topSliceWithJelly bottomSliceWithPB <span class="ot">(</span>refl , <span class="ot">(</span>refl , inl <span class="ot">(</span>jelly , refl<span class="ot">)))</span> <span class="ot">(</span><span class="dv">1</span> , ⋆<span class="ot">)</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Get a knife with peanut butter.</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>  step1 <span class="ot">:</span> Σ <span class="ot">_</span> ꞉ Utensil × CondimentJar , <span class="ot">_</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>  step1 <span class="ot">=</span></span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span></span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>      newKnife <span class="ot">:</span> Utensil</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>      newKnife <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchUtensil knife<span class="ot">)</span></span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>      pb <span class="ot">:</span> CondimentJar</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>      pb <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchCondimentJar peanutButter<span class="ot">)</span></span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span> loadFrom <span class="ot">(</span>newKnife , refl knife , refl<span class="ot">)</span> <span class="ot">(</span>pr₁ <span class="ot">(</span>openJar pb<span class="ot">)</span> , <span class="ot">(</span>peanutButter , refl<span class="ot">)</span> , refl open&#39;<span class="ot">)</span></span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Get a slice of bread and smear it with the PB knife.</span></span>
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a>  step2 <span class="ot">:</span> Σ <span class="ot">_</span> ꞉ SliceOfBread × Utensil , <span class="ot">_</span></span>
<span id="cb22-16"><a href="#cb22-16" aria-hidden="true" tabindex="-1"></a>  step2 <span class="ot">=</span></span>
<span id="cb22-17"><a href="#cb22-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span></span>
<span id="cb22-18"><a href="#cb22-18" aria-hidden="true" tabindex="-1"></a>      bottomSlice <span class="ot">:</span> SliceOfBread</span>
<span id="cb22-19"><a href="#cb22-19" aria-hidden="true" tabindex="-1"></a>      bottomSlice <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchSliceOfBread sourdough<span class="ot">)</span></span>
<span id="cb22-20"><a href="#cb22-20" aria-hidden="true" tabindex="-1"></a>      pbKnife <span class="ot">:</span> Utensil</span>
<span id="cb22-21"><a href="#cb22-21" aria-hidden="true" tabindex="-1"></a>      pbKnife <span class="ot">=</span> pr₁ <span class="ot">(</span>pr₁ step1<span class="ot">)</span></span>
<span id="cb22-22"><a href="#cb22-22" aria-hidden="true" tabindex="-1"></a>      emptyPB <span class="ot">:</span> CondimentJar</span>
<span id="cb22-23"><a href="#cb22-23" aria-hidden="true" tabindex="-1"></a>      emptyPB <span class="ot">=</span> pr₂ <span class="ot">(</span>pr₁ step1<span class="ot">)</span></span>
<span id="cb22-24"><a href="#cb22-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb22-25"><a href="#cb22-25" aria-hidden="true" tabindex="-1"></a>      smearSliceOfBread</span>
<span id="cb22-26"><a href="#cb22-26" aria-hidden="true" tabindex="-1"></a>      <span class="ot">(</span>pbKnife , <span class="ot">(</span>refl <span class="ot">(</span>shape pbKnife<span class="ot">))</span> , <span class="ot">((</span>refl <span class="ot">(</span>shape pbKnife<span class="ot">))</span> , peanutButter<span class="ot">)</span> , refl<span class="ot">)</span></span>
<span id="cb22-27"><a href="#cb22-27" aria-hidden="true" tabindex="-1"></a>      top</span>
<span id="cb22-28"><a href="#cb22-28" aria-hidden="true" tabindex="-1"></a>      <span class="ot">(</span>bottomSlice , <span class="ot">(</span>inl <span class="ot">(</span>refl top , refl<span class="ot">)))</span></span>
<span id="cb22-29"><a href="#cb22-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-30"><a href="#cb22-30" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Our successfuly smeared slice to be used as the bottom of the sandwich!</span></span>
<span id="cb22-31"><a href="#cb22-31" aria-hidden="true" tabindex="-1"></a>  bottomSliceWithPB <span class="ot">:</span> SliceOfBread</span>
<span id="cb22-32"><a href="#cb22-32" aria-hidden="true" tabindex="-1"></a>  bottomSliceWithPB <span class="ot">=</span> pr₁ <span class="ot">(</span>pr₁ step2<span class="ot">)</span></span>
<span id="cb22-33"><a href="#cb22-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-34"><a href="#cb22-34" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Get another slice of bread and smear it with jelly, using the same knife as before.</span></span>
<span id="cb22-35"><a href="#cb22-35" aria-hidden="true" tabindex="-1"></a>  step3 <span class="ot">:</span> Σ <span class="ot">_</span> ꞉ SliceOfBread × Utensil , <span class="ot">_</span></span>
<span id="cb22-36"><a href="#cb22-36" aria-hidden="true" tabindex="-1"></a>  step3 <span class="ot">=</span></span>
<span id="cb22-37"><a href="#cb22-37" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span></span>
<span id="cb22-38"><a href="#cb22-38" aria-hidden="true" tabindex="-1"></a>      jellyKnife <span class="ot">:</span> Utensil</span>
<span id="cb22-39"><a href="#cb22-39" aria-hidden="true" tabindex="-1"></a>      jellyKnife <span class="ot">=</span></span>
<span id="cb22-40"><a href="#cb22-40" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span></span>
<span id="cb22-41"><a href="#cb22-41" aria-hidden="true" tabindex="-1"></a>          <span class="co">-- The knife is now clean after having spread all its peanut butter on the other slice.</span></span>
<span id="cb22-42"><a href="#cb22-42" aria-hidden="true" tabindex="-1"></a>          usedKnife <span class="ot">:</span> Utensil</span>
<span id="cb22-43"><a href="#cb22-43" aria-hidden="true" tabindex="-1"></a>          usedKnife <span class="ot">=</span> pr₂ <span class="ot">(</span>pr₁ step2<span class="ot">)</span></span>
<span id="cb22-44"><a href="#cb22-44" aria-hidden="true" tabindex="-1"></a>          j <span class="ot">:</span> CondimentJar</span>
<span id="cb22-45"><a href="#cb22-45" aria-hidden="true" tabindex="-1"></a>          j <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchCondimentJar jelly<span class="ot">)</span></span>
<span id="cb22-46"><a href="#cb22-46" aria-hidden="true" tabindex="-1"></a>        <span class="kw">in</span> pr₁ <span class="ot">(</span>pr₁ <span class="ot">(</span>loadFrom <span class="ot">(</span>usedKnife , <span class="ot">(</span>refl knife , refl<span class="ot">))</span> <span class="ot">(</span>pr₁ <span class="ot">(</span>openJar j<span class="ot">)</span> , <span class="ot">(</span>jelly , refl<span class="ot">)</span> , refl open&#39;<span class="ot">)))</span></span>
<span id="cb22-47"><a href="#cb22-47" aria-hidden="true" tabindex="-1"></a>      topSlice <span class="ot">:</span> SliceOfBread</span>
<span id="cb22-48"><a href="#cb22-48" aria-hidden="true" tabindex="-1"></a>      topSlice <span class="ot">=</span> pr₁ <span class="ot">(</span>fetchSliceOfBread wholeGrain<span class="ot">)</span></span>
<span id="cb22-49"><a href="#cb22-49" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb22-50"><a href="#cb22-50" aria-hidden="true" tabindex="-1"></a>      smearSliceOfBread</span>
<span id="cb22-51"><a href="#cb22-51" aria-hidden="true" tabindex="-1"></a>      <span class="ot">(</span>jellyKnife , <span class="ot">(</span>refl knife , <span class="ot">(</span>refl knife , jelly<span class="ot">)</span> , refl<span class="ot">))</span></span>
<span id="cb22-52"><a href="#cb22-52" aria-hidden="true" tabindex="-1"></a>      bottom</span>
<span id="cb22-53"><a href="#cb22-53" aria-hidden="true" tabindex="-1"></a>      <span class="ot">(</span>topSlice , <span class="ot">(</span>inr <span class="ot">(</span>refl bottom , refl<span class="ot">)))</span></span>
<span id="cb22-54"><a href="#cb22-54" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-55"><a href="#cb22-55" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Our successfully smeared slice to be used as the top of the sandwich!</span></span>
<span id="cb22-56"><a href="#cb22-56" aria-hidden="true" tabindex="-1"></a>  topSliceWithJelly <span class="ot">:</span> SliceOfBread</span>
<span id="cb22-57"><a href="#cb22-57" aria-hidden="true" tabindex="-1"></a>  topSliceWithJelly <span class="ot">=</span> pr₁ <span class="ot">(</span>pr₁ step3<span class="ot">)</span></span></code></pre></div>
<p>I broke it down into steps (<code>step1</code>, <code>step2</code>, <code>step3</code>) so it’s a bit easier to follow. The important part is we have our sandwich:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>sandwich topSliceWithJelly bottomSliceWithPB <span class="ot">(</span>refl , <span class="ot">(</span>refl , inl <span class="ot">(</span>jelly , refl<span class="ot">)))</span> <span class="ot">(</span><span class="dv">1</span> , ⋆<span class="ot">)</span></span></code></pre></div>
<p>It has a top slice, a bottom slice, proof that the slices are smeared appropriately, and it’s in 1 piece.</p>
<p>For most of you, it’s probably really difficult to try reading a foreign language in an unfamiliar paradigm. Don’t worry about piecing together every little bit. What you should be looking at are the types of the variables and what things they refer to. For example:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>usedKnife <span class="ot">:</span> Utensil</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>usedKnife <span class="ot">=</span> pr₂ <span class="ot">(</span>pr₁ step2<span class="ot">)</span></span></code></pre></div>
<p>The first line tells us <code>usedKnife</code> is a utensil. And, in the second line, we can see it comes from <code>step2</code>, which involved a knife being used to smear a slice of bread with peanut butter, as the comment says. So, now we know <code>usedKnife</code> is not just any utensil, but a knife, and the one we used previously.</p>
<p>See the full code on GitHub: <a href="https://github.com/SlimTim10/simple-sandwich">https://github.com/SlimTim10/simple-sandwich</a></p>
<h1 id="conclusion">Conclusion</h1>
<p>I hope you enjoyed this exploration with me! <a href="./contact.html">Send me a message</a> if you have any comments or feedback. I love to chat about this stuff! Many thanks to <a href="https://neckdeep.dev/">Danny</a> for sparking this idea and sharing the journey. Go check out his blog, it’s a real treat to read.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>There have been attempts to extend Haskell’s type system, but they’re very hacky and ugly compared to Agda. It’s still <a href="https://serokell.io/blog/why-dependent-haskell">being worked on</a>, but it’s not quite there yet.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Tue, 17 Jan 2023 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/a-simple-sandwich-part-ii.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>A Simple Sandwich, Part I</title>
    <link>https://timjohns.ca/a-simple-sandwich-part-i.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        A Simple Sandwich, Part I
      </h1>
      <p class="writing">Dec 28, 2022</p>
      
    </header>
	<img class="post-image" alt="Drawing of a sandwich" src="./images/blog/a_simple_sandwich_i.png" />
    <section class="content writing">
	  <p>I wrote this as a sort of response to <a href="https://neckdeep.dev/blog/2022-12-13-a-simple-sandwich-i/">a post by my friend Danny Fekete</a>. For any of this to make sense, you’ll want to read his post first. These are my thoughts related to the ideas Danny brought up as well as Haskell code inspired by Danny’s Ruby code. I would describe the subject as <strong>programming philosophy</strong>.</p>
<h1 id="food-for-thought">Food for Thought</h1>
<p>The point of the “exact instructions challenge” shown in <a href="https://www.youtube.com/watch?v=FN2RM-CHkuI">this video</a> is to explain to kids (or any non-programmers) what it’s like to write a computer program to solve a task. I used to think this was a good explanation, but now I’ve changed my mind. What’s being said is that giving a computer instructions to solve a task is challenging because you need to be very precise. The computer is dumb and won’t fill in the gaps; it will not necessarily do what you have in mind if you give it vague instructions. Instead, it does the wrong thing or produces an error. So let’s think about this. Why is it different from giving a human vague instructions? Well, a human can fill in the blanks. Why? Because they have the same context as the instruction-giver and both minds abstract the details. If a human did not have the proper context, they would do the task wrong, like the dad in the video. So, the dad is not acting specifically like a computer but rather any receiver with improper context that is attempting the task anyway. Realistically, if a computer has improper context to perform an instruction, it will produce an error rather than try to do it and fail. In whatever programming language you choose, if you try to run the function <code>makeSandwich</code> and that function doesn’t exist, it will produce an error instead of trying to make a sandwich (whatever it means for a computer to make a sandwich…).</p>
<p>So really, what we’re talking about here is <strong>context</strong> and <strong>abstraction</strong>, not necessarily humans vs computers. Now you think I’m being pedantic. True, computers are usually the ones with less context and can’t do abstraction on their own. But programmers are the ones deciding what context is needed! If a language is made at a higher level of abstraction than another, it may need less context than the other to accomplish the same task. For example, in Haskell, I can write <code>putStrLn (unwords ["Hello,", "world!"])</code> to print “Hello, world!”, but in C, I would have to write a lot more code (giving more context about how to make an array into a sentence of words). The fact is, no programmer writes code <strong>from scratch</strong>. Everyone is building upon other work, even if you’re including the language’s standard library. In fact, if I take the effort to write the <code>unwords</code> function in C, then the resulting code is not too different from Haskell: <code>printf("%s", unwords((char**){"Hello,", "world!"}, 2));</code>.</p>
<p>In the end, if someone (it doesn’t matter who) has made a <code>makeSandwich</code> function and it makes a sandwich (somehow…), I can tell the computer to run that function and I don’t need to give it extra information. The same as telling a human who I trust to make a sandwich, “make me a sandwich”.</p>
<p>Now that we have sophisticated AI (demonstrated by tools like <a href="https://openai.com/blog/chatgpt/">ChatGPT</a>), computers actually have as much context as the average person for many problems. The AI can do spoken language processing that appears to be on par with humans. I can give it a problem to solve, written in plain English, and it will give a solution! Many people would be fooled into thinking they’re chatting with a human.</p>
<h1 id="programming-a-sandwich">Programming a Sandwich</h1>
<p>That said, let’s say we want to demonstrate what it would be like to program the computer to make a sandwich anyway. In <a href="https://neckdeep.dev/blog/2022-12-13-a-simple-sandwich-i/">Danny’s post</a>, he wrote a great, complete example in Ruby code. After reading through it, it brings up some interesting points to talk about:</p>
<ul>
<li>Error handling</li>
<li>Mutability and state</li>
<li>Programming paradigms (object-oriented programming, functional programming)</li>
<li>Type theory</li>
</ul>
<p>Fortunately for me, Danny already handled the hardest part: deciding what functionality to include in the sandwich-making code. After all, we can’t expect the computer to make a real sandwich in the end, so one has to (somewhat arbitrarily) decide what a valid solution requires.</p>
<p>For my own exploration, I decided to take the following steps:</p>
<ul>
<li>Translate Danny’s OOP (object-oriented programming) solution into Haskell</li>
<li>Write an idiomatic Haskell solution</li>
<li>Write a Haskell solution using type-level programming</li>
<li>Write an Agda solution</li>
</ul>
<p>Before getting to the code, I want to express some thoughts about programming concepts.</p>
<h1 id="error-handling">Error Handling</h1>
<p>Deciding how to handle errors is a notoriously tricky problem in programming. We have to think about what kind of errors our code may encounter. Are they logic-breaking errors, in which case we want our app to print a message and quit running when it encounters one? Or are they more like warnings, where we can print a message to the user and allow the code to continue running? Should we even handle them at all or just let the program break when it may? Maybe we should mix and match? Can we reduce the possible errors some other way?</p>
<p>Before I could write any Haskell solution to the sandwich-making problem, I had to decide how to handle errors. After all, many things can go wrong along the way, like attempting to put a knife in a closed jar of peanut butter.</p>
<p>Because Haskell is a purely functional language, every function is considered either to be “pure” or in a monad (such as “IO”). Using the monad concept is how Haskell gets around the “impure” or “side effect” capability while retaining a pure mathematical foundation. It is favourable to keep as many functions pure as possible, so handling errors in a pure way would be ideal.</p>
<h2 id="breaking-errors">Breaking errors</h2>
<p>One option to handle errors is to simply break execution and print an error message whenever one happens. In Haskell, this would be done using the built-in <code>error</code> function, which can be used in any function. But this comes with caveats:</p>
<ul>
<li>We can’t know which functions may produce an error by looking at their type signature.</li>
<li>We can’t recover from errors.</li>
</ul>
<h2 id="exceptions">Exceptions</h2>
<p>Another option is to throw exceptions. Then we can catch errors, but it comes with a big caveat:</p>
<ul>
<li>Every function that may throw an exception (or include another function that may throw an exception) must be in the IO monad. That means virtually all the code has to live in the IO monad, and we don’t have any pure functions.</li>
</ul>
<h2 id="maybe">Maybe</h2>
<p>A more idiomatic option in Haskell is to use the <code>Maybe</code> type. Any function that might produce an error returns a <code>Maybe a</code> value, which is either <code>Nothing</code> or <code>Just a</code>, where <code>a</code> is any type. For example,</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">relinquishContents ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Jar</span>, <span class="dt">Condiment</span>)</span></code></pre></div>
<p>This version of <code>relinquishContents</code> takes a <code>Jar</code> and returns either <code>Nothing</code> if it fails (because the jar is closed or empty) or a pair <code>(Jar, Condiment)</code> of a new empty <code>Jar</code> and a <code>Condiment</code>. The problem with using <code>Maybe</code> is we don’t have any message attached to the error side; we just have <code>Nothing</code>. So we know something went wrong, but we don’t know what it is.</p>
<h2 id="either">Either</h2>
<p>Finally, the solution I settled on is the other idiomatic option in Haskell: the <code>Either</code> type. It’s almost the same as <code>Maybe</code>, except its values are <code>Left a</code> and <code>Right b</code>, where <code>a</code> and <code>b</code> are any types. This way, we have,</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">relinquishContents ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">Jar</span>, <span class="dt">Condiment</span>)</span></code></pre></div>
<p>In the error case, <code>relinquishContents</code> returns a <code>Left String</code> (such as <code>Left "The jar is closed and knife-impermeable."</code>). In the good case, it returns a <code>Right (Jar, Condiment)</code>. In other words, we <strong>either</strong> have an error message or a good return value.</p>
<p>Taking this path, every function that might produce an error must return an <code>Either</code> type, which allows us to keep most of the code pure. Also, we have no choice but to write code which handles the errors where they may occur. We can’t simply skip over the fact that a function may produce an error; we have to handle both sides of the result: <code>Left</code> and <code>Right</code>.</p>
<h1 id="mutability-and-state">Mutability and State</h1>
<p>In <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">OOP</a>, it’s common to make an instance of an object with some properties and then mutate its properties along the way. For example, we may have a <code>CondimentJar</code> with a <code>contents</code> property that starts off as some string, like “Peanut Butter”. When we want to empty the jar, we set its <code>contents</code> property to <code>nil</code>, effectively <strong>mutating the state</strong> of the jar.</p>
<p>This can often make code easy to write but harder to follow. For example, in the <a href="https://neckdeep.dev/blog/2022-12-13-a-simple-sandwich-i/">Ruby solution’s</a> <code>Sandwich</code> class, I didn’t know what the <code>build!</code> method was going to do when I first saw it. Based on the name, I figured it would build a sandwich and mutate the instance somehow. I didn’t know if it would also mutate something inside the sandwich, like the slices of bread. Without reading the rest of the code, how could I know what other variables might get mutated down the line? To discover the function’s purpose and result, I had to read its entire body. In Haskell, I only need to read a function’s type signature to know exactly what its capabilities are.</p>
<p>In pure functional code, there’s no such thing as mutability. When we have a <code>CondimentJar</code> with its <code>contents</code> set to “Peanut Butter”, we can’t simply change that jar. It will always have peanut butter as its contents. Instead of mutating the jar’s state, we must make a new jar which is a copy of the first one, but with its <code>contents</code> set to a different value.</p>
<p>To people less familiar with the concept of immutability, this may seem like a burden, and sometimes it is! But really, it’s just a different perspective on writing code. Instead of keeping track of every variable and its current state at any point in the code, immutability ensures that no variables can ever change, so we can easily discern their value.</p>
<p>Now, this presents us with a philosophical problem in the sandwich-making context. What sense does it make to have a jar which is always full of peanut butter and a knife which is always clean, and when we put them to use we have a <strong>new</strong> empty jar and a <strong>new</strong> loaded knife? And does it make sense that we still have access to the old objects? The way I see it, we can think of this in different ways.</p>
<p>In one way, we can say we simply don’t care that it doesn’t represent the real world accurately and as long as we don’t make use of the old objects after we use them, we’re not doing anything we couldn’t do in reality. We just have to always use the latest version of each object.</p>
<p>Another way to think about it is that having access to the old objects is like being able to travel through time. We can think of every variable as being in a particular snapshot of the universe, which we can always go back to. However, this idea breaks down when we can access a new object and its older counterpart simultaneously, which is kind of like having multiple universes that can interact (like the <a href="https://en.wikipedia.org/wiki/Multiverse_(Marvel_Comics)">Marvel multiverse</a>).</p>
<p>The most accurate representation of state in a pure functional context is to keep all stateful things in a variable that must be passed as an argument to any function that may update state. This is like passing around the universe (or at least, the important things in it) so we only have access to one version of it at any point in time. In Haskell, there are <a href="https://hackage.haskell.org/package/base-4.17.0.0/docs/Control-Concurrent-MVar.html">libraries</a> which handle this in a monad. Then we can write code which looks like we’re updating state, but anything that involves state must be inside the state monad.</p>
<p>In my code, I opted for the first approach; simply ignore the problem! I figure the sandwich-making is represented well enough and the code is simpler to understand.</p>
<h1 id="haskell-solution---oop-translation">Haskell Solution - OOP Translation</h1>
<p>Since Haskell is a functional language, the following Haskell code is <strong>not idiomatic</strong>. It is a translation of the object-oriented <a href="https://neckdeep.dev/blog/2022-12-13-a-simple-sandwich-i/">Ruby solution</a>. Similarly to how we might translate a poem from Portuguese to English word-for-word, the result may have proper grammar and spelling, but the English translation won’t sound poetic like it would if it were composed in English from the start.</p>
<h2 id="condimenths">Condiment.hs</h2>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Condiment</span> <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Condiment</span> <span class="ot">=</span> <span class="dt">String</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">OpenOrClosed</span> <span class="ot">=</span> <span class="dt">Open</span> <span class="op">|</span> <span class="dt">Closed</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Eq</span>)</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Jar</span> <span class="ot">=</span> <span class="dt">Jar</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> contents ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> lid ::</span> <span class="dt">OpenOrClosed</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="ot">newJar ::</span> <span class="dt">Condiment</span> <span class="ot">-&gt;</span> <span class="dt">Jar</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>newJar c <span class="ot">=</span> <span class="dt">Jar</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>  { contents <span class="ot">=</span> <span class="dt">Just</span> c</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>  , lid <span class="ot">=</span> <span class="dt">Closed</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a><span class="ot">isEmpty ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>isEmpty <span class="dt">Jar</span>{contents<span class="ot">=</span><span class="dt">Nothing</span>} <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>isEmpty _ <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a><span class="ot">hasStuff ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>hasStuff <span class="ot">=</span> <span class="fu">not</span> <span class="op">.</span> isEmpty</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a><span class="ot">isClosed ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>isClosed <span class="dt">Jar</span>{lid<span class="ot">=</span><span class="dt">Closed</span>} <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>isClosed _ <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a><span class="ot">closeJar ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Jar</span></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a>closeJar cj <span class="ot">=</span> cj {lid<span class="ot">=</span><span class="dt">Closed</span>}</span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a><span class="ot">isOpen ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a>isOpen <span class="ot">=</span> <span class="fu">not</span> <span class="op">.</span> isClosed</span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a><span class="ot">openJar ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Jar</span></span>
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true" tabindex="-1"></a>openJar cj <span class="ot">=</span> cj {lid<span class="ot">=</span><span class="dt">Open</span>}</span>
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-39"><a href="#cb3-39" aria-hidden="true" tabindex="-1"></a><span class="ot">relinquishContents ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">Jar</span>, <span class="dt">Condiment</span>)</span>
<span id="cb3-40"><a href="#cb3-40" aria-hidden="true" tabindex="-1"></a>relinquishContents cj<span class="op">@</span><span class="dt">Jar</span>{contents<span class="ot">=</span><span class="dt">Just</span> c}</span>
<span id="cb3-41"><a href="#cb3-41" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> isClosed cj <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is closed and knife-impermeable.&quot;</span></span>
<span id="cb3-42"><a href="#cb3-42" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> isEmpty cj <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is empty. How disappointing.&quot;</span></span>
<span id="cb3-43"><a href="#cb3-43" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> (cj{contents<span class="ot">=</span><span class="dt">Nothing</span>}, c)</span></code></pre></div>
<p>In this OOP translation, a Haskell <strong>record</strong> is defined for each of its Ruby <strong>class</strong> counterpart. In idiomatic Haskell, records are used frequently but not to represent classes/objects in such a way. And the small functions like <code>isClosed</code> correspond to OOP <strong>methods</strong> or property accessors, which would be replaced by pattern matching in idiomatic Haskell.</p>
<p>In Condiment.hs, the <code>newJar</code> function acts like an <strong>object constructor</strong> in OOP (e.g., Ruby’s <code>initialize</code> method). It takes a <code>Condiment</code> to tell it what the contents of the jar should be and gives back a closed jar full of that condiment.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Haskell</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> pb <span class="ot">=</span> Condiment.newJar <span class="st">&quot;Peanut Butter&quot;</span></span></code></pre></div>
<div class="sourceCode" id="cb5"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Ruby</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>pb <span class="kw">=</span> <span class="dt">CondimentJar</span><span class="at">.new</span>(<span class="st">&quot;Peanut Butter&quot;</span>)</span></code></pre></div>
<p>As discussed above about error handling, <code>relinquishContents</code> returns an <code>Either</code> type which may either be an error message (<code>Left String</code>) or a pair of a new empty jar and a condiment (<code>Right (Jar, Condiment)</code>).</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">relinquishContents ::</span> <span class="dt">Jar</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">Jar</span>, <span class="dt">Condiment</span>)</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>relinquishContents cj<span class="op">@</span><span class="dt">Jar</span>{contents<span class="ot">=</span><span class="dt">Just</span> c}</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> isClosed cj <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is closed and knife-impermeable.&quot;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> isEmpty cj <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is empty. How disappointing.&quot;</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> (cj{contents<span class="ot">=</span><span class="dt">Nothing</span>}, c)</span></code></pre></div>
<h2 id="knifehs">Knife.hs</h2>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Knife</span> <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Condiment</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Knife</span> <span class="ot">=</span> <span class="dt">Knife</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> contents ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment.Condiment</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="ot">new ::</span> <span class="dt">Knife</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>new <span class="ot">=</span> <span class="dt">Knife</span> {contents<span class="ot">=</span><span class="dt">Nothing</span>}</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a><span class="ot">isClean ::</span> <span class="dt">Knife</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>isClean <span class="dt">Knife</span> {contents<span class="ot">=</span><span class="dt">Nothing</span>} <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>isClean _ <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a><span class="ot">clean ::</span> <span class="dt">Knife</span> <span class="ot">-&gt;</span> <span class="dt">Knife</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>clean k <span class="ot">=</span> k {contents<span class="ot">=</span><span class="dt">Nothing</span>}</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a><span class="ot">isLoaded ::</span> <span class="dt">Knife</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>isLoaded <span class="ot">=</span> <span class="fu">not</span> <span class="op">.</span> isClean</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a><span class="ot">loadFrom ::</span> <span class="dt">Knife</span> <span class="ot">-&gt;</span> <span class="dt">Condiment.Jar</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">Knife</span>, <span class="dt">Condiment.Jar</span>)</span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>loadFrom k cj</span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> isLoaded k <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This knife is already loaded. Don&#39;t mix your condiments!&quot;</span></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="fu">uncurry</span> load <span class="op">&lt;$&gt;</span> Condiment.relinquishContents cj</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>    load cj&#39; c <span class="ot">=</span> (k {contents<span class="ot">=</span><span class="dt">Just</span> c}, cj&#39;)</span></code></pre></div>
<p>Interesting to note here is the decision to include <code>loadFrom</code> in the Knife.hs module. It seemed right to put it here because the OOP version has <code>loadFrom</code> as a method of the <code>Knife</code> object. But in this Haskell version, <code>loadFrom</code> is a pure function that happens to take a <code>Knife</code> and a <code>Condiment.Jar</code> as two arguments, so it doesn’t need to belong in any specific module. It would work just as well to put it in Main.hs. In fact, the same could be said for any of the functions. The choice to put them in a particular module is somewhat arbitrary; it simply makes sense intuitively to bundle them together based on context. In the case of <code>loadFrom</code>, it would make just as much sense to put it in Condiment.hs or Main.hs.</p>
<h2 id="breadhs">Bread.hs</h2>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Bread</span> <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Condiment</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Knife</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Surface</span> <span class="ot">=</span> <span class="dt">Surface</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> contents ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment.Condiment</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="ot">newSurface ::</span> <span class="dt">Surface</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>newSurface <span class="ot">=</span> <span class="dt">Surface</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>  { contents <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a><span class="ot">surfaceIsPlain ::</span> <span class="dt">Surface</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>surfaceIsPlain <span class="dt">Surface</span> {contents<span class="ot">=</span><span class="dt">Nothing</span>} <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>surfaceIsPlain _ <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a><span class="ot">surfaceIsSmeared ::</span> <span class="dt">Surface</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>surfaceIsSmeared <span class="ot">=</span> <span class="fu">not</span> <span class="op">.</span> surfaceIsPlain</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Slice</span> <span class="ot">=</span> <span class="dt">Slice</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> top ::</span> <span class="dt">Surface</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> bottom ::</span> <span class="dt">Surface</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a><span class="ot">newSlice ::</span> <span class="dt">Slice</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a>newSlice <span class="ot">=</span> <span class="dt">Slice</span></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a>  { top <span class="ot">=</span> newSurface</span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a>  , bottom <span class="ot">=</span> newSurface</span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true" tabindex="-1"></a><span class="ot">sliceIsPlain ::</span> <span class="dt">Slice</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a>sliceIsPlain <span class="dt">Slice</span> {top<span class="ot">=</span>t, bottom<span class="ot">=</span>b}</span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> surfaceIsPlain t <span class="op">&amp;&amp;</span> surfaceIsPlain b</span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a><span class="ot">sliceIsSmeared ::</span> <span class="dt">Slice</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a>sliceIsSmeared <span class="ot">=</span> <span class="fu">not</span> <span class="op">.</span> sliceIsPlain</span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true" tabindex="-1"></a><span class="ot">smearSurface ::</span> <span class="dt">Knife.Knife</span> <span class="ot">-&gt;</span> <span class="dt">Surface</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">Knife.Knife</span>, <span class="dt">Surface</span>)</span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true" tabindex="-1"></a>smearSurface k s</span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> surfaceIsSmeared s <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This surface was already smeared!&quot;</span></span>
<span id="cb8-43"><a href="#cb8-43" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> Knife.isClean k <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This knife is too clean to smear with.&quot;</span></span>
<span id="cb8-44"><a href="#cb8-44" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> (Knife.clean k, s {contents<span class="ot">=</span>Knife.contents k})</span></code></pre></div>
<h2 id="sandwichhs">Sandwich.hs</h2>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Sandwich</span> <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Bread</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Condiment</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Knife</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Maybe</span> <span class="kw">as</span> <span class="dt">Maybe</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.List</span> <span class="kw">as</span> <span class="dt">L</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Sandwich</span> <span class="ot">=</span> <span class="dt">Sandwich</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> slices ::</span> [<span class="dt">Bread.Slice</span>]</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> built ::</span> <span class="dt">Bool</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> isCut ::</span> <span class="dt">Bool</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a><span class="ot">new ::</span> [<span class="dt">Bread.Slice</span>] <span class="ot">-&gt;</span> <span class="dt">Sandwich</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>new slices <span class="ot">=</span> <span class="dt">Sandwich</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>  { slices <span class="ot">=</span> slices</span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>  , built <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>  , isCut <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a><span class="ot">flavours ::</span> <span class="dt">Sandwich</span> <span class="ot">-&gt;</span> [<span class="dt">Condiment.Condiment</span>]</span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>flavours <span class="ot">=</span> <span class="fu">concat</span> <span class="op">.</span> <span class="fu">map</span> sliceFlavours <span class="op">.</span> slices</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a><span class="ot">    sliceFlavours ::</span> <span class="dt">Bread.Slice</span> <span class="ot">-&gt;</span> [<span class="dt">Condiment.Condiment</span>]</span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>    sliceFlavours <span class="ot">=</span> <span class="dt">Maybe</span><span class="op">.</span>catMaybes <span class="op">.</span> <span class="fu">map</span> Bread.contents <span class="op">.</span> <span class="fu">sequence</span> [Bread.top, Bread.bottom]</span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a><span class="ot">showFlavours ::</span> <span class="dt">Sandwich</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a>showFlavours <span class="ot">=</span> f <span class="op">.</span> flavours</span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> [<span class="dt">Condiment.Condiment</span>] <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true" tabindex="-1"></a>    f cs</span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">length</span> cs <span class="op">==</span> <span class="dv">2</span> <span class="ot">=</span> L.intercalate <span class="st">&quot; and &quot;</span> cs</span>
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> L.intercalate <span class="st">&quot;, &quot;</span> (<span class="fu">init</span> cs) <span class="op">++</span> <span class="st">&quot;, and &quot;</span> <span class="op">++</span> <span class="fu">last</span> cs</span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true" tabindex="-1"></a><span class="ot">isReadyToEat ::</span> <span class="dt">Sandwich</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true" tabindex="-1"></a>isReadyToEat sw <span class="ot">=</span> built sw <span class="op">&amp;&amp;</span> isCut sw</span>
<span id="cb9-39"><a href="#cb9-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-40"><a href="#cb9-40" aria-hidden="true" tabindex="-1"></a><span class="ot">build ::</span> <span class="dt">Sandwich</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> <span class="dt">Sandwich</span></span>
<span id="cb9-41"><a href="#cb9-41" aria-hidden="true" tabindex="-1"></a>build sw</span>
<span id="cb9-42"><a href="#cb9-42" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> built sw <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;It&#39;s already a glorious tower of food!&quot;</span></span>
<span id="cb9-43"><a href="#cb9-43" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">length</span> (slices sw) <span class="op">&lt;</span> <span class="dv">2</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;Not enough slices&quot;</span></span>
<span id="cb9-44"><a href="#cb9-44" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> outsideSmeared <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This sandwich would be icky to hold.&quot;</span></span>
<span id="cb9-45"><a href="#cb9-45" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> tooPlain <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This sandwich might actually be a loaf.&quot;</span></span>
<span id="cb9-46"><a href="#cb9-46" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> (sw {built<span class="ot">=</span><span class="dt">True</span>})</span>
<span id="cb9-47"><a href="#cb9-47" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-48"><a href="#cb9-48" aria-hidden="true" tabindex="-1"></a><span class="ot">    bottomSmeared ::</span> <span class="dt">Bool</span></span>
<span id="cb9-49"><a href="#cb9-49" aria-hidden="true" tabindex="-1"></a>    bottomSmeared <span class="ot">=</span> Bread.surfaceIsSmeared <span class="op">.</span> Bread.bottom <span class="op">.</span> <span class="fu">head</span> <span class="op">$</span> slices sw</span>
<span id="cb9-50"><a href="#cb9-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-51"><a href="#cb9-51" aria-hidden="true" tabindex="-1"></a><span class="ot">    topSmeared ::</span> <span class="dt">Bool</span></span>
<span id="cb9-52"><a href="#cb9-52" aria-hidden="true" tabindex="-1"></a>    topSmeared <span class="ot">=</span> Bread.surfaceIsSmeared <span class="op">.</span> Bread.top <span class="op">.</span> <span class="fu">last</span> <span class="op">$</span> slices sw</span>
<span id="cb9-53"><a href="#cb9-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-54"><a href="#cb9-54" aria-hidden="true" tabindex="-1"></a><span class="ot">    outsideSmeared ::</span> <span class="dt">Bool</span></span>
<span id="cb9-55"><a href="#cb9-55" aria-hidden="true" tabindex="-1"></a>    outsideSmeared <span class="ot">=</span> <span class="fu">length</span> (slices sw) <span class="op">&gt;=</span> <span class="dv">2</span> <span class="op">&amp;&amp;</span> (bottomSmeared <span class="op">||</span> topSmeared)</span>
<span id="cb9-56"><a href="#cb9-56" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-57"><a href="#cb9-57" aria-hidden="true" tabindex="-1"></a><span class="ot">    tooPlain ::</span> <span class="dt">Bool</span></span>
<span id="cb9-58"><a href="#cb9-58" aria-hidden="true" tabindex="-1"></a>    tooPlain <span class="ot">=</span> <span class="fu">any</span> Bread.sliceIsPlain <span class="op">.</span> <span class="fu">init</span> <span class="op">.</span> <span class="fu">tail</span> <span class="op">$</span> slices sw</span>
<span id="cb9-59"><a href="#cb9-59" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-60"><a href="#cb9-60" aria-hidden="true" tabindex="-1"></a><span class="ot">cut ::</span> <span class="dt">Sandwich</span> <span class="ot">-&gt;</span> <span class="dt">Knife.Knife</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> <span class="dt">Sandwich</span></span>
<span id="cb9-61"><a href="#cb9-61" aria-hidden="true" tabindex="-1"></a>cut sw k</span>
<span id="cb9-62"><a href="#cb9-62" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="fu">not</span> <span class="op">.</span> built) sw <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;Build the sandwich and then cut it in one glorious stroke.&quot;</span></span>
<span id="cb9-63"><a href="#cb9-63" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> Knife.isLoaded k <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;No! You&#39;ll get the edge all yucky with that knife.&quot;</span></span>
<span id="cb9-64"><a href="#cb9-64" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> isCut sw <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;One cut will do.&quot;</span></span>
<span id="cb9-65"><a href="#cb9-65" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> (sw {isCut<span class="ot">=</span><span class="dt">True</span>})</span></code></pre></div>
<h2 id="mainhs">Main.hs</h2>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Main</span> <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Condiment</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Knife</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Bread</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Sandwich</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> bread <span class="ot">=</span> <span class="fu">replicate</span> <span class="dv">5</span> Bread.newSlice</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> pb <span class="ot">=</span> Condiment.newJar <span class="st">&quot;Peanut Butter&quot;</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> jelly <span class="ot">=</span> Condiment.newJar <span class="st">&quot;Jelly&quot;</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> knife <span class="ot">=</span> Knife.new</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- First attempt. Didn&#39;t open the jar of peanut butter.</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>  <span class="fu">either</span> printError <span class="fu">putStrLn</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>    (pbKnife, pbEmpty) <span class="ot">&lt;-</span> knife <span class="ot">`Knife.loadFrom`</span> pb <span class="co">-- Problem</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>    (usedKnife1, surface1) <span class="ot">&lt;-</span> Bread.smearSurface pbKnife <span class="op">.</span> Bread.top <span class="op">.</span> <span class="fu">head</span> <span class="op">$</span> bread</span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>    (jellyKnife, jellyEmpty) <span class="ot">&lt;-</span> knife <span class="ot">`Knife.loadFrom`</span> Condiment.openJar jelly</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>    (usedKnife2, surface2) <span class="ot">&lt;-</span> Bread.smearSurface jellyKnife <span class="op">.</span> Bread.bottom <span class="op">.</span> <span class="fu">last</span> <span class="op">$</span> bread</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> sw <span class="ot">=</span> Sandwich.new bread</span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a>    Sandwich.build sw</span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="st">&quot;Sandwich made!&quot;</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Next attempt. Used too much bread inside.</span></span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a>  <span class="fu">either</span> printError <span class="fu">putStrLn</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a>    (pbKnife, pbEmpty) <span class="ot">&lt;-</span> knife <span class="ot">`Knife.loadFrom`</span> Condiment.openJar pb</span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a>    (usedKnife1, surface1) <span class="ot">&lt;-</span> Bread.smearSurface pbKnife <span class="op">.</span> Bread.top <span class="op">.</span> <span class="fu">head</span> <span class="op">$</span> bread</span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a>    (jellyKnife, jellyEmpty) <span class="ot">&lt;-</span> knife <span class="ot">`Knife.loadFrom`</span> Condiment.openJar jelly</span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true" tabindex="-1"></a>    (usedKnife2, surface2) <span class="ot">&lt;-</span> Bread.smearSurface jellyKnife <span class="op">.</span> Bread.bottom <span class="op">.</span> <span class="fu">last</span> <span class="op">$</span> bread</span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> sw <span class="ot">=</span> Sandwich.new bread</span>
<span id="cb10-32"><a href="#cb10-32" aria-hidden="true" tabindex="-1"></a>    Sandwich.build sw <span class="co">-- Problem</span></span>
<span id="cb10-33"><a href="#cb10-33" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="st">&quot;Sandwich made!&quot;</span></span>
<span id="cb10-34"><a href="#cb10-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-35"><a href="#cb10-35" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Successful sandwich making!</span></span>
<span id="cb10-36"><a href="#cb10-36" aria-hidden="true" tabindex="-1"></a>  <span class="fu">either</span> printError <span class="fu">putStrLn</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb10-37"><a href="#cb10-37" aria-hidden="true" tabindex="-1"></a>    (pbKnife, pbEmpty) <span class="ot">&lt;-</span> knife <span class="ot">`Knife.loadFrom`</span> Condiment.openJar pb</span>
<span id="cb10-38"><a href="#cb10-38" aria-hidden="true" tabindex="-1"></a>    (usedKnife1, surface1) <span class="ot">&lt;-</span> Bread.smearSurface pbKnife <span class="op">.</span> Bread.top <span class="op">.</span> <span class="fu">head</span> <span class="op">$</span> bread</span>
<span id="cb10-39"><a href="#cb10-39" aria-hidden="true" tabindex="-1"></a>    (jellyKnife, jellyEmpty) <span class="ot">&lt;-</span> knife <span class="ot">`Knife.loadFrom`</span> Condiment.openJar jelly</span>
<span id="cb10-40"><a href="#cb10-40" aria-hidden="true" tabindex="-1"></a>    (usedKnife2, surface2) <span class="ot">&lt;-</span> Bread.smearSurface jellyKnife <span class="op">.</span> Bread.bottom <span class="op">.</span> <span class="fu">last</span> <span class="op">$</span> bread</span>
<span id="cb10-41"><a href="#cb10-41" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> sw <span class="ot">=</span> Sandwich.new [<span class="fu">head</span> bread, <span class="fu">last</span> bread]</span>
<span id="cb10-42"><a href="#cb10-42" aria-hidden="true" tabindex="-1"></a>    Sandwich.build sw</span>
<span id="cb10-43"><a href="#cb10-43" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="st">&quot;Sandwich made!&quot;</span></span>
<span id="cb10-44"><a href="#cb10-44" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-45"><a href="#cb10-45" aria-hidden="true" tabindex="-1"></a><span class="ot">    printError ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span>
<span id="cb10-46"><a href="#cb10-46" aria-hidden="true" tabindex="-1"></a>    printError e <span class="ot">=</span> <span class="fu">putStrLn</span> (<span class="st">&quot;Error: &quot;</span> <span class="op">++</span> e)</span></code></pre></div>
<p>This module, Main.hs, is where things get more interesting. In Haskell, we always need a <code>main</code> function that lives in the IO (input/output) monad, otherwise we would never be able to see any results from running our application. The functions that return an <code>Either</code> type for errors are also used as a monad. Haskell’s <code>do</code> notation uses monadic operations which end up looking like imperative instructions. It’s really just syntactic sugar for doing things sequentially and updating context as it goes. The interesting thing is that each code block containing a sandwich-making attempt acts similarly to <code>try-catch</code> exception handling in other languages. If anything goes wrong, that is, if any function returns a <code>Left</code> value, it gets printed with “Error:” before it. If all goes right, it prints the result of the block: “Sandwich made!”.</p>
<p>Again, there’s nothing stopping us from using <code>pbKnife</code> more than once because we’re not keeping track of any state, so some care must be taken when making a sandwich.</p>
<p>In the end, I think this version is quite readable (if you know Haskell), though the modules contain more functions than needed, and the custom types are all records instead of more intuitive types, as in the following version.</p>
<h2 id="what-is-a-sandwich">What is a sandwich?</h2>
<p>Something about the <code>Sandwich</code> type (or Ruby class) doesn’t sit well with me. In my mind, it doesn’t make sense for a sandwich to have a <code>built</code> property that says whether the sandwich is built correctly or not. What would it mean to have a sandwich that is not built? That sounds like something that is <em>not</em> a sandwich, which shouldn’t be part of the definition of what a sandwich <em>is</em>. If it is possible to make an instance of a sandwich that is not a proper sandwich, maybe the type/class/definition of a sandwich needs more refining. In this definition, a sandwich is allowed to have any number of slices. Wouldn’t it make more sense for a sandwich to require at least two slices of bread? Or, even more accurately, a sandwich requires exactly two slices of bread (any inner slices of bread can be considered part of the sandwich–unless that’s all it has, in which case it is a loaf). I see it as partway to an accurate definition of a sandwich but stopped short.</p>
<h1 id="haskell-solution---idiomatic">Haskell Solution - Idiomatic</h1>
<p>In this version, I attempted a more idiomatic Haskell solution, using fewer records, more pattern matching, and more features of types.</p>
<p>I also took some liberties to reframe parts of the problem. In Danny’s code, I noticed a validation to make sure we’re using a knife where another utensil wouldn’t work.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ruby"><code class="sourceCode ruby"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="cf">def</span> smear!(knife:, surface:)</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">unless</span> knife<span class="at">.is_a?</span>(<span class="dt">Knife</span>)</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>      <span class="fu">raise</span> <span class="dt">InvalidKnifeError</span>, <span class="st">&quot;That&#39;s not hygienic.&quot;</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">end</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="co"># ...</span></span></code></pre></div>
<p>I decided if we’re going to be checking that we’re using a knife, we may as well include other utensils. Otherwise, the only kind of utensil the program knows about is a knife. In Haskell, we never need to check whether a value is of a particular type; that’s made explicit by static typing, and the compiler does the type-checking work.</p>
<p>I took a similar approach to bread. We may also include different flavours of bread to make things more interesting.</p>
<p>Because this version is idiomatic code, it’s also much shorter, so I put it all in a single module.</p>
<h2 id="mainhs-1">Main.hs</h2>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Main</span> <span class="kw">where</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">UtensilShape</span> <span class="ot">=</span> <span class="dt">Knife</span> <span class="op">|</span> <span class="dt">Spoon</span> <span class="op">|</span> <span class="dt">Fork</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>)</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Utensil</span> <span class="ot">=</span> <span class="dt">Utensil</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> uShape ::</span> <span class="dt">UtensilShape</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> uCondiment ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>)</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a><span class="ot">fetchUtensil ::</span> <span class="dt">UtensilShape</span> <span class="ot">-&gt;</span> <span class="dt">Utensil</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>fetchUtensil shape <span class="ot">=</span> <span class="dt">Utensil</span></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a>  { uShape <span class="ot">=</span> shape</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>  , uCondiment <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Condiment</span> <span class="ot">=</span> <span class="dt">PeanutButter</span> <span class="op">|</span> <span class="dt">Jelly</span></span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>)</span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">OpenOrClosed</span> <span class="ot">=</span> <span class="dt">Open</span> <span class="op">|</span> <span class="dt">Closed</span></span>
<span id="cb12-22"><a href="#cb12-22" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>)</span>
<span id="cb12-23"><a href="#cb12-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-24"><a href="#cb12-24" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">CondimentJar</span> <span class="ot">=</span> <span class="dt">CondimentJar</span></span>
<span id="cb12-25"><a href="#cb12-25" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> cjCondiment ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb12-26"><a href="#cb12-26" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> cjLid ::</span> <span class="dt">OpenOrClosed</span></span>
<span id="cb12-27"><a href="#cb12-27" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-28"><a href="#cb12-28" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>)</span>
<span id="cb12-29"><a href="#cb12-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-30"><a href="#cb12-30" aria-hidden="true" tabindex="-1"></a><span class="ot">fetchCondimentJar ::</span> <span class="dt">Condiment</span> <span class="ot">-&gt;</span> <span class="dt">CondimentJar</span></span>
<span id="cb12-31"><a href="#cb12-31" aria-hidden="true" tabindex="-1"></a>fetchCondimentJar c <span class="ot">=</span> <span class="dt">CondimentJar</span></span>
<span id="cb12-32"><a href="#cb12-32" aria-hidden="true" tabindex="-1"></a>  { cjCondiment <span class="ot">=</span> <span class="dt">Just</span> c</span>
<span id="cb12-33"><a href="#cb12-33" aria-hidden="true" tabindex="-1"></a>  , cjLid <span class="ot">=</span> <span class="dt">Closed</span></span>
<span id="cb12-34"><a href="#cb12-34" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-35"><a href="#cb12-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-36"><a href="#cb12-36" aria-hidden="true" tabindex="-1"></a><span class="ot">loadFrom ::</span> <span class="dt">Utensil</span> <span class="ot">-&gt;</span> <span class="dt">CondimentJar</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">Utensil</span>, <span class="dt">CondimentJar</span>)</span>
<span id="cb12-37"><a href="#cb12-37" aria-hidden="true" tabindex="-1"></a>loadFrom _ <span class="dt">CondimentJar</span>{cjLid<span class="ot">=</span><span class="dt">Closed</span>} <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is closed and knife-impermeable.&quot;</span></span>
<span id="cb12-38"><a href="#cb12-38" aria-hidden="true" tabindex="-1"></a>loadFrom _ <span class="dt">CondimentJar</span>{cjCondiment<span class="ot">=</span><span class="dt">Nothing</span>} <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;The jar is empty. How disappointing.&quot;</span></span>
<span id="cb12-39"><a href="#cb12-39" aria-hidden="true" tabindex="-1"></a>loadFrom <span class="dt">Utensil</span>{uShape<span class="ot">=</span><span class="dt">Fork</span>} _ <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;Forks aren&#39;t the right shape for condiments.&quot;</span></span>
<span id="cb12-40"><a href="#cb12-40" aria-hidden="true" tabindex="-1"></a>loadFrom u cj<span class="op">@</span><span class="dt">CondimentJar</span>{cjCondiment<span class="ot">=</span><span class="dt">Just</span> c}</span>
<span id="cb12-41"><a href="#cb12-41" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Right</span> (u { uCondiment <span class="ot">=</span> <span class="dt">Just</span> c }, cj { cjCondiment <span class="ot">=</span> <span class="dt">Nothing</span> })</span>
<span id="cb12-42"><a href="#cb12-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-43"><a href="#cb12-43" aria-hidden="true" tabindex="-1"></a><span class="ot">openJar ::</span> <span class="dt">CondimentJar</span> <span class="ot">-&gt;</span> <span class="dt">CondimentJar</span></span>
<span id="cb12-44"><a href="#cb12-44" aria-hidden="true" tabindex="-1"></a>openJar cj <span class="ot">=</span> cj { cjLid <span class="ot">=</span> <span class="dt">Open</span> }</span>
<span id="cb12-45"><a href="#cb12-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-46"><a href="#cb12-46" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BreadFlavour</span> <span class="ot">=</span> <span class="dt">Sourdough</span> <span class="op">|</span> <span class="dt">WholeGrain</span> <span class="op">|</span> <span class="dt">White</span></span>
<span id="cb12-47"><a href="#cb12-47" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>)</span>
<span id="cb12-48"><a href="#cb12-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-49"><a href="#cb12-49" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SliceOfBread</span> <span class="ot">=</span> <span class="dt">SliceOfBread</span></span>
<span id="cb12-50"><a href="#cb12-50" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> sobFlavour ::</span> <span class="dt">BreadFlavour</span></span>
<span id="cb12-51"><a href="#cb12-51" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> sobTop ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb12-52"><a href="#cb12-52" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> sobBottom ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb12-53"><a href="#cb12-53" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-54"><a href="#cb12-54" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>)</span>
<span id="cb12-55"><a href="#cb12-55" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-56"><a href="#cb12-56" aria-hidden="true" tabindex="-1"></a><span class="ot">fetchSliceOfBread ::</span> <span class="dt">BreadFlavour</span> <span class="ot">-&gt;</span> <span class="dt">SliceOfBread</span></span>
<span id="cb12-57"><a href="#cb12-57" aria-hidden="true" tabindex="-1"></a>fetchSliceOfBread flavour <span class="ot">=</span> <span class="dt">SliceOfBread</span></span>
<span id="cb12-58"><a href="#cb12-58" aria-hidden="true" tabindex="-1"></a>  { sobFlavour <span class="ot">=</span> flavour</span>
<span id="cb12-59"><a href="#cb12-59" aria-hidden="true" tabindex="-1"></a>  , sobTop <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb12-60"><a href="#cb12-60" aria-hidden="true" tabindex="-1"></a>  , sobBottom <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb12-61"><a href="#cb12-61" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-62"><a href="#cb12-62" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-63"><a href="#cb12-63" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Surface</span> <span class="ot">=</span> <span class="dt">Top</span> <span class="op">|</span> <span class="dt">Bottom</span></span>
<span id="cb12-64"><a href="#cb12-64" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>)</span>
<span id="cb12-65"><a href="#cb12-65" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-66"><a href="#cb12-66" aria-hidden="true" tabindex="-1"></a><span class="ot">smearSliceOfBread ::</span> <span class="dt">Utensil</span> <span class="ot">-&gt;</span> <span class="dt">Surface</span> <span class="ot">-&gt;</span> <span class="dt">SliceOfBread</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> (<span class="dt">SliceOfBread</span>, <span class="dt">Utensil</span>)</span>
<span id="cb12-67"><a href="#cb12-67" aria-hidden="true" tabindex="-1"></a>smearSliceOfBread u surface slice</span>
<span id="cb12-68"><a href="#cb12-68" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> uShape u <span class="op">/=</span> <span class="dt">Knife</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;You can&#39;t smear with that!&quot;</span></span>
<span id="cb12-69"><a href="#cb12-69" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> uCondiment u <span class="op">==</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This knife is too clean to smear with.&quot;</span></span>
<span id="cb12-70"><a href="#cb12-70" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> surface <span class="op">==</span> <span class="dt">Top</span> <span class="op">&amp;&amp;</span> sobTop slice <span class="op">/=</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This surface was already smeared!&quot;</span></span>
<span id="cb12-71"><a href="#cb12-71" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> surface <span class="op">==</span> <span class="dt">Bottom</span> <span class="op">&amp;&amp;</span> sobBottom slice <span class="op">/=</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This surface was already smeared!&quot;</span></span>
<span id="cb12-72"><a href="#cb12-72" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> (smearedSlice, cleanUtensil)</span>
<span id="cb12-73"><a href="#cb12-73" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-74"><a href="#cb12-74" aria-hidden="true" tabindex="-1"></a>    smearedSlice</span>
<span id="cb12-75"><a href="#cb12-75" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> surface <span class="op">==</span> <span class="dt">Top</span> <span class="ot">=</span> slice { sobTop <span class="ot">=</span> uCondiment u }</span>
<span id="cb12-76"><a href="#cb12-76" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> surface <span class="op">==</span> <span class="dt">Bottom</span> <span class="ot">=</span> slice { sobBottom <span class="ot">=</span> uCondiment u }</span>
<span id="cb12-77"><a href="#cb12-77" aria-hidden="true" tabindex="-1"></a>    cleanUtensil <span class="ot">=</span> u { uCondiment <span class="ot">=</span> <span class="dt">Nothing</span>}</span>
<span id="cb12-78"><a href="#cb12-78" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-79"><a href="#cb12-79" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Sandwich</span> <span class="ot">=</span> <span class="dt">Sandwich</span></span>
<span id="cb12-80"><a href="#cb12-80" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> swBottom ::</span> <span class="dt">SliceOfBread</span></span>
<span id="cb12-81"><a href="#cb12-81" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> swTop ::</span> <span class="dt">SliceOfBread</span></span>
<span id="cb12-82"><a href="#cb12-82" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> swPieces ::</span> [(<span class="dt">SliceOfBread</span>, <span class="dt">SliceOfBread</span>)]</span>
<span id="cb12-83"><a href="#cb12-83" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-84"><a href="#cb12-84" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Show</span>)</span>
<span id="cb12-85"><a href="#cb12-85" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-86"><a href="#cb12-86" aria-hidden="true" tabindex="-1"></a><span class="ot">makeSandwich ::</span> <span class="dt">SliceOfBread</span> <span class="ot">-&gt;</span> <span class="dt">SliceOfBread</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> <span class="dt">Sandwich</span></span>
<span id="cb12-87"><a href="#cb12-87" aria-hidden="true" tabindex="-1"></a>makeSandwich bottom top</span>
<span id="cb12-88"><a href="#cb12-88" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> sobTop bottom <span class="op">==</span> <span class="dt">Nothing</span> <span class="op">&amp;&amp;</span> sobBottom top <span class="op">==</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This sandwich might actually be a loaf.&quot;</span></span>
<span id="cb12-89"><a href="#cb12-89" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> sobTop top <span class="op">/=</span> <span class="dt">Nothing</span> <span class="op">||</span> sobBottom bottom <span class="op">/=</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;This sandwich would be icky to hold.&quot;</span></span>
<span id="cb12-90"><a href="#cb12-90" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> <span class="dt">Sandwich</span> { swBottom <span class="ot">=</span> bottom, swTop <span class="ot">=</span> top, swPieces <span class="ot">=</span> [(bottom, top)] }</span>
<span id="cb12-91"><a href="#cb12-91" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-92"><a href="#cb12-92" aria-hidden="true" tabindex="-1"></a><span class="co">-- A sandwich is always cut through all the pieces, doubling them all</span></span>
<span id="cb12-93"><a href="#cb12-93" aria-hidden="true" tabindex="-1"></a><span class="ot">cutSandwich ::</span> <span class="dt">Utensil</span> <span class="ot">-&gt;</span> <span class="dt">Sandwich</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> <span class="dt">Sandwich</span></span>
<span id="cb12-94"><a href="#cb12-94" aria-hidden="true" tabindex="-1"></a>cutSandwich u sw</span>
<span id="cb12-95"><a href="#cb12-95" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> uShape u <span class="op">==</span> <span class="dt">Fork</span> <span class="op">||</span> uShape u <span class="op">==</span> <span class="dt">Spoon</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;You can&#39;t cut a sandwich with that!&quot;</span></span>
<span id="cb12-96"><a href="#cb12-96" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> uCondiment u <span class="op">/=</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Left</span> <span class="st">&quot;No! You&#39;ll get the edge all yucky with that knife.&quot;</span></span>
<span id="cb12-97"><a href="#cb12-97" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Right</span> sw { swPieces <span class="ot">=</span> newPieces }</span>
<span id="cb12-98"><a href="#cb12-98" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-99"><a href="#cb12-99" aria-hidden="true" tabindex="-1"></a>    newPieces <span class="ot">=</span> <span class="fu">concat</span> [swPieces sw, swPieces sw]</span>
<span id="cb12-100"><a href="#cb12-100" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-101"><a href="#cb12-101" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb12-102"><a href="#cb12-102" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb12-103"><a href="#cb12-103" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> knife <span class="ot">=</span> fetchUtensil <span class="dt">Knife</span></span>
<span id="cb12-104"><a href="#cb12-104" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> pb <span class="ot">=</span> fetchCondimentJar <span class="dt">PeanutButter</span></span>
<span id="cb12-105"><a href="#cb12-105" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> jelly <span class="ot">=</span> fetchCondimentJar <span class="dt">Jelly</span></span>
<span id="cb12-106"><a href="#cb12-106" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-107"><a href="#cb12-107" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- First attempt. Didn&#39;t open the jar of peanut butter.</span></span>
<span id="cb12-108"><a href="#cb12-108" aria-hidden="true" tabindex="-1"></a>  <span class="fu">either</span> printError <span class="fu">putStrLn</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb12-109"><a href="#cb12-109" aria-hidden="true" tabindex="-1"></a>    (pbKnife, emptyPB) <span class="ot">&lt;-</span> knife <span class="ot">`loadFrom`</span> pb <span class="co">-- Problem</span></span>
<span id="cb12-110"><a href="#cb12-110" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="st">&quot;Sandwich made!&quot;</span></span>
<span id="cb12-111"><a href="#cb12-111" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-112"><a href="#cb12-112" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Next attempt. Too plain.</span></span>
<span id="cb12-113"><a href="#cb12-113" aria-hidden="true" tabindex="-1"></a>  <span class="fu">either</span> printError <span class="fu">putStrLn</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb12-114"><a href="#cb12-114" aria-hidden="true" tabindex="-1"></a>    (pbKnife, emptyPB) <span class="ot">&lt;-</span> knife <span class="ot">`loadFrom`</span> openJar pb</span>
<span id="cb12-115"><a href="#cb12-115" aria-hidden="true" tabindex="-1"></a>    (jellyKnife, emptyJelly) <span class="ot">&lt;-</span> knife <span class="ot">`loadFrom`</span> openJar jelly</span>
<span id="cb12-116"><a href="#cb12-116" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> bottomSlice <span class="ot">=</span> fetchSliceOfBread <span class="dt">Sourdough</span></span>
<span id="cb12-117"><a href="#cb12-117" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> topSlice <span class="ot">=</span> fetchSliceOfBread <span class="dt">WholeGrain</span></span>
<span id="cb12-118"><a href="#cb12-118" aria-hidden="true" tabindex="-1"></a>    sw <span class="ot">&lt;-</span> makeSandwich bottomSlice topSlice</span>
<span id="cb12-119"><a href="#cb12-119" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="st">&quot;Sandwich made!&quot;</span></span>
<span id="cb12-120"><a href="#cb12-120" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-121"><a href="#cb12-121" aria-hidden="true" tabindex="-1"></a>  <span class="co">-- Successful sandwich making!</span></span>
<span id="cb12-122"><a href="#cb12-122" aria-hidden="true" tabindex="-1"></a>  <span class="fu">either</span> printError <span class="fu">putStrLn</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb12-123"><a href="#cb12-123" aria-hidden="true" tabindex="-1"></a>    (pbKnife, emptyPB) <span class="ot">&lt;-</span> knife <span class="ot">`loadFrom`</span> openJar pb</span>
<span id="cb12-124"><a href="#cb12-124" aria-hidden="true" tabindex="-1"></a>    (jellyKnife, emptyJelly) <span class="ot">&lt;-</span> knife <span class="ot">`loadFrom`</span> openJar jelly</span>
<span id="cb12-125"><a href="#cb12-125" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> bottomSlice <span class="ot">=</span> fetchSliceOfBread <span class="dt">Sourdough</span></span>
<span id="cb12-126"><a href="#cb12-126" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> topSlice <span class="ot">=</span> fetchSliceOfBread <span class="dt">WholeGrain</span></span>
<span id="cb12-127"><a href="#cb12-127" aria-hidden="true" tabindex="-1"></a>    (bottomSliceWithPB, cleanKnife) <span class="ot">&lt;-</span> smearSliceOfBread pbKnife <span class="dt">Top</span> bottomSlice</span>
<span id="cb12-128"><a href="#cb12-128" aria-hidden="true" tabindex="-1"></a>    (topSliceWithJelly, cleanKnife) <span class="ot">&lt;-</span> smearSliceOfBread jellyKnife <span class="dt">Bottom</span> topSlice</span>
<span id="cb12-129"><a href="#cb12-129" aria-hidden="true" tabindex="-1"></a>    sw <span class="ot">&lt;-</span> makeSandwich bottomSliceWithPB topSliceWithJelly</span>
<span id="cb12-130"><a href="#cb12-130" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> <span class="st">&quot;Sandwich made!&quot;</span></span>
<span id="cb12-131"><a href="#cb12-131" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-132"><a href="#cb12-132" aria-hidden="true" tabindex="-1"></a><span class="ot">    printError ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span>
<span id="cb12-133"><a href="#cb12-133" aria-hidden="true" tabindex="-1"></a>    printError e <span class="ot">=</span> <span class="fu">putStrLn</span> (<span class="st">&quot;Error: &quot;</span> <span class="op">++</span> e)</span></code></pre></div>
<p>To replace the <code>new</code> functions from the OOP-translated version, I included functions like <code>fetchCondimentJar</code>, which act similarly. The different naming convention (“fetch-” instead of “new-”) is because I started thinking of the instance-creating functions as being analogous to fetching something from the kitchen. When it’s time to get a condiment jar, we can use <code>fetchCondimentJar</code> to fetch one of the given condiments. Interestingly, these idiomatic functions still behave much like OOP constructors.</p>
<p>I also merged the previous <code>Slice</code> and <code>Bread</code> into a single type, <code>SliceOfBread</code>:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SliceOfBread</span> <span class="ot">=</span> <span class="dt">SliceOfBread</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> sobFlavour ::</span> <span class="dt">BreadFlavour</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> sobTop ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> sobBottom ::</span> <span class="dt">Maybe</span> <span class="dt">Condiment</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>A slice of bread has a top and bottom, both of which can be smeared with a condiment or nothing (hence the <code>Maybe Condiment</code> type). There’s no need for a separate type just for <code>Slice</code>.</p>
<p>Another difference is the type definition for <code>Surface</code>. Instead of using a record, a surface only needs to represent the top or bottom of a slice of bread, so a surface can be a <strong>sum type</strong> (a choice between multiple values):</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Surface</span> <span class="ot">=</span> <span class="dt">Top</span> <span class="op">|</span> <span class="dt">Bottom</span></span></code></pre></div>
<p>As for the <code>Sandwich</code> type and its shortcomings discussed above, it has been updated in this version.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Sandwich</span> <span class="ot">=</span> <span class="dt">Sandwich</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> swBottom ::</span> <span class="dt">SliceOfBread</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> swTop ::</span> <span class="dt">SliceOfBread</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> swPieces ::</span> [(<span class="dt">SliceOfBread</span>, <span class="dt">SliceOfBread</span>)]</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>Now, a sandwich doesn’t have a <code>built</code> property because if an instance of a sandwich exists, it is because it was built. Still, it could be improved. After all, with this definition, it’s easy to make a sandwich that doesn’t make sense:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- A sandwich whose top and bottom slices are sourdough,</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- but consists of a single piece whose slices are whole grain</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>impossibleSandwich <span class="ot">=</span> <span class="dt">Sandwich</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  { swBottom <span class="ot">=</span> fetchSliceOfBread <span class="dt">Sourdough</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>  , swTop <span class="ot">=</span> fetchSliceOfBread <span class="dt">Sourdough</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>  , swPieces <span class="ot">=</span> [(fetchSliceOfBread <span class="dt">WholeGrain</span>, fetchSliceOfBread <span class="dt">WholeGrain</span>)]</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>No matter how much error handling we add along the way to making a sandwich, our definition of a sandwich makes it possible to skip the error checks and create an erroneous sandwich. Even if we force the user only to make a sandwich using the proper functions, we have to be sure we include checks for all the possible mistakes that could be made. Are we sure we didn’t miss one?</p>
<p>The other approach is to avoid possible errors altogether by using type-safe definitions, making it so a sandwich can only be made when its type is fulfilled. To relate this to the <a href="https://www.youtube.com/watch?v=FN2RM-CHkuI">video</a>, the kids are frustrated because their father is failing in ways they didn’t expect him to fail. He’s doing things they didn’t want him to do. On the computer, why would we program the ability to do things we don’t want to happen? We don’t want it to be possible to attempt to put a knife in a closed jar, so we shouldn’t make a function where that can happen. Type systems can help us resolve this. Stay tuned for Part II…</p>
<p>See the full Haskell code on GitHub: <a href="https://github.com/SlimTim10/simple-sandwich">https://github.com/SlimTim10/simple-sandwich</a></p>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Wed, 28 Dec 2022 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/a-simple-sandwich-part-i.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>How to Learn Web Development On Your Own</title>
    <link>https://timjohns.ca/how-to-learn-web-development-on-your-own.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        How to Learn Web Development On Your Own
      </h1>
      <p class="writing">Dec 15, 2022</p>
      
    </header>
	<img class="post-image" alt="Drawing of a pile of books." src="./images/blog/how_to_learn_web_development_one_your_own.jpg" />
    <section class="content writing">
	  <p><strong>How do you learn a complex skill like web development without going to school or hiring a mentor?</strong></p>
<p>Although I’ve taught programming for a long time, I am primarily self-taught. That’s not to say I didn’t learn from others along the way, but I didn’t have a dedicated mentor or teacher that I learned from, and I don’t attribute my knowledge to my school experiences. The tips here are from personal experience and my experience in observing and teaching others.</p>
<h1 id="choose-good-material">Choose good material</h1>
<p>There are so many courses and books on programming and web development topics. How do you choose? In the long run, the material you start with doesn’t make much difference. But in the shorter term, like the next 1-2 years, taking one path versus another can make a big difference.</p>
<p>One thing to look for is material that emphasizes <strong>foundational concepts</strong>. Web development is very much a trend-based industry. Programming languages, libraries, and frameworks form and disappear like bubbles in boiling water. But programming foundations last for decades. You don’t want to focus on a particular trend that goes out of fashion while still having shaky foundational knowledge.</p>
<p>You also want to make sure the material is not spoon-feeding information. For example, I’ve had students come to me after taking a Udemy course on React, and even after making it through the course and building a final project, they still didn’t understand the fundamentals. They couldn’t build a new project and couldn’t explain how state works (which is a fundamental concept in React). The problem is that the course had them follow along with videos showing what code to write, so it was a lot of “monkey see, monkey do” without helping them understand <strong>why</strong> they were writing things the way they were.</p>
<p>Good material will assign you work that makes you <strong>think and exercise your problem-solving skills</strong>.</p>
<p>Some decisions are more straightforward, like choosing which programming language to learn. Since we’re talking about web development, JavaScript is your best bet. It’s ubiquitous on the web and the <a href="https://bootcamp.berkeley.edu/blog/most-in-demand-programming-languages/">most in-demand programming language on the market</a>. The second best would be Ruby because the Ruby on Rails framework is very popular for building web applications. Whichever language you pick, learn one language thoroughly before moving on. Once you’ve grasped the logic of programming in one language, it’s much easier to pick up another.</p>
<p>My top recommendations for starting out are:</p>
<ul>
<li><a href="https://intuitivejs.info/">Intuitive JavaScript</a></li>
<li><a href="https://www.theodinproject.com/">The Odin Project</a></li>
<li><a href="https://www.udemy.com/">Udemy</a> (depending on the course)</li>
</ul>
<p>I hesitate to recommend <a href="https://www.freecodecamp.org/">freeCodeCamp</a> and <a href="https://www.codecademy.com/">Codecademy</a> because they do more “monkey see, monkey do” than good teaching.</p>
<h1 id="learn-to-google-all-the-things">Learn to google all the things</h1>
<p>Get used to googling things as you’re coding. Like, <strong>more than you think</strong>. Professional developers google even the smallest things because it’s usually faster than trying to remember the answer or checking your own notes.</p>
<p>The critical skill is learning <strong>how to search</strong>. You’ll have to experiment to see what works and what doesn’t, but as a quick tip, use quotes when you want to search something literally, like an error message (e.g., <code>"psql: could not connect to server: No such file or directory"</code>). Also, you don’t need to click the first link and read the whole page. When I search, I open a few of the results in new tabs, then quickly skim through them to see which one is relevant. I’ll often accumulate a whole bunch of tabs (usually 5-10, often more) while I’m trying to solve one problem, then close them all afterwards to make space for the next problem.</p>
<p>Even if you’re able to google and solve a problem <em>eventually</em>, you can always improve your searching process. Good searching skills can make you solve problems ten times faster, literally.</p>
<h1 id="build-projects">Build projects</h1>
<p>There are so many good reasons for building projects to learn web development. For one, it’s as close as you can get to replicating the <strong>actual work</strong> you would be doing as an engineer on the job, so it’s the best way to practice. Another reason is that you will encounter the most <strong>interesting and important problems</strong> when building projects that you can’t find in exercises or books. Also, having built projects that you’re proud of is the best way to combat <strong>imposter syndrome</strong>, which is too common among software engineers. When you can look back at your projects, you feel a sense of accomplishment and confidence that you have what it takes to do the work. After all, building things is what it’s all about.</p>
<p>Of course, if you’re starting from scratch, you may not be ready to start building a project. But you’ll get there soon. You don’t need a lot of coding knowledge to start a project. Once you’ve learned some of the basics, you can start building a small project right away, like a command-line app.</p>
<p><strong>How do you choose a project to build?</strong></p>
<p>Make sure you’re not overreaching with what you want the project to do. In other words, make sure the project isn’t too complex and doesn’t have too many complicated features. Lots of people like to build tools for themselves. Something that makes their life easier. Don’t try to make a tool for someone else; that adds a layer of complexity you don’t need (trying to understand your client’s needs). If you’re into games, coding a game can be a great project idea. It can be a simplified clone of a game you like to play.</p>
<p>It’s important to choose a project that you’re <strong>genuinely interested in building</strong>. Research shows that interest leads to the use of deep comprehension processes, meaning you’ll learn better if you’re interested.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<h1 id="join-communities">Join communities</h1>
<p>Even though you’re self-teaching, you don’t have to be alone. You can join many communities to be surrounded by <strong>people talking about code</strong>. Chatting with people of various backgrounds and experiences can be a great way to <strong>build your network</strong>. When it comes to the job search, one of your new contacts might be just the connection you need. It can also help you feel motivated and accountable to do your work. You’ll also learn to talk like an engineer by interacting with actual engineers, which helps with landing a job.</p>
<p>As of writing this article, these are some awesome communities you can join right away:</p>
<ul>
<li><a href="https://torontojs.com/">TorontoJS</a> (Slack)
<ul>
<li>Local to Toronto, Canada</li>
<li>Try to find a community local to where you live!</li>
</ul></li>
<li><a href="https://womenintechto.com/">Women in Tech</a></li>
<li><a href="https://www.codebuddies.org/slack">CodeBuddies</a> (Slack)</li>
<li><a href="https://theprogrammershangout.com/about">The Programmer’s Hangout</a> (Discord)</li>
<li><a href="https://discord.com/invite/devcord">devcord</a> (Discord)</li>
<li><a href="https://discord.gg/V75WSQG">The Odin Project</a> (Discord)
<ul>
<li><a href="https://www.theodinproject.com/lessons/foundations-join-the-odin-community">More information</a></li>
</ul></li>
<li><a href="https://www.reactiflux.com/">Reactiflux</a> (Discord)
<ul>
<li>Tailored to React JS and related technologies</li>
</ul></li>
</ul>
<p>If you need a bigger list of communities, check these out:</p>
<ul>
<li><a href="https://github.com/mhxion/awesome-discord-communities">Awesome Discord Communities</a></li>
<li><a href="https://dev.to/htnguy/top-10-discord-servers-for-developers-559o">Top 10 Discord Servers for Developers</a></li>
<li><a href="https://careerkarma.com/blog/the-best-discord-servers-to-join-for-javascript/">https://careerkarma.com/blog/the-best-discord-servers-to-join-for-javascript/</a></li>
<li><a href="https://discord.me/servers/tag/javascript">https://discord.me/servers/tag/javascript</a></li>
</ul>
<h1 id="be-consistent">Be consistent</h1>
<p>Programming concepts <strong>take time</strong> to sink in. You won’t understand every concept the first time you read it. You’ll have many moments along the way where you <strong><em>just don’t get it</em></strong>, and you need to keep at it. Being consistent in studying will get you to the good moments where things will <strong><em>click</em></strong>, and suddenly it all makes sense.</p>
<p>Just like building muscles at the gym, you need to get your reps in. The difference is your brain doesn’t need as much time to recover as your muscles. Do at least a little bit of coding every day. In the long run, being consistent will get you to a high level of proficiency.</p>
<h1 id="look-at-code-on-github">Look at code on GitHub</h1>
<p>Being a programmer isn’t all about writing code. It’s also about <strong>reading code</strong>. On <a href="https://github.com/">GitHub</a>, you can find code in virtually any programming language and on any subject. Of course, you don’t want to browse random projects on GitHub and start reading any code you come across.</p>
<p>It’s not hard to find a project on GitHub similar to something you want to make. From there, you can observe how the code is set up and what approach the author(s) took to solve the project’s challenges. You can see how certain features were implemented, perhaps differently from what you imagined. You may start to notice specific patterns you hadn’t thought of before that you can adopt in your own code. Keep in mind that GitHub has a very low barrier of entry, so not every project will use best practices (in fact, many projects probably don’t even work!). Still, you can learn from bad code as well as good code. As much as picking up new strategies, you may also learn what <strong>not to do</strong>.</p>
<p>Sometimes documentation for a particular library or framework lacks helpful examples, and the only place to find it in use is in a small project on GitHub. I frequently use GitHub in this way.</p>
<h1 id="use-a-mix-of-resources">Use a mix of resources</h1>
<p>Books, websites, forums, blog posts, tutorials, videos… there are so many different places to learn from. Take advantage of the abundance of information!</p>
<p>Don’t limit yourself to a single resource or medium when learning a concept. When you don’t understand something, you might blame yourself for not being smart enough, but it’s probably the case that it just hasn’t been presented to you the right way. For instance, you might be stuck with understanding what a REST API is after reading a few articles, then find a great video on YouTube that clears it up in a visual way that no article or book could.</p>
<p>Official documentation, like <a href="https://reactjs.org/docs/getting-started.html">reactjs.org</a> or <a href="https://nodejs.org/en/docs/">nodejs.org</a>, is great for being accurate, but it’s not always the best for learning. It’s often too verbose or lacking in examples. Instead, find a resource that’s more accessible and then cross-reference the information with the official documentation if you’re worried about correctness or best practices.</p>
<p>If you want to learn from books, be aware that very few programming books are meant to be read from front to back like a novel. Instead, it’s better to use books as references, consulting them when you need answers to specific questions.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://sci-hub.hkvisa.net/10.3102/00346543064001037">Tobias, S. (1994). Interest, Prior Knowledge, and Learning. Review of Educational Research, 64(1), 37–54.</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Thu, 15 Dec 2022 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/how-to-learn-web-development-on-your-own.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>5 Tips to Make the Most of a Coding Mentorship</title>
    <link>https://timjohns.ca/5-tips-to-make-the-most-of-a-coding-mentorship.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        5 Tips to Make the Most of a Coding Mentorship
      </h1>
      <p class="writing">Nov  8, 2022</p>
      
    </header>
	<img class="post-image" alt="Drawing of a stick figure helping another up a staircase." src="./images/blog/mentorship_tips.png" />
    <section class="content writing">
	  <p>I’ve been mentoring coding, programming, software development, or whatever you want to call it, for over 7 years. I choose the mentorship model over lecturing because I like to connect with each student and take a quality-over-quantity approach to teaching. If you’re interested in having a coding mentor, here are some tips to give you the best chance of success.</p>
<h1 id="tip-1-come-up-with-project-ideas">Tip 1. Come up with project ideas</h1>
<p>When it comes to coding, most of your real learning is going to come from building projects. And when it comes to deciding on what a project to build, it’s best if it’s an idea that you came up with. Sure, you can pick from a list of project ideas, make a clone of a popular app, or have your mentor suggest an idea to you, but it’s never as good as thinking of a problem <em>you</em> want to solve or an app you wish you had. You get to be <strong>more creative</strong> and you’ll be more invested in the result. It’s a great feeling when you bring to life an idea you had in your head.</p>
<p>People sometimes find it hard to come up with their own ideas for projects, but trust me, <strong>you can do it!</strong> You have tons of great ideas in you; you just need to find them. If you like games, maybe you can make a different version of a game you like to play. Maybe you’re into budgeting and you’ve always wanted a specific kind of tracker to help you stick to a budget.</p>
<p><strong>Be ambitious!</strong> Don’t worry if you think your project idea might be too big or beyond your skill level. Your mentor can help you decide on features, make sure the scope of the project is manageable, and provide support as you build it.</p>
<h1 id="tip-2-ask-lots-of-questions">Tip 2. Ask lots of questions</h1>
<p>In contrast to being a student in a course/class/cohort, when you have a mentor you can <strong>ask as many questions as you want</strong>. Take advantage of it! A mentoring session can be dedicated entirely to one question or a concept you want to delve into; it’s all about <em>you</em>. Don’t be afraid to ask about things outside of your planned learning path, like other libraries or frameworks. <strong>Be curious!</strong></p>
<p>Many questions will come up as you’re doing exercises or building projects.</p>
<p><em>Do I understand this concept right?</em></p>
<p><em>Is there a better way to write this function?</em></p>
<p><em>What’s the difference between Git and GitHub?</em></p>
<p>Between sessions with your mentor, as soon as you think of a question you want to ask be sure to <strong>write it down</strong>. You may not remember everything you wanted to ask the next time you meet with your mentor.</p>
<h1 id="tip-3-be-honest-about-your-time-commitment">Tip 3. Be honest about your time commitment</h1>
<p><strong>Be honest with yourself and your mentor</strong> about the amount of time you are committing to doing the work between sessions. If you frequently under work, you will not make the progress both of you were expecting and your planned timeline will not be possible. You will likely burn out before you get very far. Diligence will pay off. Put in the hours and you’ll do great.</p>
<h1 id="tip-4-put-in-the-work-to-get-a-job">Tip 4. Put in the work to get a job</h1>
<p>If your end goal is to get a job as a developer, there will come a point when you need to apply for jobs. This part you have to do mostly on your own. Your mentor can help you with personal branding, like updating your LinkedIn profile and making a great portfolio, but you’re the one who has to <strong>search for jobs</strong>, <strong>send out your resume</strong>, and <strong>make connections</strong>.</p>
<p>Treat it like a full-time job. There’s always something you can be doing to improve your chances at finding a job. Set targets for yourself, like sending out 10+ resumes per week. Join online communities centered around programming to meet people in the industry.</p>
<h1 id="tip-5-make-sure-its-a-good-fit">Tip 5. Make sure it’s a good fit</h1>
<p>A mentorship is a two-way street. You should be making sure it’s a good fit just as much as the mentor. Aside from obvious compatibilities like scheduling times and technical knowledge, it’s about the <strong>environment your mentor provides</strong> when you’re learning. You should feel comfortable to approach your mentor with any question. Your mentor should never make you feel stupid. Your environment should be <strong>constantly supportive</strong>.</p>
<p>Like all people, different mentors will have personalities that will affect how they teach you. Maybe you want someone who’s really stern and doesn’t let you get away with small mistakes. Or maybe you want someone who’s going to hold your hand every step of the way. As for myself, for example, I’m not the kind of mentor to push you to stay on top of the work. If you struggle with self-discipline and you need someone to constantly be on your case about doing the work, I’m probably not the right mentor for you.</p>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Tue, 08 Nov 2022 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/5-tips-to-make-the-most-of-a-coding-mentorship.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>6 Tips to Make the Most of a Coding Bootcamp</title>
    <link>https://timjohns.ca/6-tips-to-make-the-most-of-a-coding-bootcamp.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        6 Tips to Make the Most of a Coding Bootcamp
      </h1>
      <p class="writing">Oct 24, 2022</p>
      
    </header>
	<img class="post-image" alt="Drawing of boots in front of a camping tent." src="./images/blog/bootcamp_tips.jpg" />
    <section class="content writing">
	  <p>I was a mentor and instructor for the Web Development Bootcamp at Lighthouse Labs for over 3 years. I’ve seen countless students go through the bootcamp, some more successful than others. Many students get to the end of the bootcamp only to struggle to land their first job in the industry. Some never make it at all. I want to share some tips that can help you make sure your time at a coding bootcamp ends in success. As with most things in life, you get out what you put in. If you put in the bare minimum, don’t expect great results out of the bootcamp. You need to put in the effort, the more the better.</p>
<h1 id="tip-1-do-the-prep-work">Tip 1. Do the prep work</h1>
<p>A bootcamp might market itself as 12 weeks, but in reality it’s more like 6 months (or more!). The students who enter the bootcamp with some practice under their belt are the ones who will keep up and succeed in the end. You should do a <strong>bare minimum of 2 months of prep work</strong>, and more if you’ve never been exposed to coding in the first place. <strong>Learning to code takes time to sink in</strong>; there are no shortcuts or hacks to quickly force it into your brain. Taking a bootcamp without first trying to learn the basics on your own would be a big mistake. After the first two weeks, you would be lost and there’s no time to catch up.</p>
<p>A good bootcamp will have suggestions for prep work materials. It doesn’t really matter where you learn from, as long as it’s teaching you the basics and you’re writing code (not just reading!). Some of my favourites are:</p>
<ul>
<li><a href="https://www.freecodecamp.org/">freeCodeCamp</a></li>
<li><a href="https://www.codecademy.com/">Codecademy</a></li>
<li><a href="https://www.theodinproject.com/">The Odin Project</a></li>
<li><a href="https://www.udemy.com/">Udemy</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn">MDN Guides</a></li>
<li>and obviously, <a href="https://intuitivejs.info/">Intuitive JavaScript</a></li>
</ul>
<h1 id="tip-2-make-connections">Tip 2. Make connections</h1>
<p>This is the same advice you hear about going to college/university. <strong>Talk to your teachers!</strong> They’re a great connection to have, but they’ll be more inclined to help you outside of the bootcamp if you separate yourself from the herd. Ask them about programming or their hobbies. You may have more in common with them than you think!</p>
<p>Of course, talk to your classmates too. In a way, you’re all competing since you’re all trying to get jobs in the same industry. But the job pool for developers is huge, so you probably won’t end up competing directly with your peers. And more importantly, once you’ve all moved on from bootcamp your connections in the industry become even more valuable, so it’s important to keep in touch. Job openings come up all the time and they’re not always public. By knowing the right person at the right time, you can land your dream job before anyone else has a chance to apply.</p>
<p>Don’t sleep on networking. It can be the best tool for your career. And remember, it’s just <strong>talking to people</strong>.</p>
<h1 id="tip-3-dont-fall-behind">Tip 3. Don’t fall behind</h1>
<p>Bootcamps have a strict, full schedule. That’s what makes it a bootcamp. Everything has been planned down to the hour, and whatever time is left over, you should use it to rest. As a result, there’s no time in a bootcamp for catching up. The unfortunate reality is, <strong>if you fall behind, you’re left behind</strong>. So do everything you can to stay on top, or ahead, of the work.</p>
<p>Of course, life happens and you might have things outside of your control preventing you from keeping up. In that case, you should talk to your bootcamp manager to see what accomodations can be made for you to not be left behind (this usually means rolling over to the next cohort).</p>
<h1 id="tip-4-practice-communicating-clearly">Tip 4. Practice communicating clearly</h1>
<p>Communication is a huge part of every job interview. People want to make sure you’ll be easy to work with because you communicate well. Effective communication doesn’t come naturally to everyone. In a bootcamp, you will have lots of opportunity to practice, but nobody will force you to improve, so it’s up to you to put in the effort.</p>
<p>When you ask for help from a mentor or your peers, try your best to explain your problem clearly. If you notice they have trouble understanding how to help you, try to figure out what you can do better and put it to the test with the next assistance.</p>
<p>When it’s time to demo your project to the class, <strong>take it seriously</strong>. This is a great skill to have and you’ll make use of it on the job more than you think. There will be many times where you’re leading the work on a product feature and you need to bring your colleagues up to speed on it. This uses the same communication skills as a project demo.</p>
<p>I can’t tell you how many project demos I’ve seen where I don’t understand what the product does or who it’s for. Some <strong>visual diagrams</strong> or a <strong>clear explanation</strong> can make a huge difference. When you’ve spent so much time on your project, it’s easy to forget that someone seeing it for the first time doesn’t know anything about it. It’s your job to educate the audience in a clear manner what the project is, what it’s for, and how it works.</p>
<p>Another mistake I’ve seen countless times is when a presenter reads from a script, in a monotone voice. <strong>Don’t do this.</strong> Everyone can tell you’re reading a script and they’re instantly bored. It’s the least engaging way to present, and therefore poor communication. <strong>Have fun with the presentation!</strong> You had fun building your project and you’re proud of it, so show it with enthusiasm!</p>
<h1 id="tip-5-be-resourceful">Tip 5. Be resourceful</h1>
<p>Use the resources that your bootcamp recommends. I mean <strong>use them a lot</strong>. More than you probably think. Seriously, developers don’t just remember every function name and how it works. We look things up constantly.</p>
<p>Also, use resources <strong>other than the ones your bootcamp recommends</strong>. In <em>the real world</em>, developers don’t consult a trusted list of books and websites whenever they run into a problem. They simply google the error message and look at whichever results seem useful. Don’t even limit yourself to written material; sometimes a video is just right for the occasion. Learning to find relevant results by searching the right terms is a skill in itself, and a surprisingly uncommon one. The solution to your problem won’t always be on one of your favourite websites, but it’s out there somewhere. You need to know how to find it.</p>
<p><strong>Discover libraries and frameworks</strong> that the course doesn’t mention. I was always impressed when a student would come up to me and say, “I found this library called X and I want to use it in my project. I read the docs and saw some examples, and it seems like a good way to do Y. Do you know how to use it?” My answer was typically, “No, but I can figure it out with you.” Those students always did well in the end. Even if you don’t end up using what you found, it’s good to know what’s out there for future projects.</p>
<h1 id="tip-6-immerse-yourself">Tip 6. Immerse yourself</h1>
<p>One of the best things a bootcamp has to offer is an environment for <strong>deep immersion</strong>. Take advantage of it! Allow yourself to be immersed in coding. You’ll be surprised how much knowledge you can absorb. It’s the same reason the fastest way to learn a language is to live in a country where you’re surrounded by it.</p>
<p>Spend more time thinking about coding than you thought you could. If you’re not having dreams about coding, you’re not doing enough.</p>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Mon, 24 Oct 2022 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/6-tips-to-make-the-most-of-a-coding-bootcamp.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>Breaking the Order | Coding Challenge &amp; Analysis 1</title>
    <link>https://timjohns.ca/breaking-the-order-coding-challenge-analysis-1.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        Breaking the Order | Coding Challenge & Analysis 1
      </h1>
      <p class="writing">Aug 26, 2022</p>
      
    </header>
	<img class="post-image" alt="drawing of coding challenge" src="./images/blog/coding_challenge_1.jpg" />
    <section class="content writing">
	  <div id="toc"><ul>
<li><a href="#javascript-coding-challenge-breaking-the-order" id="toc-javascript-coding-challenge-breaking-the-order"><span class="toc-section-number">1</span> JavaScript Coding Challenge: Breaking the Order</a></li>
<li><a href="#solution" id="toc-solution"><span class="toc-section-number">2</span> Solution</a></li>
<li><a href="#abstracting-the-ordering" id="toc-abstracting-the-ordering"><span class="toc-section-number">3</span> Abstracting the Ordering</a></li>
<li><a href="#imperative-solution" id="toc-imperative-solution"><span class="toc-section-number">4</span> Imperative Solution</a></li>
<li><a href="#final-thoughts" id="toc-final-thoughts"><span class="toc-section-number">5</span> Final Thoughts</a>
<ul>
<li><a href="#haskell-solution" id="toc-haskell-solution"><span class="toc-section-number">5.1</span> Haskell Solution</a></li>
</ul></li>
</ul></div>
<h1 data-number="1" id="javascript-coding-challenge-breaking-the-order"><span class="header-section-number">1</span> JavaScript Coding Challenge: Breaking the Order</h1>
<p>Given an array of numbers, find the last index before the ordering breaks. Indexing should begin with 0. If the numbers start by increasing, find last index where the numbers are increasing. If the numbers start by decreasing, find the last index where they are decreasing. If there is no break in the ordering, return -1. The array will contain at least 3 numbers and the first two will be increasing or decreasing.</p>
<p>For example, given the array <code>[10, 9, 8, 7, 9, 10]</code>, the result should be 3, because the 7 at index 3 is the last index where the numbers are decreasing.</p>
<p>More examples:</p>
<pre class="example"><code>[1, 2, 4, 7, 2, 3, 1] -&gt; 3
[1, 2, 3, 4, 5] -&gt; -1
[10, 11, 12, 12, 13] -&gt; 2
</code></pre>
<p>If you want to give this challenge a try, stop reading here and go do that now. For my solution and analysis, continue on.</p>
<h1 data-number="2" id="solution"><span class="header-section-number">2</span> Solution</h1>
<p>There are lots of ways to approach this challenge. My first thought was to use <code>findIndex</code>, since the goal is to find the index of a number based on something. However, it’s not as straightforward as it first seems. Take the example array <code>[10, 9, 8, 7, 9, 10]</code>. If we’re to look at each value individually, as <code>findIndex</code> allows, we don’t actually have enough information to deduce the break in the ordering. After all, it’s not a number by itself (e.g., 9) that indicates a break in the ordering; it’s the fact that a 9 came after a 7. So really, we’re looking between the numbers, or at the <strong>pairs</strong> of numbers. We could still use <code>findIndex</code> and use its second argument, each index of the array, and work things out looking at the current number and one ahead, but then we also have to make sure the index is in bounds and it’s just not as elegant as dealing with pairs.</p>
<p>To get the right pairs, we can make a helper function called <code>zip</code>. This is something I use a lot in Haskell and it’s a shame that JavaScript doesn’t have such a useful function in its standard library. But it’s easy to make. The goal of <code>zip</code> is to take in two arrays and “zip” them together, making an array of pairs, where each pair has an element from the first array and an element from the second array. For example, if we zip <code>[1, 2, 3, 4]</code> and <code>[7, 8, 9, 10]</code>, we should get <code>[ [1, 7], [2, 8], [3, 9], [4, 10] ]</code>. Disregarding special cases where the arrays are different sizes, we can make zip using <code>map</code>.</p>
<div class="sourceCode" id="cb2" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> zip <span class="op">=</span> (xs<span class="op">,</span> ys) <span class="kw">=&gt;</span> xs<span class="op">.</span><span class="fu">map</span>((_<span class="op">,</span> i) <span class="kw">=&gt;</span> [ xs[i]<span class="op">,</span> ys[i] ])</span></code></pre></div>
<p>Now, what do we want to zip together? Well, from the array <code>[10, 9, 8, 7, 9, 10]</code>, it would be nice to have the consecutive numbers as pairs <code>[ [10, 9], [9, 8], [8, 7], [7, 9], [9, 10] ]</code>. Then we can just get the index of the pair where the numbers stop decreasing and we’re done! So, the two arrays we need to zip are: <code>[10, 9, 8, 7, 9]</code> and <code>[9, 8, 7, 9, 10]</code>. The first array is the original, without the last element. The second array is the original, without the first element.</p>
<div class="sourceCode" id="cb3" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> arr <span class="op">=</span> [<span class="dv">10</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> init <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">0</span><span class="op">,</span> <span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> tail <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)</span></code></pre></div>
<p>All that’s left is to find the index where the ordering is broken. Although, we still need to know how to code where “the ordering is broken”. We can’t just assume the array will start off increasing or decreasing. The first thing that comes to mind is a conditional based on the start of the array. If the first pair is increasing, then find the index where the pairs stop increasing, and repeat the logic for decreasing. We can put this all together and include the tests.</p>
<div class="sourceCode" id="cb4" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> zip <span class="op">=</span> (xs<span class="op">,</span> ys) <span class="kw">=&gt;</span> xs<span class="op">.</span><span class="fu">map</span>((_<span class="op">,</span> i) <span class="kw">=&gt;</span> [ xs[i]<span class="op">,</span> ys[i] ])</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrder <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> init <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">0</span><span class="op">,</span> <span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> tail <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> pairs <span class="op">=</span> <span class="fu">zip</span>(init<span class="op">,</span> tail)</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> pairs<span class="op">.</span><span class="fu">findIndex</span>(([x<span class="op">,</span> y]) <span class="kw">=&gt;</span> {</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> [firstX<span class="op">,</span> firstY] <span class="op">=</span> pairs[<span class="dv">0</span>]</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> firstX <span class="op">&lt;</span> firstY</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>      <span class="op">?</span> <span class="op">!</span>(x <span class="op">&lt;</span> y)</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">:</span> <span class="op">!</span>(x <span class="op">&gt;</span> y)</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  })</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">10</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]) <span class="op">===</span> <span class="dv">3</span>)</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">1</span>]) <span class="op">===</span> <span class="dv">3</span>)</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]) <span class="op">===</span> <span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">10</span><span class="op">,</span> <span class="dv">11</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">13</span>]) <span class="op">===</span> <span class="dv">2</span>)</span></code></pre></div>
<h1 data-number="3" id="abstracting-the-ordering"><span class="header-section-number">3</span> Abstracting the Ordering</h1>
<p>Something that came to my mind after coming up with the solution is that the change in ordering doesn’t have to be thought of as a condition; it can be a value itself. This also comes from Haskell, which has an <code>Ordering</code> type whose values are <code>LT</code>, <code>EQ</code>, and <code>GT</code>. With this idea in mind, what we really care about is finding the first pair whose ordering value is different from the first pair’s ordering value. All we need is a <code>compare</code> function that returns an ordering value given two numbers.</p>
<div class="sourceCode" id="cb5" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> compare <span class="op">=</span> (x<span class="op">,</span> y) <span class="kw">=&gt;</span> (</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&lt;</span> y <span class="op">?</span> <span class="st">&#39;LT&#39;</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> x <span class="op">&gt;</span> y <span class="op">?</span> <span class="st">&#39;GT&#39;</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <span class="st">&#39;EQ&#39;</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<p>We can now use this function in the final solution.</p>
<div class="sourceCode" id="cb6" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> zip <span class="op">=</span> (xs<span class="op">,</span> ys) <span class="kw">=&gt;</span> xs<span class="op">.</span><span class="fu">map</span>((_<span class="op">,</span> i) <span class="kw">=&gt;</span> [ xs[i]<span class="op">,</span> ys[i] ])</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> compare <span class="op">=</span> (x<span class="op">,</span> y) <span class="kw">=&gt;</span> (</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&lt;</span> y <span class="op">?</span> <span class="st">&#39;LT&#39;</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> x <span class="op">&gt;</span> y <span class="op">?</span> <span class="st">&#39;GT&#39;</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <span class="st">&#39;EQ&#39;</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrder <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> init <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">0</span><span class="op">,</span> <span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> tail <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> pairs <span class="op">=</span> <span class="fu">zip</span>(init<span class="op">,</span> tail)</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> pairs<span class="op">.</span><span class="fu">findIndex</span>(([x<span class="op">,</span> y]) <span class="kw">=&gt;</span> {</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> [firstX<span class="op">,</span> firstY] <span class="op">=</span> pairs[<span class="dv">0</span>]</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">compare</span>(x<span class="op">,</span> y) <span class="op">!==</span> <span class="fu">compare</span>(firstX<span class="op">,</span> firstY)</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>  })</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">10</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]) <span class="op">===</span> <span class="dv">3</span>)</span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">1</span>]) <span class="op">===</span> <span class="dv">3</span>)</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]) <span class="op">===</span> <span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">10</span><span class="op">,</span> <span class="dv">11</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">13</span>]) <span class="op">===</span> <span class="dv">2</span>)</span></code></pre></div>
<h1 data-number="4" id="imperative-solution"><span class="header-section-number">4</span> Imperative Solution</h1>
<p>For fun, I wanted to try the same solution idea using a more old-school imperative programming style. So, instead of <code>zip</code> and <code>findIndex</code>, we can use a <code>for</code> loop.</p>
<p>The first time I wrote this imperative solution, I had a mistake in it. Can you spot it?</p>
<div class="sourceCode" id="cb7" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrder <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> arr<span class="op">.</span><span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) {</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">compare</span>(arr[i]<span class="op">,</span> arr[i<span class="op">+</span><span class="dv">1</span>]) <span class="op">!==</span> <span class="fu">compare</span>(arr[<span class="dv">0</span>]<span class="op">,</span> arr[<span class="dv">1</span>])) {</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> i</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">10</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]) <span class="op">===</span> <span class="dv">3</span>) <span class="co">// -&gt; true</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">1</span>]) <span class="op">===</span> <span class="dv">3</span>) <span class="co">// -&gt; true</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]) <span class="op">===</span> <span class="op">-</span><span class="dv">1</span>) <span class="co">// -&gt; false</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">10</span><span class="op">,</span> <span class="dv">11</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">12</span><span class="op">,</span> <span class="dv">13</span>]) <span class="op">===</span> <span class="dv">2</span>) <span class="co">// -&gt; true</span></span></code></pre></div>
<p>The mistake is in the indexing. In the last iteration of the loop, <code>arr[i+1]</code> is out of bounds (thus <code>undefined</code>). To correct this, the loop should stop one index earlier.</p>
<div class="sourceCode" id="cb8" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrder <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> arr<span class="op">.</span><span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> i<span class="op">++</span>) {</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">compare</span>(arr[i]<span class="op">,</span> arr[i<span class="op">+</span><span class="dv">1</span>]) <span class="op">!==</span> <span class="fu">compare</span>(arr[<span class="dv">0</span>]<span class="op">,</span> arr[<span class="dv">1</span>])) {</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> i</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]) <span class="op">===</span> <span class="op">-</span><span class="dv">1</span>) <span class="co">// -&gt; true</span></span></code></pre></div>
<p>But Tim, you could have made the same mistake in the functional code! True, let’s see if it plays out differently. Let’s say I made the mistake of using the entire array as the first one.</p>
<div class="sourceCode" id="cb9" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrder <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> init <span class="op">=</span> arr <span class="co">// should be arr.slice(0, -1)</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> tail <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> pairs <span class="op">=</span> <span class="fu">zip</span>(init<span class="op">,</span> tail)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> pairs<span class="op">.</span><span class="fu">findIndex</span>(([x<span class="op">,</span> y]) <span class="kw">=&gt;</span> {</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> [firstX<span class="op">,</span> firstY] <span class="op">=</span> pairs[<span class="dv">0</span>]</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">compare</span>(x<span class="op">,</span> y) <span class="op">!==</span> <span class="fu">compare</span>(firstX<span class="op">,</span> firstY)</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  })</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]) <span class="op">===</span> <span class="op">-</span><span class="dv">1</span>) <span class="co">// -&gt; false</span></span></code></pre></div>
<p>Now that the code fails in the same way, how would I discover this mistake and debug it? Well, I could easily print out the list of pairs to see if it looks right.</p>
<div class="sourceCode" id="cb10" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrder <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> init <span class="op">=</span> arr</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> tail <span class="op">=</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">const</span> pairs <span class="op">=</span> <span class="fu">zip</span>(init<span class="op">,</span> tail)</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;pairs:&#39;</span><span class="op">,</span> pairs)</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> pairs<span class="op">.</span><span class="fu">findIndex</span>(([x<span class="op">,</span> y]) <span class="kw">=&gt;</span> {</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> [firstX<span class="op">,</span> firstY] <span class="op">=</span> pairs[<span class="dv">0</span>]</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">compare</span>(x<span class="op">,</span> y) <span class="op">!==</span> <span class="fu">compare</span>(firstX<span class="op">,</span> firstY)</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>  })</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]) <span class="op">===</span> <span class="op">-</span><span class="dv">1</span>) <span class="co">// -&gt; false</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a><span class="co">// pairs: [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ], [ 5, undefined ] ]</span></span></code></pre></div>
<p>From here, I can easily tell the last pair shouldn’t be there, so the arrays need to be the same length to fix it.</p>
<p>In contrast, how would I debug the imperative code?</p>
<div class="sourceCode" id="cb11" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrder <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> arr<span class="op">.</span><span class="at">length</span><span class="op">;</span> i<span class="op">++</span>) { <span class="co">// should be: i &lt; arr.length - 1</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">compare</span>(arr[i]<span class="op">,</span> arr[i<span class="op">+</span><span class="dv">1</span>]) <span class="op">!==</span> <span class="fu">compare</span>(arr[<span class="dv">0</span>]<span class="op">,</span> arr[<span class="dv">1</span>])) {</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> i</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="fu">breakingTheOrder</span>([<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span>]) <span class="op">===</span> <span class="op">-</span><span class="dv">1</span>) <span class="co">// -&gt; false</span></span></code></pre></div>
<p>For me, this code is much more difficult to debug. It’s hard to decide what to print first: <code>i</code>, <code>arr[i]</code>, or <code>arr[i+1]</code>. And then I have to sift through the many lines in the console because the printing is inside a loop.</p>
<p>Now, you may be wondering why the imperative code is shorter than the functional code. Make no mistake, this is not inherent to the paradigm; I simply decided to use more variables in the functional code and wrote the imperative version idiomatically. Here is a more similar comparison:</p>
<div class="sourceCode" id="cb12" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> zip <span class="op">=</span> (xs<span class="op">,</span> ys) <span class="kw">=&gt;</span> xs<span class="op">.</span><span class="fu">map</span>((_<span class="op">,</span> i) <span class="kw">=&gt;</span> [ xs[i]<span class="op">,</span> ys[i] ])</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> compare <span class="op">=</span> (x<span class="op">,</span> y) <span class="kw">=&gt;</span> (</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&lt;</span> y <span class="op">?</span> <span class="st">&#39;LT&#39;</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> x <span class="op">&gt;</span> y <span class="op">?</span> <span class="st">&#39;GT&#39;</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <span class="st">&#39;EQ&#39;</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrderFunctional <span class="op">=</span> arr <span class="kw">=&gt;</span> (</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">zip</span>(arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">0</span><span class="op">,</span> <span class="op">-</span><span class="dv">1</span>)<span class="op">,</span> arr<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>))</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">findIndex</span>(([x<span class="op">,</span> y]) <span class="kw">=&gt;</span> <span class="fu">compare</span>(x<span class="op">,</span> y) <span class="op">!==</span> <span class="fu">compare</span>(arr[<span class="dv">0</span>]<span class="op">,</span> arr[<span class="dv">1</span>]))</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>)</span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> breakingTheOrderImperative <span class="op">=</span> arr <span class="kw">=&gt;</span> {</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> (<span class="kw">let</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> arr<span class="op">.</span><span class="at">length</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> i<span class="op">++</span>) {</span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="fu">compare</span>(arr[i]<span class="op">,</span> arr[i<span class="op">+</span><span class="dv">1</span>]) <span class="op">!==</span> <span class="fu">compare</span>(arr[<span class="dv">0</span>]<span class="op">,</span> arr[<span class="dv">1</span>])) {</span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> i</span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h1 data-number="5" id="final-thoughts"><span class="header-section-number">5</span> Final Thoughts</h1>
<p>I mentioned Haskell a few times, because it always comes to mind when I’m solving coding challenges like this. When I first learned Haskell and started practicing with challenges on <a href="https://www.codewars.com/">Codewars</a>, it felt really different from any other language I had used–in fact it often felt like cheating. Haskell’s built-in library is so well-equipped that you really feel handicapped when you go back to other languages. And this has to do with the power of functional programming, which comes from abstracting patterns and recognizing these patterns in the wild. Once you harness that ability, solving problems becomes really easy. You get to know which functions and techniques come up a lot and how to recognize the situations to use them. Like the concept of zipping a list together with its shifted self (I never would have thought of it before using Haskell!).</p>
<p>With all this talk about Haskell, it’s only fair to show the equivalent Haskell solution.</p>
<h2 data-number="5.1" id="haskell-solution"><span class="header-section-number">5.1</span> Haskell Solution</h2>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (findIndex)</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Maybe</span> (fromMaybe)</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="ot">breakingTheOrder ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>breakingTheOrder lst <span class="ot">=</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  fromMaybe (<span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">$</span> findIndex ( \(x, y) <span class="ot">-&gt;</span> <span class="fu">compare</span> x y <span class="op">/=</span> <span class="fu">compare</span> (lst <span class="op">!!</span> <span class="dv">0</span>) (lst <span class="op">!!</span> <span class="dv">1</span>) )</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">$</span> <span class="fu">zip</span> (<span class="fu">init</span> lst) (<span class="fu">tail</span> lst)</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">10</span>, <span class="dv">9</span>, <span class="dv">8</span>, <span class="dv">7</span>, <span class="dv">9</span>, <span class="dv">10</span>] <span class="op">==</span> <span class="dv">3</span></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">4</span>, <span class="dv">7</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">1</span>] <span class="op">==</span> <span class="dv">3</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>] <span class="op">==</span> <span class="op">-</span><span class="dv">1</span></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">10</span>, <span class="dv">11</span>, <span class="dv">12</span>, <span class="dv">12</span>, <span class="dv">13</span>] <span class="op">==</span> <span class="dv">2</span></span></code></pre></div>
<p>However, if this were really a problem to solve in a Haskell mindset, the problem should be tweaked a bit. Instead of returning <code>-1</code> in the case where the ordering doesn’t break, we can use a <code>Maybe</code> type of value. So, return an index number where the ordering breaks, or nothing. This is naturally what Haskell’s <code>findIndex</code> function is built around; maybe finding an index. The new solution is even simpler:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (findIndex)</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="ot">breakingTheOrder ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Int</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>breakingTheOrder lst <span class="ot">=</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  findIndex ( \(x, y) <span class="ot">-&gt;</span> <span class="fu">compare</span> x y <span class="op">/=</span> <span class="fu">compare</span> (lst <span class="op">!!</span> <span class="dv">0</span>) (lst <span class="op">!!</span> <span class="dv">1</span>) )</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">$</span> <span class="fu">zip</span> (<span class="fu">init</span> lst) (<span class="fu">tail</span> lst)</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">10</span>, <span class="dv">9</span>, <span class="dv">8</span>, <span class="dv">7</span>, <span class="dv">9</span>, <span class="dv">10</span>] <span class="op">==</span> <span class="dt">Just</span> <span class="dv">3</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">4</span>, <span class="dv">7</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">1</span>] <span class="op">==</span> <span class="dt">Just</span> <span class="dv">3</span></span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>, <span class="dv">4</span>, <span class="dv">5</span>] <span class="op">==</span> <span class="dt">Nothing</span></span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span> <span class="op">$</span> breakingTheOrder [<span class="dv">10</span>, <span class="dv">11</span>, <span class="dv">12</span>, <span class="dv">12</span>, <span class="dv">13</span>] <span class="op">==</span> <span class="dt">Just</span> <span class="dv">2</span></span></code></pre></div>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Fri, 26 Aug 2022 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/breaking-the-order-coding-challenge-analysis-1.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>
<item>
    <title>Imperative vs Declarative With Pumpkin Pie</title>
    <link>https://timjohns.ca/imperative-vs-declarative-with-pumpkin-pie.html</link>
    <description><![CDATA[<main>
  <article id="blog-post">
    <header>
      <h1 class="writing">
        Imperative vs Declarative With Pumpkin Pie
      </h1>
      <p class="writing">Jun 30, 2022</p>
      
    </header>
	<img class="post-image" alt="drawing of pumpkin pie" src="./images/blog/pumpkin_pie.jpg" />
    <section class="content writing">
	  <p>The discussion of <strong>imperative</strong> vs <strong>declarative</strong> programming comes up a lot. The difference between the two paradigms can be confusing. I often see examples that present an unfair comparison or are plain wrong. It’s time to set the record straight. The declarative paradigm is not about conveying less information; that’s <strong>abstraction</strong> (more about that later). It’s about conveying information in a different way.</p>
<h1 id="definitions">Definitions</h1>
<p>First, an introduction or reminder of what defines declarative and imperative clauses in plain English.</p>
<h2 id="declarative">Declarative</h2>
<p><strong>Declarative</strong> clauses most commonly function as <strong>statements</strong>. The usual word order is: subject, then verb, then other elements. Declaratives can be affirmative or negative. They make statements about how things are and how they are not.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<p>Examples:</p>
<ul>
<li>I saw them last week.</li>
<li>Some courses begin in January.</li>
<li>The door was left open.</li>
<li>Those are not the only tickets left.</li>
<li>You could pass me the spoon.</li>
<li>I am happy.</li>
<li>x is equal to 5.</li>
</ul>
<h2 id="imperative">Imperative</h2>
<p><strong>Imperative</strong> clauses most commonly function as <strong>commands</strong>, <strong>instructions</strong>, or <strong>orders</strong>. They usually begin with a verb. We do not usually include the subject in an imperative clause.<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> In the context of programming, the implied subject is the computer running the code.</p>
<p>Examples:</p>
<ul>
<li>Go see them!</li>
<li>Don’t begin a course in january.</li>
<li>Don’t leave the door open.</li>
<li>Get the last tickets.</li>
<li>Pass me the spoon.</li>
<li>Be happy.</li>
<li>Set x to 5.</li>
</ul>
<h1 id="pumpkin-pie">Pumpkin Pie</h1>
<p>Before we get to code comparisons, let’s look at a plain English example using delicious pumpkin pie.</p>
<h2 id="ingredients">Ingredients</h2>
<ul>
<li>3 egg yolks</li>
<li>1 large egg</li>
<li>1/2 teaspoon salt</li>
<li>2 teaspoons ground cinnamon</li>
<li>1 teaspoon ground ginger</li>
<li>1/4 teaspoon ground nutmeg</li>
<li>1/4 teaspoon ground cloves</li>
<li>1 (15 ounce) can of pumpkin puree</li>
<li>1 (12 oz.) can of evaporated milk</li>
<li>1 frozen pie crust</li>
</ul>
<h2 id="imperative-recipe">Imperative Recipe</h2>
<ol>
<li>Preheat oven to 425 degrees F (220 degrees C).</li>
<li>Whisk together pumpkin puree, egg yolks, and egg in a large bowl. Add evaporated milk, cinnamon, ginger, cloves, nutmeg, and salt; whisk until thoroughly combined.</li>
<li>Fit pie crust in a 9-inch pie plate and crimp edges.</li>
<li>Pour filling into the pie shell and lightly tap on the work surface to release any air bubbles.</li>
<li>Bake in the preheated oven for 15 minutes.</li>
<li>Reduce heat to 350 degrees F (175 degrees C) and bake until just set in the middle, 30 to 40 more minutes. Allow to cool completely before serving.</li>
</ol>
<h2 id="declarative-recipe">Declarative Recipe</h2>
<ul>
<li>The base is the pumpkin puree, egg yolks, and egg whisked together in a large bowl.</li>
<li>The filling is evaporated milk, cinnamon, ginger, cloves, nutmeg, and salt whisked into the base until thoroughly combined.</li>
<li>The pie shell is the pie crust fit in a 9-inch pie plate with crimped edges.</li>
<li>The raw pie is the pie shell with the filling poured in and lightly tapped to release any air bubbles.</li>
<li>The semi-cooked pie is the raw pie baked in an oven preheated at 425 degrees F for 15 minutes.</li>
<li>The cooked pie is the semi-cooked pie baked at 350 degrees F for 30 to 40 minutes.</li>
<li>The cooked pie can be served after being allowed to cool completely.</li>
</ul>
<h2 id="whats-the-difference">What’s the difference?</h2>
<p>As you can see, the imperative recipe is a set of step-by-step instructions. They are intended to be followed in the written order. In contrast, the declarative recipe is a set of statements. They each simply state a fact about the pumpkin pie, or some part of it. The statements can be rearranged and read in any order.</p>
<blockquote>
<p><strong>Declarative Recipe (Rearranged)</strong></p>
<ul>
<li>The cooked pie can be served after being allowed to cool completely.</li>
<li>The raw pie is the pie shell with the filling poured in and lightly tapped to release any air bubbles.</li>
<li>The base is the pumpkin puree, egg yolks, and egg whisked together in a large bowl.</li>
<li>The pie shell is the pie crust fit in a 9-inch pie plate with crimped edges.</li>
<li>The cooked pie is the semi-cooked pie baked at 350 degrees F for 30 to 40 minutes.</li>
<li>The semi-cooked pie is the raw pie baked in an oven preheated at 425 degrees F for 15 minutes.</li>
<li>The filling is evaporated milk, cinnamon, ginger, cloves, nutmeg, and salt whisked into the base until thoroughly combined.</li>
</ul>
</blockquote>
<p>If you want to end up with a finished pie, you will end up reading every statement in the end because of how they depend on each other for information. These dependencies are the key to forcing some kind of order. In fact, you will end up doing the steps in the same order as the imperative recipe.</p>
<p>Something interesting to notice is that the declarative recipe does not force the baker to start by preheating the oven. It would still work to preheat the oven after making the raw pie, but we would miss out on the potential time savings by preheating the oven as the first step and multitasking. This is similar to optimizations that programming compilers do; things that programmers shouldn’t need to worry about.</p>
<h1 id="programming-comparison-javascript">Programming comparison (JavaScript)</h1>
<p>The difference between imperative and declarative programming is defined by the concept of state.<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a> <a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a> Imperative programming involves the use of explicit state, which is information that gets remembered over time.<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a> Declarative programming is described as stateless. We can use recursion in (functional) declarative programming, which can be thought of as keeping implicit state, but since the context changes with each recursive call of a function there isn’t an explicit state that is persisting over the entire operation.</p>
<p>Now let’s compare imperative and declarative code. I’m choosing to use JavaScript because the language caters to both imperative and declarative ways of writing code.</p>
<h2 id="get-even-numbers-imperative">Get even numbers, imperative</h2>
<p>The goal is to get all the even numbers from a given list of numbers.</p>
<div class="sourceCode" id="cb1" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> numbers <span class="op">=</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]<span class="op">;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> even <span class="op">=</span> x <span class="kw">=&gt;</span> x <span class="op">%</span> <span class="dv">2</span> <span class="op">===</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> evensImperative <span class="op">=</span> []<span class="op">;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> (<span class="kw">const</span> num <span class="kw">of</span> numbers) {</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (<span class="fu">even</span>(num)) {</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    evensImperative<span class="op">.</span><span class="fu">push</span>(num)<span class="op">;</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(evensImperative)<span class="op">;</span></span></code></pre></div>
<p>The explicit state is <code>evensImperative</code>, which changes its value over time, accumulating all the even numbers.</p>
<h2 id="get-even-numbers-declarative-version-1">Get even numbers, declarative version 1</h2>
<p>The same goal, using (functional) declarative programming.</p>
<div class="sourceCode" id="cb2" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> numbers <span class="op">=</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]<span class="op">;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> even <span class="op">=</span> x <span class="kw">=&gt;</span> x <span class="op">%</span> <span class="dv">2</span> <span class="op">===</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> getEvens <span class="op">=</span> (xs<span class="op">,</span> acc) <span class="kw">=&gt;</span> (</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  (xs<span class="op">.</span><span class="at">length</span> <span class="op">===</span> <span class="dv">0</span>) <span class="op">?</span> acc</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <span class="fu">even</span>(xs[<span class="dv">0</span>]) <span class="op">?</span> <span class="fu">getEvens</span>(xs<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)<span class="op">,</span> [<span class="op">...</span>acc<span class="op">,</span> xs[<span class="dv">0</span>]])</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">:</span> <span class="fu">getEvens</span>(xs<span class="op">.</span><span class="fu">slice</span>(<span class="dv">1</span>)<span class="op">,</span> acc)</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>)<span class="op">;</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> evensDeclarative <span class="op">=</span> <span class="fu">getEvens</span>(numbers<span class="op">,</span> [])<span class="op">;</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(evensDeclarative)<span class="op">;</span></span></code></pre></div>
<p>I consider this version to be the most fair comparison. To accomplish the task, we define a function that uses recursion to build a new list of only even numbers from the given list. Any version which refines the code to use the help of other functions is using the principal of abstraction. It would not be <em>more declarative</em>, but rather more abstract.</p>
<h2 id="get-even-numbers-declarative-version-2">Get even numbers, declarative version 2</h2>
<p>Using <code>reduce</code> is a refinement on the previous version, a step up in abstraction. Reduce is a more specific, yet still quite expressive, function to transform an array into something new.</p>
<div class="sourceCode" id="cb3" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> numbers <span class="op">=</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]<span class="op">;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> even <span class="op">=</span> x <span class="kw">=&gt;</span> x <span class="op">%</span> <span class="dv">2</span> <span class="op">===</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> evensDeclarative <span class="op">=</span> numbers<span class="op">.</span><span class="fu">reduce</span>((acc<span class="op">,</span> x) <span class="kw">=&gt;</span> (</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">even</span>(x) <span class="op">?</span> [<span class="op">...</span>acc<span class="op">,</span> x] <span class="op">:</span> acc</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>)<span class="op">,</span> [])<span class="op">;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(evensDeclarative)<span class="op">;</span></span></code></pre></div>
<h2 id="get-even-numbers-declarative-version-3">Get even numbers, declarative version 3</h2>
<p>For even more refinement, the most idiomatic functional solution to this problem is to use a filtering function, which is commonly provided in functional languages.</p>
<div class="sourceCode" id="cb4" data-org-language="js"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> numbers <span class="op">=</span> [<span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">,</span> <span class="dv">10</span>]<span class="op">;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> even <span class="op">=</span> x <span class="kw">=&gt;</span> x <span class="op">%</span> <span class="dv">2</span> <span class="op">===</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> evensDeclarative <span class="op">=</span> numbers<span class="op">.</span><span class="fu">filter</span>(even)<span class="op">;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(evensDeclarative)<span class="op">;</span></span></code></pre></div>
<h1 id="so-which-one-is-better">So which one is better?</h1>
<p>One is not necessarily better than the other, but it’s fun to think about how they are different depending on the context.</p>
<p>An important distinction is the difference in goals between recipes and programming. For cooking recipes, the goal is to give instructions to a human to follow. Imperative recipes are naturally easier because we need to perform step-by-step actions in the end. Trying to bake a pumpkin pie based on the declarative recipe would involve translating the statements into a sequence of steps, making us do extra work. However, in programming, the goal is not to tell the computer what steps to take to solve a problem. The goal is to write a solution to a problem and have the computer execute it, however it may. The fact that computers run imperatively at their lowest level doesn’t matter because it is abstracted away by the compiler, so the solutions we write can be in any paradigm, imperative or declarative.</p>
<p>One difference when we write things in a declarative way is that it becomes easier to <strong>break the problem down</strong>, which is extremely helpful in both finding and verifying a solution. Looking at the declarative recipe, we can see each statement as its own small piece of the recipe. And each of those can be broken down further into smaller pieces if necessary. When each statement is very small, it’s easy to look at it and see that it is correct, thus it becomes easy to verify that the entire solution is correct. At the same time, the dependency structure of the statements can be analyzed to verify that the entire solution makes sense and is not missing any pieces.</p>
<p>Another consequence of this breaking down of problems is the ability to <strong>reuse</strong> the pieces. An individual statement might be pulled apart from the solution as a whole and be reused to solve another problem. For example, the declarative pumpkin pie talks about the filling. Maybe we want to use a blueberry filling instead. If we have a similar declarative recipe for blueberry pie, we can simply swap in the blueberry pie’s filling and leave the rest the same. Now we have a blueberry pie recipe! (This won’t actually work for the given pumpkin pie recipe because it’s too different from making blueberry pie, but I hope the point still stands.)</p>
<p>To make all of this more clear, imagine you’re the pumpkin pie baker and you have 3 helpers. It’s your job to assign each helper their own tasks so all your jobs are easier. With the imperative recipe, you would need to have a good idea of the all the steps before you can decide how to assign tasks to your helpers. You can’t simply say to one, “It’s your job to pour the filling into the pie shell” without also explaining when that needs to happen and what the filling is. With the declarative recipe, you can assign the task “Make the raw pie” to one helper, with the relevant statement “The raw pie is the pie shell with the filling poured in and lightly tapped to release any air bubbles.” When the helper asks, “What is the filling?” you can simply direct them to the helper who has the task of making the filling. All of the statements can be assigned as tasks to whoever you want and the information will sort itself out.</p>
<h1 id="what-about-abstraction">What about abstraction?</h1>
<p>Even though the declarative paradigm does not force abstraction<a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a>, it does seem to lend itself better to it. That’s why so many other examples comparing imperative and declarative unfairly involve abstraction; it’s hard to avoid it! And that’s a good thing. Abstraction is what lets us focus on what’s important and ignore the rest. I don’t know about you, but I can only keep so much information in my head before feeling overwhelmed.</p>
<p>As an example, let’s say you are already familiar with making pumpkin pies. In the declarative recipe, we can remove some statements that you don’t need and leave only the ones you find hard to remember. This is harder to do with the imperative recipe where the dependencies aren’t clear.</p>
<blockquote>
<p><strong>Declarative Recipe (Trimmed)</strong></p>
<ul>
<li>The pie shell is the pie crust fit in a 9-inch pie plate with crimped edges.</li>
<li>The raw pie is the pie shell with the filling poured in and lightly tapped to release any air bubbles.</li>
<li>The semi-cooked pie is the raw pie baked in an oven preheated at 425 degrees F for 15 minutes.</li>
<li>The cooked pie is the semi-cooked pie baked at 350 degrees F for 30 to 40 minutes.</li>
</ul>
</blockquote>
<p>Related to abstraction, the declarative recipe also lets us identify what’s important. With the imperative recipe, it’s hard to tell where things are headed. What’s the point of whisking together the ingredients in a bowl? Are we making a soup at the same time? In the declarative recipe, it’s clear that whisking together the ingredients makes a base, which is then used to make the filling.</p>
<p>In programming, abstraction is even more clear. Whenever we substitute a bunch of code for a function, we’re replacing that code with an abstract blob that we don’t need to look inside. In the even numbers example above, each subsequent declarative version is an abstraction on the previous one. This is easy to do in declarative programming because we can pick any statement and abstract it since we know what things depends on or not. Each statement is like its own bundle of stuff that can be put in a box and closed up. This is very useful and happens <em>a lot</em> in programming.</p>
<h1 id="correcting-the-misinformation">Correcting the misinformation</h1>
<p>I said I’ve seen many examples that don’t do a good job of showing the difference between imperative and declarative programming. Let’s look at a few of them and where they went wrong.</p>
<h2 id="book-essential-linq">Book: “Essential LINQ”</h2>
<p>(Calvert, C., &amp; Kulkarni, D. (2009). Essential LINQ. Addison-Wesley Professional)</p>
<blockquote>
<p>Imperative programming requires developers to define step by step how code should be executed. To give directions in an imperative fashion, you say, “Go to 1st Street, turn left onto Main, drive two blocks, turn right onto Maple, and stop at the third house on the left.” The declarative version might sound something like this: “Drive to Sue’s house.” One says how to do something; the other says what needs to be done.</p>
</blockquote>
<p>“Drive to Sue’s house” is a command, so this example is clearly wrong. Not to mention the information provided in the two versions isn’t the same. Sue isn’t even mentioned in the imperative directions.</p>
<h2 id="imperative-vs-declarative-programming-post-by-tyler-mcginnis"><a href="https://ui.dev/imperative-vs-declarative-programming">Imperative vs Declarative Programming</a>, post by Tyler McGinnis</h2>
<blockquote>
<p>“Imperative programming is like how you do something, and declarative programming is more like what you do.”</p>
</blockquote>
<p>I don’t find that definition helpful because “what you do” seems confusing or plain wrong. Declarative programming is something that people do, but that can’t be what it means. Maybe it means “what you tell the computer to do”, but that sounds like a command which makes it imperative. I don’t know how to interpret this. I know this definition isn’t meant to be taken seriously, but I think it makes things even less clear.</p>
<blockquote>
<p>An imperative approach (HOW): “I see that table located under the Gone Fishin’ sign is empty. My husband and I are going to walk over there and sit down.”</p>
<p>A declarative approach (WHAT): “Table for two, please.”</p>
</blockquote>
<p>Is it just me or are these backwards? The first one is a couple of statements (declarative) and the second one is a command (imperative).</p>
<p>Sorry Tyler, I’m a fan of your work, but I think you got this concept wrong. To be honest, I think the only part of the post that is right is the collection of definitions at the end, which the rest of the post doesn’t properly take into consideration.</p>
<h2 id="stack-overflow-accepted-answer-to-difference-between-declarative-and-imperative-in-reactjs">Stack Overflow accepted answer to “Difference between declarative and imperative in React.js?”</h2>
<p><a href="https://stackoverflow.com/a/33656983">https://stackoverflow.com/a/33656983</a></p>
<blockquote>
<p>Imagine you have a butler, who is kind of a metaphor for a framework. And you would like to make dinner. In an imperative world, you would tell them step by step how to make dinner. You have to provide these instructions:</p>
<pre class="example"><code>
Go to the kitchen
Open fridge
Remove chicken from fridge
...
Bring food to the table

</code></pre>
<p>In a declarative world, you would simply describe what you want</p>
<pre class="example"><code>
I want dinner with chicken.
</code></pre>
</blockquote>
<p>A more fair declarative version would be “I want chicken from the fridge which is in the kitchen, and I want to eat it at the table.”</p>
<blockquote>
<p>If your butler doesn’t know how to make chicken, then you cannot operate in a declarative style.</p>
</blockquote>
<p>This doesn’t make sense. As we’ve seen, we can easily translate an imperative recipe to a collection of statements, which the butler can be told.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p><a href="https://dictionary.cambridge.org/grammar/british-grammar/clause-types">Cambridge Dictionary</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p><a href="https://dictionary.cambridge.org/grammar/british-grammar/clause-types">Cambridge Dictionary</a><a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p><a href="https://sci-hub.hkvisa.net/10.1007/978-3-642-01862-6_29">Fahland, D., Lübke, D., Mendling, J., Reijers, H., Weber, B., Weidlich, M., &amp; Zugal, S. (2009). Declarative versus Imperative Process Modeling Languages: The Issue of Understandability. Lecture Notes in Business Information Processing, 353–366.</a><a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p>Roy, P.V., Haridi, S.: Concepts, Techniques, and Models of Computer Programming. MIT Press, Cambridge (2004)<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5"><p><a href="https://www.info.ucl.ac.be/~pvr/paradigms.html">https://www.info.ucl.ac.be/~pvr/paradigms.html</a><a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6"><p>As far as I can tell, this is true in general terms. However, in computing, declarative programming is an abstraction on low-level machine code which is imperative. But high-level imperative programming languages are far abstracted from machine code as well. So let’s compare apples to apples and leave the low-level oranges to the machine… or something.<a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
    </section>
	<section class="read-more">
	  <a href="/blog.html" class="btn btn-primary">Read More</a>
	</section>
    <section class="newsletter">
      <script async data-uid="3c58182786" src="https://tim-johns.ck.page/3c58182786/index.js"></script>
    </section>
  </article>
</main>
]]></description>
    <pubDate>Thu, 30 Jun 2022 00:00:00 UT</pubDate>
    <guid>https://timjohns.ca/imperative-vs-declarative-with-pumpkin-pie.html</guid>
    <dc:creator>Tim Johns</dc:creator>
</item>

    </channel>
</rss>
