<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="/notepad/feed.xml" rel="self" type="application/atom+xml" /><link href="/notepad/" rel="alternate" type="text/html" /><updated>2026-04-15T22:04:41+00:00</updated><id>/notepad/feed.xml</id><title type="html">Andrew’s Notepad</title><subtitle>Its a blog!</subtitle><entry><title type="html">I left for Moho, but forgot to bring fuel</title><link href="/notepad/2026/04/10/moho.html" rel="alternate" type="text/html" title="I left for Moho, but forgot to bring fuel" /><published>2026-04-10T00:00:00+00:00</published><updated>2026-04-10T00:00:00+00:00</updated><id>/notepad/2026/04/10/moho</id><content type="html" xml:base="/notepad/2026/04/10/moho.html"><![CDATA[<div style="display:flex;justify-content:center;">
<img src="/notepad/img/2026-04-10/Moho_delta_v_map.png" width="50%" />
</div>

<p>This is a story of a really poorly executed Moho mission. Getting to Moho is hard. If you try do it with a direct Hohmann transfer, then the $\Delta v$ map tells us you need a whopping $16,670m/s$ of $\Delta v$. That’s a big rocket and I don’t want to spend any money. So I’m going to send this rocket instead:</p>

<h2 id="the-rocket">The Rocket</h2>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_001_VAB.jpg" width="75%" /></div>

<p>According to the VAB, the rocket has $9640m/s$ of $\Delta v$ broken down as follows</p>

<ul>
  <li>$883 + 2039 = 2935 m/s$ for the lifter.</li>
  <li>$1937 + 1916 = 3853 m/s$ for the transfer stage</li>
  <li>$2866 m/s$ for the lander. The lander actually has $1909m/s$ of $\Delta v$ on board, but the VAB shows a higher number because there is no kerbal in the chair.</li>
</ul>

<p>All in all, to get to Moho and back, we have three FL-T400 fuel tanks and a terrier, which gives $3,853 m/s$ of $\Delta v$. This is a little short of the $11,530m/s$ that we need according to the map. I’m going to go anyway and see what happens.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_002_LKO.jpg" width="75%" /></div>

<h2 id="aside-gravity-assists">Aside: Gravity assists</h2>

<p>To get to Moho, I’m going to use a lot of gravity assists. When you pass by a planet, it bends your trajectory. Bending your trajectory changes your velocity. Normally you would have to fire your engines to change your velocity. Therefore passing by a planet gives us $\Delta v$ for free.</p>

<p>Most tutorials for gravity assists online say to “just play around with maneuver nodes and you’ll get better at it” but I don’t find this answer very satisfying. Instead I have distilled the following 6 rules to help me plan what assists to use before I take off:</p>

<ol>
  <li>You enter a sphere of influence with the same speed you exit</li>
  <li>If you do two assists in the same location, you will enter the second assist with the velocity you exited the first</li>
  <li>The greater the mass of the body, the more it can bend your trajectory in a single assist</li>
  <li>The greater the relative speed, the more you can get out of assists</li>
  <li>High inclinations and oblique angles means greater relative speed</li>
  <li>Fly to where you want the encounter to be, rather than where the planet is.</li>
</ol>

<h2 id="getting-to-eve">Getting to Eve</h2>

<p>Firstly, I take off from Kerbin. With a decent ascent, I am left with $95m/s$ of $\Delta v$ on the main stage. I don’t wait for an Eve transfer window. Instead I want to use rule #6</p>

<blockquote>
  <p>6. Fly to where you want the encounter to be, rather than where the planet is</p>
</blockquote>

<p>I want to use Eve to perform an inclination change, and to do that, Eve needs to be at the ascending or descending node of Moho.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_003_Eve_Burn.jpg" width="75%" /></div>

<p>To get an Eve encounter, I create one maneuver node where my orbit intersects Eve’s, and a dummy maneuver node where I use the “+/- orbit” buttons to search forward a few orbits for close encounters. This means I can make a small burn to get an encounter anywhere along Eve’s orbit. When doing precise burns such as this one, it helps to set the thrust limiter on the engine to 1%.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_004_Eve_encounter.jpg" width="75%" /></div>

<p>When I intercept Eve, I have a larger orbit. That means I will be going faster than Eve. To get to Moho, I want to go slower than Eve. Basically I want to perform a U turn around Eve so that all of my forward speed is converted into backwards speed.</p>

<p>I burn $887m/s$ of $\Delta v$ close to Eve to get a Moho Encounter. In tital, I use $2354 m/s$ to get a Moho encounter from Low Kerbin orbit. This is a saving of $1876 m/s$ compared to a direct transfer.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_moho_intercept.jpg" width="75%" /></div>

<h2 id="eve-to-moho">Eve to Moho</h2>

<p>Once I have a Moho intercept, I want to kill as much relative velocity as possible. On the surface this seems impossible due to rules #1 and #2 which imply that no matter how many assists I do, I will always end up with the same relative velocity.</p>

<blockquote>
  <p>1. You enter a sphere of influence with the same speed you exit
2. If you do two assists in the same location, you will enter the second assist with the velocity you exited the first</p>
</blockquote>

<p>I can use a Moho assist to lower my apoapsis, but this also causes the orbit to become more oblique. The net result is that my relative velocity is unchanged, and I am back to square one.</p>

<p>Luckily for me, I can use rule #5 in reverse:</p>

<blockquote>
  <p>5. High inclinations and oblique angles means greater relative speed</p>
</blockquote>

<p>If high inclinations and oblique angles mean larger relative speed, then low inclinations and narrow angles mean low relative speed. I can perform deep space prograde burns at apoapsis to reduce the angle of intercept, and reduce my relative velocity.</p>

<p>Therefore, I can alternate assists and deep space burns to descend to Moho efficiently. I double dip and use the deep space burns to get Moho intercepts, so I don’t waste much fuel. I have to do three or four of these maneuver to get my relative speed down to something acceptable.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_down_to_moho.jpg" width="75%" /></div>

<h2 id="using-a-lander">Using a lander</h2>

<p>When I get to Moho, I can send down a small lander instead of landing the whole ship. This is a basic technique that you can use anywhere to give a good $\Delta v$ saving.</p>

<p>Additionally, it takes 310 m/s of $\Delta v$ to circularise my orbit once I capture into Moho. If I detach the lander in an elliptical orbit, I can save another chunk of mothership fuel at the expense of fuel in the lander. Again, this is a good choice to save $\Delta v$.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_landing.jpg" width="75%" /></div>

<p>Rendezvous in an elliptical orbit is a bit harder, but not impossible. I can use the same technique we use to get an encounter with a planet. One maneuver node where you want the intercept, and another maneuver node to search a few orbits ahead.</p>

<p>This is made more difficult by the fact that the lander doesn’t have enough fuel. I need $(310 + 870) * 2 = 2360 m/s$ of $\Delta v$ but my lander has $1909m/s$ of $\Delta v$ onboard. I’m going to have to use the EVA jetpack to make orbit and rendezvous, which means no maneuver nodes.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_rendezvous.jpg" width="75%" /></div>

<p>I <em>just</em> make the rendezvous with fumes in the EVA jetpack tank. I had to use some of the mothership fuel to make the rendezvous, but that’s OK. Next time, I know to bring extra EVA jetpack fuel.</p>

<h2 id="getting-back">Getting Back</h2>

<p>Moho assists can be used to get back, I simply apply the Moho descent technique in reverse: burn retrograde at solar apoapsis to get a Moho encounter, and then use the encounter to raise my apoapsis. Repeat as many times is necessary to get the orbit to the level of Eve.</p>

<p>Once I have an Eve encounter, I can use that to assist to raise my orbit to the level of Kerbin. In some cases, I’ve needed two Eve assists to do this, but in this run, I managed it with only one assist. Once I have a Kerbin encounter, I can aerobrake down to the surface, as long as I have heat protection</p>

<h2 id="as-long-as-i-have-heat-protection">As long as I have heat protection</h2>

<p>I get a Kerbin encounter with $209m/s$ of $\Delta v$ to spare. This is plenty if your heat shilds work, which they didn’t. The RC-001S sticks out to the side and overheats, destroying the whole craft. Instead, I aerobrake at the lowest altitude possible using the terrier as a heat shield.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_kerbin_aerobrake.jpg" width="75%" /></div>

<p>After spending all of my $\Delta v$ slowing down, it’s still not enough, so I get out and push the craft to get a Kerbin capture. After multiple aerobraking passes, I finally touch down at last. After 30 years in the command pod, Valentina is finally home.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_home.jpg" width="75%" /></div>

<h2 id="post-mortem">Post Mortem</h2>

<p>With any terrible mission, we should reflect on what we can do better and improve it for next time</p>

<h3 id="bring-extra-eva-fuel">Bring extra EVA fuel</h3>

<p>For dubious missions like this one, it’s always a good idea to bring extra EVA canisters. This gives you an extra $300m/s$ of $\Delta v$ to work with in the jetpack at the expense of not having a personal parachute. If you still want a parachute for safety, put it in the command module inventory and equip it before re-entry in case you need to bail out.</p>

<p>Note: if you do ever have to bail out, don’t forget to take your science with you!</p>

<h3 id="use-larger-heat-shields">Use larger heat shields</h3>

<p>The RC-001S extends past the outside fo the 1.25m heat shield, making it effectively worthless. Testing reveals that a 1.875m heat shield protects the core sufficiently for re-entry. Alternatively, you can drop the probe core with the terrier engine.</p>

<p>In general, using heat shields with the exact diameter of the part it protects is dicey, since you are unprotected if the craft tilts to one side for any reason. Command pods are an exception, since they are conical in shape.</p>

<h3 id="unpowered-eve-assist">Unpowered Eve assist</h3>

<p>To get to Moho, I used a powered Eve assist, but ignored rules #4 and $5:</p>

<blockquote>
  <p>4. The greater the relative speed, the more you can get out of assists
5. High inclinations and oblique angles means greater relative speed</p>
</blockquote>

<p>If I increase the angle between my orbit and Eve’s, I give myself more relative velocity to work with and I can use an unpowered assist instead. This costs me about $200m/s$ of $\Delta v$ during my escape burn from Kerbin, but saves the $890m/s$ burn at Eve.</p>

<div style="display:flex;justify-content:center;"><img src="/notepad/img/2026-04-10/Moho_unpowered_eve.jpg" width="75%" /></div>

<p>Overall, I got a Moho encounter from low Kerbin orbit in $1524m/s$. This is a saving of $2706m/s$ compared to a direct Hohmann transfer and $830m/s$ compared to a powered assist.</p>

<h2 id="summary">Summary</h2>

<p>Using gravity assists, a lander, and the EVA jetpack, we save a lot of delta V getting to Moho. This allows us to send a really cheap rocket there and back. A summary of the techniques used are as follows:</p>

<table>
  <thead>
    <tr>
      <th>New technique</th>
      <th>Cost</th>
      <th>Old technique</th>
      <th>Cost</th>
      <th>Saving</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Eve powered assist</td>
      <td>$2354m/s$</td>
      <td>Kerbin to Moho Hohmann transfer</td>
      <td>$4230m/s$</td>
      <td>$1876m/s$</td>
    </tr>
    <tr>
      <td>Eve unpowered assist</td>
      <td>$1594m/s$</td>
      <td>Kerbin to Moho Hohmann transfer</td>
      <td>$4230m/s$</td>
      <td>$2636m/s$</td>
    </tr>
    <tr>
      <td>Moho self assist capture</td>
      <td>$686m/s$</td>
      <td>Moho capture burn</td>
      <td>$2100m/s$</td>
      <td>$1414m/s$</td>
    </tr>
    <tr>
      <td>Moho self assist escape</td>
      <td>$778m/s$</td>
      <td>Moho to Kerbin Hohmann transfer</td>
      <td>$2100m/s$</td>
      <td>$1632m/s$</td>
    </tr>
    <tr>
      <td>Bring a lander</td>
      <td>$225m/s$</td>
      <td>Land the whole ship</td>
      <td>$1740m/s$</td>
      <td>$1515m/s$</td>
    </tr>
    <tr>
      <td>Only circularize the lander</td>
      <td>$0m/s$</td>
      <td>Circularize the whole ship</td>
      <td>$620m/s$</td>
      <td>$620m/s$</td>
    </tr>
    <tr>
      <td>Use Eva Jetpack</td>
      <td>$0m/s$</td>
      <td>Use lander engines</td>
      <td>$600m/s$</td>
      <td>$600m/s$</td>
    </tr>
  </tbody>
</table>

<p>As with anything in KSP, poorly planned missions sometimes still work out anyway. Nothing that EVA jetpack fuel, gravity assists, and engines-as-heat-shields can’t solve.</p>]]></content><author><name></name></author><category term="Kerbal space program" /><category term="KSP" /><category term="Moho" /><category term="Gravity Assist" /><category term="EVA Jetpack" /><category term="Tutorial" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Understanding Open Recursion and Inheritance</title><link href="/notepad/notes/2021/05/30/open_recursion.html" rel="alternate" type="text/html" title="Understanding Open Recursion and Inheritance" /><published>2021-05-30T00:00:00+00:00</published><updated>2021-05-30T00:00:00+00:00</updated><id>/notepad/notes/2021/05/30/open_recursion</id><content type="html" xml:base="/notepad/notes/2021/05/30/open_recursion.html"><![CDATA[<p>A very functional idea in object orientated programming.</p>

<h3 id="summary">Summary</h3>

<ul>
  <li>Inheritance can be used to override methods.</li>
  <li>This could be used to memoize a recursive function for example.</li>
  <li>Dynamic dispatch can be desugared to continuation passing: a functional concept.</li>
  <li>This style of continuation passing can be denoted as “Open Recursion” because the recursive calls are left open to be overridden.</li>
</ul>

<h2 id="memoization-using-inheritance">Memoization Using Inheritance</h2>

<p>Using inheritance, you can call a base method from a derived class:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Base</span> <span class="p">{</span>
    <span class="nf">a</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Base Method A</span><span class="dl">'</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Derived</span> <span class="kd">extends</span> <span class="nc">Base</span> <span class="p">{</span>
    <span class="nf">b</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Derived Method B</span><span class="dl">'</span><span class="p">);</span>
        <span class="k">super</span><span class="p">.</span><span class="nf">a</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">derived</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Derived</span><span class="p">();</span>
<span class="nx">derived</span><span class="p">.</span><span class="nf">b</span><span class="p">();</span>
</code></pre></div></div>

<p>It’s also possible to do the opposite and call a derived method from a base class:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">Base</span> <span class="p">{</span>
    <span class="nf">a</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Base Method A</span><span class="dl">'</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nf">b</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="kd">abstract</span> <span class="nf">b</span><span class="p">():</span> <span class="k">void</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Derived</span> <span class="kd">extends</span> <span class="nc">Base</span> <span class="p">{</span>
    <span class="nf">b</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Derived Method B</span><span class="dl">'</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">derived</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Derived</span><span class="p">();</span>
<span class="nx">derived</span><span class="p">.</span><span class="nf">a</span><span class="p">();</span>
</code></pre></div></div>

<p>An interesting result is that the base and derived methods can call each other recursively:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Base</span> <span class="p">{</span>
    <span class="nf">method</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Base Method</span><span class="dl">'</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nf">method</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Derived</span> <span class="kd">extends</span> <span class="nc">Base</span> <span class="p">{</span>
    <span class="nf">method</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Derived Method</span><span class="dl">'</span><span class="p">);</span>
        <span class="k">super</span><span class="p">.</span><span class="nf">method</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">derived</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Derived</span><span class="p">();</span>
<span class="nx">derived</span><span class="p">.</span><span class="nf">method</span><span class="p">();</span> <span class="c1">// crashes or runs indefinitely</span>
</code></pre></div></div>

<p>Say I have a recursive function that’s particularly slow to execute, for example a naive implementation of the Fibonacci sequence:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">fib</span><span class="p">(</span><span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="nf">fib</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nf">fib</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>In the tradition of object orientated programming we can put that function into a class:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Fib</span> <span class="p">{</span>
    <span class="nf">call</span><span class="p">(</span><span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">fib</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Fib</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">fib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">fib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">10</span><span class="p">));</span>
<span class="c1">// console.log(fib.call(100)); // will not terminate in any reasonable amount of time</span>
</code></pre></div></div>

<p>One method to make this a lot faster is to memoize the function. Using inheritance, we can override the function and memoize it using a derived class:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MemoFib</span> <span class="kd">extends</span> <span class="nc">Fib</span> <span class="p">{</span>
    <span class="nl">store</span><span class="p">:</span> <span class="nb">Map</span><span class="o">&lt;</span><span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="o">&gt;</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span>

    <span class="nf">call</span><span class="p">(</span><span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">storedResult</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">storedResult</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">storedResult</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">super</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
        <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">memoFib</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MemoFib</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">10</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span> <span class="c1">// runs almost instantaneously</span>
</code></pre></div></div>

<p>We can also reverse the inheritance hierarchy so the function inherits from memoize. This will have slightly different performance characteristics, but allow us to memoize any function we like:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Memoize</span> <span class="p">{</span>
    <span class="nl">store</span><span class="p">:</span> <span class="nb">Map</span><span class="o">&lt;</span><span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="o">&gt;</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span>

    <span class="nf">call</span><span class="p">(</span><span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">storedResult</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">storedResult</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">storedResult</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
        <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">MemoFib</span> <span class="kd">extends</span> <span class="nc">Memoize</span> <span class="p">{</span>
    <span class="nf">call</span><span class="p">(</span><span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="k">super</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="k">super</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">memoFib</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MemoFib</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">10</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span>
</code></pre></div></div>

<p>We could stop here, however, this method is limited. If <code class="language-plaintext highlighter-rouge">Memoize</code> inherits <code class="language-plaintext highlighter-rouge">Fib</code>, the memoize logic is limited to the Fibonacci function, and we have to replicate it for every function we want to memoize. If <code class="language-plaintext highlighter-rouge">Fib</code> inherits <code class="language-plaintext highlighter-rouge">Memoize</code>, then we can’t swap out the kind of memoization we want to use.</p>

<h2 id="overriding-methods-like-this-is-called-open-recursion">Overriding methods like this is called “Open Recursion”</h2>

<p>To see this, we need to make some changes to our code. In OOP, a method call <code class="language-plaintext highlighter-rouge">obj.method(arg)</code> desugars to <code class="language-plaintext highlighter-rouge">method(obj, arg)</code>. We can desugar the <code class="language-plaintext highlighter-rouge">Fib</code> class that way:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Fib</span> <span class="p">{</span>
    <span class="nf">call</span><span class="p">(</span><span class="nb">self</span><span class="p">:</span> <span class="nx">Fib</span><span class="p">,</span> <span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">newFib</span> <span class="o">=</span> <span class="p">():</span> <span class="nx">Fib</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="na">call</span><span class="p">:</span> <span class="p">(</span><span class="na">self</span><span class="p">:</span> <span class="nx">Fib</span><span class="p">,</span> <span class="na">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="nb">self</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nb">self</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>

<p>The same can be done with the <code class="language-plaintext highlighter-rouge">MemoFib</code> class:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MemoFib</span> <span class="kd">extends</span> <span class="nx">Fib</span> <span class="p">{</span>
    <span class="nl">superClass</span><span class="p">:</span> <span class="nx">Fib</span><span class="p">;</span>
    <span class="nl">store</span><span class="p">:</span> <span class="nb">Map</span><span class="o">&lt;</span><span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="o">&gt;</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">newMemoFib</span> <span class="o">=</span> <span class="p">():</span> <span class="nx">MemoFib</span> <span class="o">=&gt;</span> <span class="p">({</span>
    <span class="na">superClass</span><span class="p">:</span> <span class="nf">newFib</span><span class="p">(),</span>
    <span class="na">store</span><span class="p">:</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(),</span>
    <span class="na">call</span><span class="p">:</span> <span class="p">(</span><span class="na">self</span><span class="p">:</span> <span class="nx">MemoFib</span><span class="p">,</span> <span class="na">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">storedResult</span> <span class="o">=</span> <span class="nb">self</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">storedResult</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">storedResult</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nb">self</span><span class="p">.</span><span class="nx">superClass</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span><span class="p">);</span>
        <span class="nb">self</span><span class="p">.</span><span class="nx">store</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
        <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">});</span>

<span class="kd">const</span> <span class="nx">memoFib</span> <span class="o">=</span> <span class="nf">newMemoFib</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">,</span> <span class="mi">0</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">,</span> <span class="mi">10</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">,</span> <span class="mi">100</span><span class="p">));</span>
</code></pre></div></div>

<p>We can perform some simplifications to the code:</p>

<ul>
  <li>The type <code class="language-plaintext highlighter-rouge">Fib</code> can be simplified to a closure</li>
  <li>The wrapper function <code class="language-plaintext highlighter-rouge">newFib</code> can be removed, all we care about is the contents</li>
  <li>The only pert of <code class="language-plaintext highlighter-rouge">MemoFib</code> we want to be publicly available is <code class="language-plaintext highlighter-rouge">call</code>, so we can return a closure instead of an object</li>
  <li><code class="language-plaintext highlighter-rouge">superClass</code> can be removed since it’s always going to be the same</li>
</ul>

<p>After applying these simplifications we get the following;</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Fib</span> <span class="o">=</span> <span class="p">(</span><span class="nb">self</span><span class="p">:</span> <span class="nx">Fib</span><span class="p">,</span> <span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="kr">number</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">fib</span> <span class="o">=</span> <span class="p">(</span><span class="nb">self</span><span class="p">:</span> <span class="nx">Fib</span><span class="p">,</span> <span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="nf">self</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nf">self</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">newMemoFib</span> <span class="o">=</span> <span class="p">():</span> <span class="nx">Fib</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">store</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span>
    <span class="k">return </span><span class="p">(</span><span class="na">self</span><span class="p">:</span> <span class="nx">Fib</span><span class="p">,</span> <span class="na">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">storedResult</span> <span class="o">=</span> <span class="nx">store</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">storedResult</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">storedResult</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nf">fib</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span><span class="p">);</span>
        <span class="nx">store</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
        <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">memoFib</span> <span class="o">=</span> <span class="nf">newMemoFib</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFib</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">,</span> <span class="mi">0</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFib</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">,</span> <span class="mi">10</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFib</span><span class="p">(</span><span class="nx">memoFib</span><span class="p">,</span> <span class="mi">100</span><span class="p">));</span>
</code></pre></div></div>

<p>Passing a function to another function like this is denoted “continuation passing” in functional languages, which essentially means passing a callback function as an argument.</p>

<p>We can perform a further simplification. Closures have access to themselves if we give them a name, so we shouldn’t need to pass <code class="language-plaintext highlighter-rouge">self</code> to <code class="language-plaintext highlighter-rouge">self</code>. We can remove the <code class="language-plaintext highlighter-rouge">self</code> argument from <code class="language-plaintext highlighter-rouge">Fib</code> that way:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Fib</span> <span class="o">=</span> <span class="p">(</span><span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="kr">number</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">fib</span> <span class="o">=</span> <span class="p">(</span><span class="nb">self</span><span class="p">:</span> <span class="nx">Fib</span><span class="p">,</span> <span class="nx">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="nf">self</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nf">self</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">newMemoFib</span> <span class="o">=</span> <span class="p">():</span> <span class="nx">Fib</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">store</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span>
    <span class="kd">const</span> <span class="nx">memoized</span> <span class="o">=</span> <span class="p">(</span><span class="na">n</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">number</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">storedResult</span> <span class="o">=</span> <span class="nx">store</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">n</span><span class="p">);</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">storedResult</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">storedResult</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nf">fib</span><span class="p">(</span><span class="nx">memoized</span><span class="p">,</span> <span class="nx">n</span><span class="p">);</span>
        <span class="nx">store</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
        <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">memoized</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">memoFib</span> <span class="o">=</span> <span class="nf">newMemoFib</span><span class="p">();</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFib</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFib</span><span class="p">(</span><span class="mi">10</span><span class="p">));</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFib</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">newMemoFib</code> can memoize anything if we pass it as an argument. We can also make a generic version of <code class="language-plaintext highlighter-rouge">Fib</code> over any argument or return value:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Callable</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="nx">arg</span><span class="p">:</span> <span class="nx">A</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">R</span>
<span class="kd">type</span> <span class="nx">Memoizable</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="nb">self</span><span class="p">:</span> <span class="nx">Callable</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span><span class="p">,</span> <span class="nx">arg</span><span class="p">:</span> <span class="nx">A</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">R</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">fib</span><span class="p">:</span> <span class="nx">Memoizable</span><span class="o">&lt;</span><span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="o">||</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="nf">self</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nf">self</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">factorial</span><span class="p">:</span> <span class="nx">Memoizable</span><span class="o">&lt;</span><span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="nx">n</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">n</span> <span class="o">===</span> <span class="mi">0</span> <span class="p">?</span> <span class="mi">1</span> <span class="p">:</span> <span class="nf">self</span><span class="p">(</span><span class="nx">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="nx">n</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">newMemo</span> <span class="o">=</span> <span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">baseClass</span><span class="p">:</span> <span class="nx">Memoizable</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span><span class="p">):</span> <span class="nx">Callable</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">store</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Map</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span><span class="p">();</span>
    <span class="kd">const</span> <span class="nx">memoized</span> <span class="o">=</span> <span class="p">(</span><span class="na">arg</span><span class="p">:</span> <span class="nx">A</span><span class="p">):</span> <span class="nx">R</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">storedResult</span> <span class="o">=</span> <span class="nx">store</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">arg</span><span class="p">);</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">storedResult</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">storedResult</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nf">baseClass</span><span class="p">(</span><span class="nx">memoized</span><span class="p">,</span> <span class="nx">arg</span><span class="p">);</span>
        <span class="nx">store</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">arg</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
        <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">memoized</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">memoFib</span> <span class="o">=</span> <span class="nf">newMemo</span><span class="p">(</span><span class="nx">fib</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFib</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span>

<span class="kd">const</span> <span class="nx">memoFact</span> <span class="o">=</span> <span class="nf">newMemo</span><span class="p">(</span><span class="nx">factorial</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFact</span><span class="p">(</span><span class="mi">20</span><span class="p">));</span>
</code></pre></div></div>

<p>We see that <code class="language-plaintext highlighter-rouge">newMemo</code> is just a function that takes something that is memoizable and turns it into something callable. If I realize that my factorial function doesn’t perform any better with memoization, I can swap out <code class="language-plaintext highlighter-rouge">newMemo</code> with something else as long as it turns my memoizable function into something callable:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">newRecursive</span> <span class="o">=</span> <span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">baseClass</span><span class="p">:</span> <span class="nx">Memoizable</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span><span class="p">):</span> <span class="nx">Callable</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">recursive</span> <span class="o">=</span> <span class="p">(</span><span class="na">arg</span><span class="p">:</span> <span class="nx">A</span><span class="p">):</span> <span class="nx">R</span> <span class="o">=&gt;</span> <span class="nf">baseClass</span><span class="p">(</span><span class="nx">recursive</span><span class="p">,</span> <span class="nx">arg</span><span class="p">);</span>
    <span class="k">return</span> <span class="nx">recursive</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">memoFact</span> <span class="o">=</span> <span class="nf">newRecursive</span><span class="p">(</span><span class="nx">factorial</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">memoFact</span><span class="p">(</span><span class="mi">20</span><span class="p">));</span>
</code></pre></div></div>

<p>Excellent. I can memoize any function that is memoizable, and I can swap out the kind of recursion I use. I no longer have any of the limitations of the inheritance version.</p>

<p>If you look at the type signature of <code class="language-plaintext highlighter-rouge">Memoizable</code> versus <code class="language-plaintext highlighter-rouge">Callable</code>, we can now understand the difference between open and closed recursion. <code class="language-plaintext highlighter-rouge">Memoizable</code> functions are “Open” and <code class="language-plaintext highlighter-rouge">Callable</code> functions are “Closed”. This is because <code class="language-plaintext highlighter-rouge">Memoizable</code> functions call themselves by argument, and <code class="language-plaintext highlighter-rouge">Callable</code> functions call themselves by name. Open recursion allows the caller to override the recursive call with whatever we want. In our case, we could override the recursive call with memoization.</p>

<p><img src="/notepad/img/2021-05-30/openRecursion.png" alt="Open versus closed recursion" /></p>

<h2 id="conclusion">Conclusion</h2>

<p>It turns out maybe object orientated and functional programming have something in common. When methods are overridden in an inheritance hierarchy, this desugars to continuation passing. Functional programs that use continuation passing can be converted to objects using inheritance, and inheritance can be converted to open recursion.</p>

<hr />

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="open recursion" /><category term="functional programming" /><category term="object orientated programming" /><category term="inheritance" /><category term="memoization" /><category term="javascript" /><category term="typescript" /><category term="java" /><summary type="html"><![CDATA[A very functional idea in object orientated programming.]]></summary></entry><entry><title type="html">Prove Santa Claus is real using Typescript</title><link href="/notepad/notes/2021/02/14/santa_claus.html" rel="alternate" type="text/html" title="Prove Santa Claus is real using Typescript" /><published>2021-02-14T00:00:00+00:00</published><updated>2021-02-14T00:00:00+00:00</updated><id>/notepad/notes/2021/02/14/santa_claus</id><content type="html" xml:base="/notepad/notes/2021/02/14/santa_claus.html"><![CDATA[<h3 id="prove-santa-claus-is-real-using-typescript">Prove Santa Claus is real using Typescript</h3>

<p><img src="/notepad/img/2020-02-14/hell_frozen_over.jpg" alt="We're going to make it happen" /></p>

<h3 id="summary">Summary</h3>

<ul>
  <li>Curry’s paradox allows proofs of any statement in some languages that have the ability to construct a self referential sentence.</li>
  <li>This paradox allows a proof of any statement, no matter how absurd.</li>
  <li>Some statically typed programming languages allow for basic logical statements to be made and subsequently proven. Typescript is one of these languages.</li>
</ul>

<h2 id="the-premise">The Premise</h2>

<blockquote>
  <p>If this sentence is true, then Santa Claus is real.</p>
</blockquote>

<p>This statement seems innocuous enough, but it exposes a fatal flaw in some logical systems. If it is possible for the above sentence to exist as a statement, then it follows that Santa Claus is real. In fact it doesn’t matter what the second half of this sentence is. You could prove that the sky is purple, unicorns outnumber humans ten to one, or that ants wear hats. This paradox is called “Curry’s paradox” after the famous mathematician Haskell Curry.</p>

<p>So how does the paradox work? Consider a more normal example of a sentence of the form “if A then B”. For example consider the following sentence:</p>

<blockquote>
  <p>If you add salt and water together, you get salt water</p>
</blockquote>

<p>In order to prove a statement like this true, first we assume the first part of the sentence has already happened and then see if the second part came true. In this example, we assume that we have already mixed salt and water together (the first part of the sentence). Then we see if the second part came true. Since we have salt water, we can safely say that the sentence is true.</p>

<p>Cool, let’s get back to the original example</p>

<blockquote>
  <p>If this sentence is true, then oranges are green</p>
</blockquote>

<p>…Close enough. To prove this statement, first we assume the first bit (the sentence is true), then we see if the second part came true as a result. We have assumed that the sentence is true, so that would mean …oranges are grey. Cool, we proved oranges are grey if the sentence is true, so that means the sentence <em>is</em> true.</p>

<p>So we have proven that the sentence is true by following normal logical rules. But if the sentence really is true, then oranges are grey.</p>

<h2 id="curry-howard">Curry-Howard</h2>

<p>Curry’s paradox exists in a lot of places including english, and naive set theory. In addition to this we can even write it in a lot of programming languages. To do this, we need to understand the connection between say a formal language used in mathematics, and a programming language. The connection is referred to as the <em>Curry-Howard correspondence</em> and it basically states that types are predicates and implementations are proofs. <em>Note that the Curry in “Curry’s paradox” and “Curry-Howard” are in fact the same person!</em></p>

<p>In typescript, we are a bit limited, but there are some easy statements that we can write using just types. A type is the same as a <em>definition</em> or an <em>axiom</em> in mathematics.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Define salt, pepper, meat, potatoes, and ducks.</span>
<span class="kd">type</span> <span class="nx">Salt</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">salt</span><span class="dl">'</span>
<span class="kd">type</span> <span class="nx">Pepper</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">pepper</span><span class="dl">'</span>
<span class="kd">type</span> <span class="nx">Meat</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">meat</span><span class="dl">'</span>
<span class="kd">type</span> <span class="nx">Potatoes</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">potatoes</span><span class="dl">'</span>
<span class="kd">type</span> <span class="nx">Duck</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">duck</span><span class="dl">'</span>

<span class="c1">// Define Santa Claus as never existing</span>
<span class="kd">type</span> <span class="nx">SantaClaus</span> <span class="o">=</span> <span class="nx">never</span><span class="p">;</span>

<span class="c1">// A type for A and B</span>
<span class="kd">type</span> <span class="nx">And</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">B</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">theFirstPart</span><span class="p">:</span> <span class="nx">A</span><span class="p">;</span>
    <span class="nl">theSecondPart</span><span class="p">:</span> <span class="nx">B</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// To get a christmas quacker, we need Santa Claus and a duck</span>
<span class="kd">type</span> <span class="nx">CristmasQuacker</span> <span class="o">=</span> <span class="nx">And</span><span class="o">&lt;</span><span class="nx">SantaClaus</span><span class="p">,</span> <span class="nx">Duck</span><span class="o">&gt;</span><span class="p">;</span>

<span class="c1">// A type for A or B</span>
<span class="kd">type</span> <span class="nx">Or</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">B</span><span class="o">&gt;</span> <span class="o">=</span> 
    <span class="p">{</span> <span class="na">theFirstOption</span><span class="p">:</span> <span class="nx">A</span> <span class="p">}</span> <span class="o">|</span>
    <span class="p">{</span> <span class="na">theSecondOption</span><span class="p">:</span> <span class="nx">B</span> <span class="p">};</span>

<span class="c1">// To get seasoning we need salt or pepper</span>
<span class="kd">type</span> <span class="nx">Seasoning</span> <span class="o">=</span> <span class="nx">Or</span><span class="o">&lt;</span><span class="nx">Salt</span><span class="p">,</span> <span class="nx">Pepper</span><span class="o">&gt;</span>

<span class="c1">// To get a meal, we need seasoning, and either meat and potatoes</span>
<span class="kd">type</span> <span class="nx">Meal</span> <span class="o">=</span> <span class="nx">And</span><span class="o">&lt;</span><span class="nx">Seasoning</span><span class="p">,</span> <span class="nx">Or</span><span class="o">&lt;</span><span class="nx">Meat</span><span class="p">,</span> <span class="nx">Potatoes</span><span class="o">&gt;&gt;</span><span class="p">;</span>
</code></pre></div></div>

<p>We have shown that we can write basic statements which contain <code class="language-plaintext highlighter-rouge">And</code> and <code class="language-plaintext highlighter-rouge">Or</code>. We can also write statements that contain “if” in them. The logical symbol for “if” is the right arrow (→), which corresponds to the fat arrow (<code class="language-plaintext highlighter-rouge">=&gt;</code>) of JavaScript:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// If both A and B exist, then A exists</span>
<span class="kd">type</span> <span class="nx">First</span> <span class="o">=</span> <span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">B</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">both</span><span class="p">:</span> <span class="nx">And</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">B</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">A</span><span class="p">;</span>

<span class="c1">// If both A and B exists, then B exists</span>
<span class="kd">type</span> <span class="nx">Second</span> <span class="o">=</span> <span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">B</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">both</span><span class="p">:</span> <span class="nx">And</span><span class="o">&lt;</span><span class="nx">A</span><span class="p">,</span> <span class="nx">B</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">B</span><span class="p">;</span>
</code></pre></div></div>

<p>This is all well and good, but these are just definitions. Take <code class="language-plaintext highlighter-rouge">First</code> as an example. <code class="language-plaintext highlighter-rouge">First</code> is a sentence that states that if both A and B exist, then A exists. However, <code class="language-plaintext highlighter-rouge">First</code> is not a proof of that statement, it is just that statement itself.</p>

<p>In order to prove something to be true, we have to create an instance of that type. Here are some examples:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">saltExists</span><span class="p">:</span> <span class="nx">Salt</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">salt</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">pepperExists</span><span class="p">:</span> <span class="nx">Pepper</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">pepper</span><span class="dl">'</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">seasoningExists</span><span class="p">:</span> <span class="nx">Seasoning</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">theSecondOption</span><span class="p">:</span> <span class="dl">'</span><span class="s1">pepper</span><span class="dl">'</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">mealsExist</span><span class="p">:</span> <span class="nx">Meal</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">theFirstPart</span><span class="p">:</span> <span class="nx">seasoningExists</span><span class="p">,</span>
    <span class="na">theSecondPart</span><span class="p">:</span> <span class="p">{</span> <span class="na">theFirstOption</span><span class="p">:</span> <span class="dl">'</span><span class="s1">meat</span><span class="dl">'</span> <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// A exists because the first part of A and B is A.</span>
<span class="kd">const</span> <span class="nx">firstIsTrue</span><span class="p">:</span> <span class="nx">First</span> <span class="o">=</span> <span class="p">(</span><span class="nx">both</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">both</span><span class="p">.</span><span class="nx">theFirstPart</span><span class="p">;</span>

<span class="c1">// B exists because the second part of A and B is B.</span>
<span class="kd">const</span> <span class="nx">secondIsTrue</span><span class="p">:</span> <span class="nx">Second</span> <span class="o">=</span> <span class="p">(</span><span class="nx">both</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">both</span><span class="p">.</span><span class="nx">theSecondPart</span><span class="p">;</span>
</code></pre></div></div>

<p>Based on our definitions of salt, pepper, meat and potatoes, we have proven the existence of seasoning, an meals! In addition to that we have proven our <code class="language-plaintext highlighter-rouge">First</code> and <code class="language-plaintext highlighter-rouge">Second</code> predicates from above.</p>

<h2 id="falsehood">Falsehood</h2>

<p>Proving something to be true is all well and good, but what if we want to prove something false? Luckily TypeScript provides us with a type which can never be created called <code class="language-plaintext highlighter-rouge">never</code>. This type is sometimes referred to as <code class="language-plaintext highlighter-rouge">void</code>, <code class="language-plaintext highlighter-rouge">false</code>, or <code class="language-plaintext highlighter-rouge">bottom</code>. The mathematical symbol for <code class="language-plaintext highlighter-rouge">never</code> is this upside down T: ⊥. We can use “A → ⊥” (if A then false) to mean “A does not exist”:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// A does not exist</span>
<span class="kd">type</span> <span class="nx">Not</span><span class="o">&lt;</span><span class="nx">A</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="nx">false_statement</span><span class="p">:</span> <span class="nx">A</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">never</span><span class="p">;</span>
</code></pre></div></div>

<p>Now we have everything to prove things are not true:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Santa Claus does not exist because we defined him not to exist</span>
<span class="kd">const</span> <span class="nx">santaClausIsntReal</span><span class="p">:</span> <span class="nx">Not</span><span class="o">&lt;</span><span class="nx">SantaClaus</span><span class="o">&gt;</span> <span class="o">=</span>
    <span class="p">(</span><span class="nx">santaClaus</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">santaClaus</span><span class="p">;</span>

<span class="c1">// Christmas Quackers do not exist because because the first ingredient</span>
<span class="c1">// of a Christmas Quacker (Santa Claus) does not exist.</span>
<span class="kd">const</span> <span class="nx">christmasQuackersArentReal</span><span class="p">:</span> <span class="nx">Not</span><span class="o">&lt;</span><span class="nx">ChristmasQuacker</span><span class="o">&gt;</span> <span class="o">=</span>
    <span class="p">(</span><span class="nx">christmasQuacker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">christmasQuacker</span><span class="p">.</span><span class="nx">theFirstPart</span><span class="p">;</span>
</code></pre></div></div>

<p>We can even perform other proofs using <code class="language-plaintext highlighter-rouge">Not</code>. For example, what about the principle of explosion which states that given a contradiction we can prove anything:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// A contradiction is when something is both true</span>
<span class="c1">// and false at the same time</span>
<span class="kd">type</span> <span class="nx">Contradiction</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nx">And</span><span class="o">&lt;</span><span class="nx">T</span><span class="p">,</span> <span class="nx">Not</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;&gt;</span><span class="p">;</span>

<span class="c1">// Lemma: given a contradiction, we can prove anything</span>
<span class="kd">type</span> <span class="nx">PrincipleOfExplosion</span> <span class="o">=</span>
    <span class="o">&lt;</span><span class="nx">T</span><span class="p">,</span> <span class="nx">U</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">contra</span><span class="p">:</span> <span class="nx">Contradiction</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">U</span><span class="p">;</span>

<span class="c1">// ...and here's a proof:</span>
<span class="kd">const</span> <span class="nx">principleOfExplosionIsTrue</span><span class="p">:</span> <span class="nx">PrincipleOfExplosion</span> <span class="o">=</span>
    <span class="p">(</span><span class="nx">contra</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">contra</span><span class="p">.</span><span class="nf">theSecondPart</span><span class="p">(</span><span class="nx">contra</span><span class="p">.</span><span class="nx">theFirstPart</span><span class="p">)</span>
</code></pre></div></div>

<p>Exciting! We can prove basic mathematical theorems using only TypeScript. We now have everything we need to move onto our paradox.</p>

<h2 id="currys-paradox">Curry’s paradox</h2>

<p>We need some way to express the statement “If this sentence is true, then Santa Claus is real” as a type. To begin, we will give the sentence a name, say <code class="language-plaintext highlighter-rouge">CurrysParadox</code>.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">CurrysParadox</span> <span class="o">=</span> <span class="o">??</span>
</code></pre></div></div>

<p>This way we can rewrite our sentence to say “If <code class="language-plaintext highlighter-rouge">CurrysParadox</code> is true, then Santa Claus is real”. We know how to write a sentence with “if” in it, and we know how to write “Santa Claus is real”, so we can now fill in the blank:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">CurrysParadox</span> <span class="o">=</span>
    <span class="p">(</span><span class="nx">paradox</span><span class="p">:</span> <span class="nx">CurrysParadox</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">SantaClaus</span><span class="p">;</span>
</code></pre></div></div>

<p>To prove that the statement <code class="language-plaintext highlighter-rouge">CurrysParadox</code> is true, we need to create an instance of it:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">currysParadoxIsTrue</span><span class="p">:</span> <span class="nx">CurrysParadox</span> <span class="o">=</span>
    <span class="p">(</span><span class="nx">paradox</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="o">??</span>
</code></pre></div></div>

<p>We are given an instance of <code class="language-plaintext highlighter-rouge">CurrysParadox</code> an argument, and we want to return an instance of <code class="language-plaintext highlighter-rouge">SantaClaus</code>. <code class="language-plaintext highlighter-rouge">CurrysParadox</code> is a function that returns a <code class="language-plaintext highlighter-rouge">SantaClaus</code>, so if we can call it, then we can get <code class="language-plaintext highlighter-rouge">SantaClaus</code> as a result. We can call paradox by passing itself as an argument:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">currysParadoxIsTrue</span><span class="p">:</span> <span class="nx">CurrysParadox</span> <span class="o">=</span>
    <span class="p">(</span><span class="nx">paradox</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">paradox</span><span class="p">(</span><span class="nx">paradox</span><span class="p">);</span>
</code></pre></div></div>

<p>Now that we know that <code class="language-plaintext highlighter-rouge">CurrysParadox</code> is true, we need to get an instance of <code class="language-plaintext highlighter-rouge">SantaClaus</code> to complete the proof. Same as above, <code class="language-plaintext highlighter-rouge">currysParadoxIsTrue</code> is an instance of <code class="language-plaintext highlighter-rouge">CurrysParadox</code>. If we can call <code class="language-plaintext highlighter-rouge">currysParadoxIsTrue</code>, then we will get <code class="language-plaintext highlighter-rouge">SantaClaus</code> as a result. We can call <code class="language-plaintext highlighter-rouge">currysParadoxIsTrue</code> by passing itself as an argument:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">santaClausIsReal</span><span class="p">:</span> <span class="nx">SantaClaus</span> <span class="o">=</span>
    <span class="nf">currysParadoxIsTrue</span><span class="p">(</span><span class="nx">currysParadoxIsTrue</span><span class="p">);</span>
</code></pre></div></div>

<p>This type checks, so once this code runs we will have an instance of <code class="language-plaintext highlighter-rouge">SantaClaus</code>. We have finally proven that Santa Claus exists using nothing but TypeScript!</p>

<p>The absurdity continues. From the principle of explosion it is possible to prove anything if you have an untrue statement first:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">anythingIsTrue</span><span class="p">:</span> <span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">T</span> <span class="o">=</span> <span class="nx">santaClausIsReal</span><span class="p">;</span>
</code></pre></div></div>

<h2 id="uh-what">Uh, What?</h2>

<p>Hold on a second. When we were defining our types, we said <code class="language-plaintext highlighter-rouge">SantaClaus</code> was equal to <code class="language-plaintext highlighter-rouge">never</code>. When we run this program, what actually gets stored in the variable we named <code class="language-plaintext highlighter-rouge">santaClausIsReal</code>? Is it a number? Is it a function? Didi we actually manage to store Santa Claus in a variable? Running the program gives us the answer:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Uncaught RangeError: Maximum call stack size exceeded
</code></pre></div></div>

<p>So the code fails with a stack overflow. This is strange considering that we <em>didn’t use any recursion in our entire program</em>. But all is well. We never actually assign anything to the variable <code class="language-plaintext highlighter-rouge">santaClausIsReal</code> because the program fails before the function returns. Unfortunately, we don’t get to see Santa after all. As consolation, we are able to live in a world where the rules of mathematics still make sense.</p>

<h2 id="so-what-happened">So what happened?</h2>

<p>If we write <code class="language-plaintext highlighter-rouge">currysParadoxIsTrue</code> inline for <code class="language-plaintext highlighter-rouge">santaClausIsReal</code>, and shorten <code class="language-plaintext highlighter-rouge">paradox</code> to <code class="language-plaintext highlighter-rouge">p</code> we get the following statement:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nx">p</span> <span class="o">=&gt;</span> <span class="nf">p</span><span class="p">(</span><span class="nx">p</span><span class="p">))((</span><span class="nx">p</span><span class="p">:</span> <span class="nx">CurrysParadox</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">p</span><span class="p">(</span><span class="nx">p</span><span class="p">));</span>
</code></pre></div></div>

<p>The astute functional programmer will realize that this is in fact Omega from lambda calculus. It is a famous example of a statement, that when executed, produces a perfect copy of itself. This explains the stack overflow: the function body produces a copy of itself, and then calls the copy repeatedly until the stack runs out of space.</p>

<p>So how do we reconcile the fact that TypeScript allowed us to write these absurd kinds of results in the first place? Is TypeScript broken? Well, no. In order to facilitate writing programs with loops and other non-obvious exit conditions, TypeScript allows us to write non-terminating programs. When we give a type to a function, we declare that when it returns, the value will have the specified type. If it never returns, then we never break any of the typing rules.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Unfortunately we don’t get to prove Santa Claus is real, but we do get an interesting insight into the parallels between mathematics and the type checker. Many languages allows us to write basic logical statements as types, and prove them using an implementation. However, this has it’s limitations. The proofs of statements are only applicable when it is known ahead of time that the program will terminate. In other cases, the language is susceptible to contradiction.</p>

<hr />

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="typescript" /><category term="Curry-Howard" /><category term="type theory" /><category term="proof" /><category term="Curry&apos;s paradox" /><category term="Functional Programming" /><category term="Javascript" /><category term="Santa Claus" /><summary type="html"><![CDATA[Prove Santa Claus is real using Typescript]]></summary></entry><entry><title type="html">Using switch is not an anti-pattern</title><link href="/notepad/notes/2021/01/16/switch_statements.html" rel="alternate" type="text/html" title="Using switch is not an anti-pattern" /><published>2021-01-16T00:00:00+00:00</published><updated>2021-01-16T00:00:00+00:00</updated><id>/notepad/notes/2021/01/16/switch_statements</id><content type="html" xml:base="/notepad/notes/2021/01/16/switch_statements.html"><![CDATA[<h1 id="using-switch-is-not-an-anti-pattern">Using “switch” is not an anti-pattern</h1>

<p><img src="/notepad/img/2020-01-17/switch.jpg" alt="It's a switch: use it" /></p>

<h2 id="summary">Summary</h2>

<ul>
  <li>Switch statements over basic enums have lots of disadvantages</li>
  <li>Many of the limitations can be overcome by using either dynamic dispatch, or the visitor pattern depending on your use case</li>
  <li>In languages that support sum types natively, consider using those instead of the visitor pattern</li>
</ul>

<h2 id="introduction">Introduction</h2>

<p>I have seen several articles recently that take the position that switch statements are an anti-pattern in regards to best practice object-orientated programming. In a way, the sentiment is usually fine, but I think that these articles are a bit incomplete and don’t tell the full story. Let’s take a lesson from functional programming to find when using a <code class="language-plaintext highlighter-rouge">switch</code> is OK.</p>

<p>I’ll use TypeScript in this article as it supports all of the necessary language features and is usually pretty easy to read.</p>

<h2 id="the-argument-against-switch-statements">The argument against switch statements</h2>

<p><img src="/notepad/img/2020-01-17/shape.jpg" alt="Trust me, it's not" /></p>

<p>In basic usage switch statements are usually pretty limited, and are used to match against integers, and sometimes strings. Imagine we have two functions <code class="language-plaintext highlighter-rouge">draw</code> and <code class="language-plaintext highlighter-rouge">area</code> which can either take a unit square (side length 1) or a unit circle (radius 1). Using switch statements the code would look something like this:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">enum</span> <span class="nx">Shape</span> <span class="p">{</span>
    <span class="nx">UnitSquare</span><span class="p">,</span>
    <span class="nx">UnitCircle</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">area</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">switch </span><span class="p">(</span><span class="nx">shape</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">case</span> <span class="nx">Shape</span><span class="p">.</span><span class="na">UnitSquare</span><span class="p">:</span>
            <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
        <span class="k">case</span> <span class="nx">Shape</span><span class="p">.</span><span class="na">UnitCircle</span><span class="p">:</span>
            <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span><span class="p">;</span>
        <span class="nl">default</span><span class="p">:</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">not a shape</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">draw</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">switch </span><span class="p">(</span><span class="nx">shape</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">case</span> <span class="nx">Shape</span><span class="p">.</span><span class="na">UnitSquare</span><span class="p">:</span>
            <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a unit square</span><span class="dl">"</span><span class="p">);</span>
            <span class="k">return</span><span class="p">;</span>
        <span class="k">case</span> <span class="nx">Shape</span><span class="p">.</span><span class="na">UnitCircle</span><span class="p">:</span>
            <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a unit circle</span><span class="dl">"</span><span class="p">);</span>
            <span class="k">return</span><span class="p">;</span>
        <span class="nl">default</span><span class="p">:</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">not a shape</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// usage</span>
<span class="kd">const</span> <span class="nx">doStuff</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">area</span><span class="p">(</span><span class="nx">shape</span><span class="p">));</span>
    <span class="nf">draw</span><span class="p">(</span><span class="nx">shape</span><span class="p">);</span>
<span class="p">}</span>
<span class="nf">doStuff</span><span class="p">(</span><span class="nx">Shape</span><span class="p">.</span><span class="nx">UnitSquare</span><span class="p">);</span>
<span class="nf">doStuff</span><span class="p">(</span><span class="nx">Shape</span><span class="p">.</span><span class="nx">UnitCircle</span><span class="p">);</span>
</code></pre></div></div>

<p>There are a number of problems with this code:</p>

<ul>
  <li>Enums are just integers so you can’t set the side length of the square or the radius of the circle</li>
  <li>If you add another shape, you have to search through all of your code to find switch statements that don’t cover every case. If you miss one you could get runtime errors.</li>
</ul>

<p>There are probably more reasons why this code is not the best. I will begrudgingly admit it that it has one benefit: as it stands, the code is dead simple to read. There’s no magic and it’s laid out in such a way that it’s very clear what it does.</p>

<p>At the moment, we have two functions that both accept two variants each. We could swap this around and have two variants that have two functions each:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Shape</span> <span class="p">{</span>
    <span class="nl">area</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="kr">number</span><span class="p">;</span>
    <span class="nl">draw</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="k">void</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Circle</span> <span class="p">{</span>
    <span class="k">private</span> <span class="nx">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>

    <span class="nf">constructor </span><span class="p">(</span><span class="nx">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">radius</span> <span class="o">=</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nf">area</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">radius</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">radius</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nf">draw</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a circle</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Rectangle</span> <span class="p">{</span>
    <span class="k">private</span> <span class="nx">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
    <span class="k">private</span> <span class="nx">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>

    <span class="nf">constructor </span><span class="p">(</span><span class="nx">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nf">area</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">*</span> <span class="k">this</span><span class="p">.</span><span class="nx">height</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nf">draw</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a rectangle</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">//usage</span>
<span class="kd">const</span> <span class="nx">doStuff</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">shape</span><span class="p">.</span><span class="nf">area</span><span class="p">());</span>
    <span class="nx">shape</span><span class="p">.</span><span class="nf">draw</span><span class="p">();</span>
<span class="p">}</span>

<span class="nf">doStuff</span><span class="p">(</span><span class="k">new</span> <span class="nc">Circle</span><span class="p">(</span><span class="mi">2</span><span class="p">));</span>
<span class="nf">doStuff</span><span class="p">(</span><span class="k">new</span> <span class="nc">Rectangle</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">));</span>
</code></pre></div></div>

<p>Instead of having an <code class="language-plaintext highlighter-rouge">enum</code>, we provide an interface. The <code class="language-plaintext highlighter-rouge">Circle</code> and <code class="language-plaintext highlighter-rouge">Rectangle</code> classes implement that interface. This solves both of the original stated aims:</p>

<ul>
  <li>The <code class="language-plaintext highlighter-rouge">Circle</code> has a radius, the <code class="language-plaintext highlighter-rouge">Rectangle</code> now has a height and width</li>
  <li>We can add new types of shapes easily without having to modify switch statements everywhere</li>
</ul>

<p>So everything is good and we can call it a day right?</p>

<h2 id="visitors">Visitors</h2>

<p>Before I can head home safe in the knowledge that the second form is the best way to write that particular code I have to ask a question about the future of my program: <strong><em>Am I more likely to add new methods to the <code class="language-plaintext highlighter-rouge">Shape</code> interface, or am I more likely to add new types?</em></strong>. For the rest of this article, I will assume that you’re more likely to add new behavior than new types. If this is not your use case, then you can stop reading, use an interface as shown above, and say good riddance to the <code class="language-plaintext highlighter-rouge">switch</code>. If you are unsure, then keep reading, you might learn something new.</p>

<p><img src="/notepad/img/2020-01-17/visitor.jpg" alt="I'm just here to fix the elevator" /></p>

<p>It’s easy to add more types to an interface: simply define a new class and implement the interface. You don’t have to modify any existing code, you can just add new functionality. However, if you decided that you wanted to add a new method to the <code class="language-plaintext highlighter-rouge">Shape</code> interface, then <em>every class that implements <code class="language-plaintext highlighter-rouge">Shape</code></em> needs to be modified.</p>

<p>Compare this to the first example of code where we used a switch statement. If we want to add a new <em>type</em>, then we have to modify all of our switch statements. However if we want to add a new <em>method</em>, then we can just write a new function without modifying any of our existing code.</p>

<p>The first example has the complete opposite problem than the second example does. However, to tackle some of the other limitations of the first example, an OOP enthusiast would probably recognize that we can use the visitor pattern instead:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="na">circle</span><span class="p">:</span> <span class="p">(</span><span class="na">circle</span><span class="p">:</span> <span class="nx">Circle</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">T</span><span class="p">;</span>
    <span class="nl">rectangle</span><span class="p">:</span> <span class="p">(</span><span class="na">rectangle</span><span class="p">:</span> <span class="nx">Rectangle</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">T</span><span class="p">;</span>
<span class="p">}</span>

<span class="kr">interface</span> <span class="nx">Shape</span> <span class="p">{</span>
    <span class="nl">visit</span><span class="p">:</span> <span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">visitor</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">T</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Circle</span> <span class="p">{</span>
    <span class="nl">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>

    <span class="nf">constructor </span><span class="p">(</span><span class="nx">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">radius</span> <span class="o">=</span> <span class="nx">radius</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nx">visit</span> <span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">visitor</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">visitor</span><span class="p">.</span><span class="nf">circle</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Rectangle</span> <span class="p">{</span>
    <span class="nl">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
    <span class="nl">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>

    <span class="nf">constructor </span><span class="p">(</span><span class="nx">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nx">visit</span> <span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">visitor</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">visitor</span><span class="p">.</span><span class="nf">rectangle</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">area</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="kr">number</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">circle</span><span class="p">:</span> <span class="p">(</span><span class="nx">circle</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">*</span> <span class="nx">circle</span><span class="p">.</span><span class="nx">radius</span> <span class="o">*</span> <span class="nx">circle</span><span class="p">.</span><span class="nx">radius</span><span class="p">,</span>
    <span class="na">rectangle</span><span class="p">:</span> <span class="p">(</span><span class="nx">rectangle</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">rectangle</span><span class="p">.</span><span class="nx">width</span> <span class="o">*</span> <span class="nx">rectangle</span><span class="p">.</span><span class="nx">height</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">draw</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">circle</span><span class="p">:</span> <span class="p">(</span><span class="nx">_circle</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a circle</span><span class="dl">"</span><span class="p">),</span>
    <span class="na">rectangle</span><span class="p">:</span> <span class="p">(</span><span class="nx">_rectangle</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a rectangle</span><span class="dl">"</span><span class="p">)</span>
<span class="p">}</span>

<span class="c1">// usage</span>

<span class="kd">const</span> <span class="nx">doStuff</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">shape</span><span class="p">.</span><span class="nf">visit</span><span class="p">(</span><span class="nx">area</span><span class="p">));</span>
    <span class="nx">shape</span><span class="p">.</span><span class="nf">visit</span><span class="p">(</span><span class="nx">draw</span><span class="p">);</span>
<span class="p">}</span>

<span class="nf">doStuff</span><span class="p">(</span><span class="k">new</span> <span class="nc">Circle</span><span class="p">(</span><span class="mi">2</span><span class="p">));</span>
<span class="nf">doStuff</span><span class="p">(</span><span class="k">new</span> <span class="nc">Rectangle</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">));</span>
</code></pre></div></div>

<p>The visitor pattern is quite complicated, but it does the job.</p>

<ul>
  <li>The circle has a radius, and the rectangle has side lengths</li>
  <li>New functionality can be added without modifying existing code</li>
  <li>(Bonus benefit!) If we add a new variant (say  we add a triangle), then the compiler will point out all the visitors where we need to change our code and won’t compile until we have fixed it.</li>
</ul>

<p>The the visitor pattern is actually a page taken out of the functional programming book: it is the church encoding for sum types in lambda calculus in disguise. That sounds like gibberish, but what that means for us humans is that we can write the visitor example with much more brevity. Note that I do not condone the use of church encoding in useful programs, but want to include it as a demonstration of how unreadable it is:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="na">circle</span><span class="p">:</span> <span class="p">(</span><span class="na">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">T</span><span class="p">;</span>
    <span class="nl">rectangle</span><span class="p">:</span> <span class="p">(</span><span class="na">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="na">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">T</span><span class="p">;</span>
<span class="p">}</span>

<span class="kr">interface</span> <span class="nx">Shape</span> <span class="p">{</span>
    <span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">visitor</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">):</span> <span class="nx">T</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">Circle</span> <span class="o">=</span> <span class="p">(</span><span class="nx">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="nx">Shape</span> <span class="o">=&gt;</span> 
    <span class="p">({</span> <span class="nx">circle</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="nf">circle</span><span class="p">(</span><span class="nx">radius</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">Rectangle</span> <span class="o">=</span> <span class="p">(</span><span class="nx">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="nx">Shape</span> <span class="o">=&gt;</span> 
    <span class="p">({</span> <span class="nx">rectangle</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="nf">rectangle</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">);</span>

<span class="kd">const</span> <span class="nx">area</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="kr">number</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">circle</span><span class="p">:</span> <span class="p">(</span><span class="nx">radius</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">*</span> <span class="nx">radius</span> <span class="o">*</span> <span class="nx">radius</span><span class="p">,</span>
    <span class="na">rectangle</span><span class="p">:</span> <span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">width</span> <span class="o">*</span> <span class="nx">height</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">draw</span><span class="p">:</span> <span class="nx">ShapeVisitor</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">circle</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a circle</span><span class="dl">"</span><span class="p">),</span>
    <span class="na">rectangle</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a rectangle</span><span class="dl">"</span><span class="p">)</span>
<span class="p">}</span>

<span class="c1">// usage</span>

<span class="kd">const</span> <span class="nx">doStuff</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">shape</span><span class="p">(</span><span class="nx">area</span><span class="p">));</span>
    <span class="nf">shape</span><span class="p">(</span><span class="nx">draw</span><span class="p">);</span>
<span class="p">}</span>

<span class="nf">doStuff</span><span class="p">(</span><span class="nc">Circle</span><span class="p">(</span><span class="mi">2</span><span class="p">));</span>
<span class="nf">doStuff</span><span class="p">(</span><span class="nc">Rectangle</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">));</span>
</code></pre></div></div>

<p>In this example we ditch classes, and use closures instead. This has all of the advantages of the visitor pattern, but is even more unreadable. Church encoding is not a great way to program.</p>

<h2 id="sum-types">Sum types</h2>

<p>In the above examples we mentioned “sum types”. A sum type is something that can be one thing or another. For example, <code class="language-plaintext highlighter-rouge">boolean</code> is a sum type of <code class="language-plaintext highlighter-rouge">true</code> and <code class="language-plaintext highlighter-rouge">false</code> because it can either be <code class="language-plaintext highlighter-rouge">true</code> or <code class="language-plaintext highlighter-rouge">false</code>. <code class="language-plaintext highlighter-rouge">Shape</code> is a sum type too: it can either be a <code class="language-plaintext highlighter-rouge">Circle</code> or a <code class="language-plaintext highlighter-rouge">Rectangle</code>.</p>

<p>We used the “Church encoding” for sum types in the above example. The Church encoding is one method you can use when your language doesn’t support sum types natively. Luckily for us, TypeScript <em>does</em> support sum types, so we should prefer that:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Shape</span> <span class="o">=</span> <span class="nx">Circle</span> <span class="o">|</span> <span class="nx">Rectangle</span>

<span class="kr">interface</span> <span class="nx">Circle</span> <span class="p">{</span>
    <span class="nl">variant</span><span class="p">:</span> <span class="dl">'</span><span class="s1">circle</span><span class="dl">'</span><span class="p">;</span>
    <span class="nl">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">const</span> <span class="nx">Circle</span> <span class="o">=</span> <span class="p">(</span><span class="nx">radius</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="nx">Circle</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span> <span class="na">variant</span><span class="p">:</span> <span class="dl">'</span><span class="s1">circle</span><span class="dl">'</span><span class="p">,</span> <span class="nx">radius</span> <span class="p">};</span>
<span class="p">}</span>

<span class="kr">interface</span> <span class="nx">Rectangle</span> <span class="p">{</span>
    <span class="nl">variant</span><span class="p">:</span> <span class="dl">'</span><span class="s1">rectangle</span><span class="dl">'</span><span class="p">;</span>
    <span class="nl">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
    <span class="nl">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">const</span> <span class="nx">Rectangle</span> <span class="o">=</span> <span class="p">(</span><span class="nx">width</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">height</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="nx">Rectangle</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span> <span class="na">variant</span><span class="p">:</span> <span class="dl">'</span><span class="s1">rectangle</span><span class="dl">'</span><span class="p">,</span> <span class="nx">width</span><span class="p">,</span> <span class="nx">height</span> <span class="p">};</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">unreachable</span> <span class="o">=</span> <span class="p">(</span><span class="nx">_x</span><span class="p">:</span> <span class="nx">never</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{};</span>

<span class="kd">const</span> <span class="nx">area</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">switch </span><span class="p">(</span><span class="nx">shape</span><span class="p">.</span><span class="nx">variant</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">case</span> <span class="dl">'</span><span class="s1">circle</span><span class="dl">'</span><span class="p">:</span>
            <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">*</span> <span class="nx">shape</span><span class="p">.</span><span class="nx">radius</span> <span class="o">*</span> <span class="nx">shape</span><span class="p">.</span><span class="nx">radius</span><span class="p">;</span>
        <span class="k">case</span> <span class="dl">'</span><span class="s1">rectangle</span><span class="dl">'</span><span class="p">:</span>
            <span class="k">return</span> <span class="nx">shape</span><span class="p">.</span><span class="nx">width</span> <span class="o">*</span> <span class="nx">shape</span><span class="p">.</span><span class="nx">height</span><span class="p">;</span>
        <span class="nl">default</span><span class="p">:</span>
            <span class="k">return</span> <span class="nf">unreachable</span><span class="p">(</span><span class="nx">shape</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">draw</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">switch </span><span class="p">(</span><span class="nx">shape</span><span class="p">.</span><span class="nx">variant</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">case</span> <span class="dl">'</span><span class="s1">circle</span><span class="dl">'</span><span class="p">:</span>
            <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a rectangle</span><span class="dl">"</span><span class="p">);</span>
            <span class="k">return</span><span class="p">;</span>
        <span class="k">case</span> <span class="dl">'</span><span class="s1">rectangle</span><span class="dl">'</span><span class="p">:</span>
            <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">drawing a circle</span><span class="dl">"</span><span class="p">);</span>
            <span class="k">return</span><span class="p">;</span>
        <span class="nl">default</span><span class="p">:</span>
            <span class="k">return</span> <span class="nf">unreachable</span><span class="p">(</span><span class="nx">shape</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// usage</span>

<span class="kd">const</span> <span class="nx">doStuff</span> <span class="o">=</span> <span class="p">(</span><span class="nx">shape</span><span class="p">:</span> <span class="nx">Shape</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">area</span><span class="p">(</span><span class="nx">shape</span><span class="p">));</span>
    <span class="nf">draw</span><span class="p">(</span><span class="nx">shape</span><span class="p">);</span>
<span class="p">}</span>

<span class="nf">doStuff</span><span class="p">(</span><span class="nc">Circle</span><span class="p">(</span><span class="mi">2</span><span class="p">));</span>
<span class="nf">doStuff</span><span class="p">(</span><span class="nc">Rectangle</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">));</span>
</code></pre></div></div>

<p>The funny <code class="language-plaintext highlighter-rouge">unreachable</code> function is used as a static assertion. The program will not compile if there is a valid code path that reaches the <code class="language-plaintext highlighter-rouge">unreachable</code> function. We no longer need to throw an error in the switch branches because the compiler can statically determine that the default branch is never executed. This means that if you added a new variant (like a triangle) the program won’t compile until you fix all of the relevant <code class="language-plaintext highlighter-rouge">switch</code> statements.</p>

<h2 id="conclusion">Conclusion</h2>

<p>We have come full circle. We took a long journey but we are back at a <code class="language-plaintext highlighter-rouge">switch</code> statement. The above code essentially has all the benefits of the original visitor example, because semantically they describe the same thing.</p>

<ul>
  <li>We started off with a switch on an enum and found it had lots of disadvantages</li>
  <li>We could fix those disadvantages by using the visitor pattern</li>
  <li>The visitor pattern is a way to describe sum types using Church encoding in languages that don’t support them natively</li>
  <li>In languages that support sum types, consider using them directly</li>
</ul>

<p>The differences between the first and last examples are:</p>

<ul>
  <li>The switch statement matches on the variants of a sum type rather than a basic <code class="language-plaintext highlighter-rouge">enum</code></li>
  <li>The switch statement is exhaustive due to the <code class="language-plaintext highlighter-rouge">unreachable</code> function</li>
</ul>

<p>So if your language supports sum types and you think you’re more likely to add new functionality to existing classes than you are to add a new types, consider using <code class="language-plaintext highlighter-rouge">switch</code>.</p>

<h2 id="parting-note">Parting Note</h2>

<p>In languages that don’t support sum types natively, don’t be afraid to use a visitor if you were thinking about using a <code class="language-plaintext highlighter-rouge">switch</code> statement. After all, it is a well established design pattern. If you find yourself needing to branch based on type, or if you need to use downcasting, then consider using a visitor as an alternative.</p>

<hr />

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="typescript" /><category term="programming" /><category term="object orientated programming" /><category term="functional programming" /><category term="javascript" /><category term="sum types" /><category term="type theory" /><category term="visitor pattern" /><category term="church encoding" /><summary type="html"><![CDATA[Using “switch” is not an anti-pattern]]></summary></entry><entry><title type="html">DRY from first principles</title><link href="/notepad/notes/2020/09/03/repeat_yourself.html" rel="alternate" type="text/html" title="DRY from first principles" /><published>2020-09-03T00:00:00+00:00</published><updated>2020-09-03T00:00:00+00:00</updated><id>/notepad/notes/2020/09/03/repeat_yourself</id><content type="html" xml:base="/notepad/notes/2020/09/03/repeat_yourself.html"><![CDATA[<h3 id="summary">Summary</h3>

<ul>
  <li>“Don’t repeat yourself” (DRY) is a widely accepted programming principle, but it has several limitations</li>
  <li>An alternative derivation of DRY is presented, that aims to alleviate some of these limitations</li>
  <li>Programs are made up of functions, and to make functions maximally reusable they should
    <ul>
      <li>Have the most lenient preconditions</li>
      <li>Have the most strict postconditions</li>
      <li>Perform the smallest amount of non-trivial work</li>
    </ul>
  </li>
</ul>

<p>If you think this article is too long, you can skip to <strong><a href="#Should-I-refactor-my-code?">Should I refactor my code?</a></strong> below</p>

<h1 id="dont-dont-repeat-yourself">Don’t Don’t Repeat yourself</h1>

<p>In software engineering, “clean code” is a sought after ideal. Code that is “clean” is easy to read, understand and maintain. Unfortunately, what clean code looks like is often disputed. Some commonly accepted software engineering best practices have lost sight of their original goals, or do not represent a complete picture. I believe Don’t Repeat Yourself (DRY) may be one of these principles.</p>

<p>DRY is a widespread and generally well accepted best practice in software engineering. The main stated advantage to DRY is that code does not need to be modified in multiple locations. If code has been de-duplicated, then bugfixes and new features only need to be added once. In addition, code only needs to be tested once rather than multiple times. The end result is that code is <strong>less error prone</strong> and <strong>faster to write</strong>.</p>

<p>Unfortunately, it is also well known that the overzealous application of DRY can lead to poor abstractions, and code that is difficult to modify. If DRY were to be taken to the extreme, then it’s aim is just to increase the entropy of written code and turn it into code golf. In some instances this is a good thing, for example: obfuscation, or minified JavaScript, but in most cases, code written in this style is obviously detrimental. This indicates that DRY has some limitations as a principle.</p>

<p>This article will explore some of the limitations of DRY and provide an alternative perspective that does not have the same limitations.</p>

<h2 id="limitations-of-dry">Limitations of DRY</h2>

<p>One of the oft discussed limitations of DRY is that it can lead to poor abstractions. Heuristic solutions like the “rule of three” exist to alleviate this problem, where only code that is duplicated three or more times is worthwhile refactoring. This is not at all perfect. For example, the fourth replication may require an additional parameterization that the first three applications did not.</p>

<p>Often ignored in this discussion, plain, non generic functions are the basic unit of code reuse, and relatively often these functions only have a single call site. Following a strict “rule of three” application, it would follow that a function with a single call site should instead be written inline, and only factored out once it has been written three times. Therefore there appear to exist some worthwhile abstractions, even if they do not reduce the repetition of code:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Large functions that have comments in them are</span>
<span class="c1">// considered good candidates for refactoring</span>
<span class="kd">function</span> <span class="nf">bigFunc</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Do part A</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Did part A</span><span class="dl">"</span><span class="p">);</span>
    <span class="c1">// Do Part B</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Did part B</span><span class="dl">"</span><span class="p">);</span>
    <span class="c1">// Do Part C</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Did part C</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// It is recommended to split such a function into</span>
<span class="c1">// smaller parts. Cited reasoning includes:</span>
<span class="c1">//  - Easier testing</span>
<span class="c1">//  - Self documenting code</span>
<span class="c1">//  - Reusability</span>

<span class="kd">function</span> <span class="nf">doPartA</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Did part A</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">doPartB</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Did part B</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">doPartC</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Did part C</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">newBigFunc</span><span class="p">()</span> <span class="p">{</span>
    <span class="nf">doPartA</span><span class="p">();</span>
    <span class="nf">doPartB</span><span class="p">();</span>
    <span class="nf">doPartC</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Another argument against applying too much DRY is that overly generic code can be more difficult to understand and maintain. I’m a bit skeptical of how significant this really is, as ‘Difficulty’ is a very subjective concept and would vary from person to person, but I suppose there may be some truth to the claim that this negatively affects software development in some measurable capacity.</p>

<p>In addition, I dispute the assertion that using DRY is necessarily faster to write. Copy and paste is quick, and I suspect that the vast majority of developer time is not spent actually typing in the first instance. In the case of modification, a global find and replace works for actually writing the code (and for copying over any relevant tests).</p>

<table><tr>
    <td width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></td>
    <td> Obviously copy and paste, and global find and replace are not the recommended tools for refactoring a program, but the concept here is that writing the code itself is not the bottleneck.</td>
</tr></table>

<p>To prove me wrong (or right) in this regard, someone would have to measure the time it takes to write out duplicated code versus non duplicated code. Additionally, they would need to show that there was a significant difference between them whilst proving that the difference wasn’t just due to chance. I doubt that such a study will be done for some time.</p>

<h2 id="from-first-principles">From First Principles</h2>

<p>Considering how widespread the principle of DRY is, there is little empirical evidence to say to what extent it improves code quality. The promotion of DRY is largely based on the subjective experiences of software engineers over the course of their work. As such it is unknown exactly how effective it really is.</p>

<p>Certainly, DRY is not an end goal. End goals include things such as reducing time to market, reducing cost, or increasing developer productivity. The quality of code can also play a part; it could be measured by the frequency and severity of bugs that affect users.</p>

<p>Since the empirical evidence is not of sufficient quality, the next best thing would be to start with some small, but fundamental assumptions about how code works, and then <em>derive</em> what good code should look like from those assumptions. Note that I will not discuss how writing code one way will fix errors that writing code in another way exposes, nor will I discuss lessons that I have learned writing software. The conclusions drawn in this article will be drawn <em>without</em> the need to have experienced real world code.</p>

<p>I will assume that <strong>a developer never deliberately introduces bugs into their programs</strong>, and would choose to write a program with no bugs if at all possible. This is actually quite an ambitious assumption. Some bugs are just not worth fixing under the scrutiny of a cost-benefit analysis; bugs that are extremely mild in nature, or are rare enough that they are never experienced by an end user might not be worth going through the trouble to fix. However, I will persist with this assumption for the purposes of this article.</p>

<p>In addition, I will assume that <strong>the harder it is to prove a program correct, the more likely it contains errors</strong>. I define a program as ‘hard’ to prove correct if that program requires a lot of symbols in some theorem proving language to ensure correctness. Conversely, a program that requires few symbols is therefore ‘easy’ to prove correct. I note then that the number of symbols required for a proof is proportional to the number of errors you would find along the way.</p>

<table><tr>
    <td width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></td>
    <td> There's an implicit assumption that during the proving process, bugs can be fixed without adding or removing symbols. In this way it makes sense to talk about an incorrect program whilst also talking about proving it correct.</td>
</tr></table>

<p>In the biggest logical leap of this article, I will mention something something Curry-Howard, and state without much proof at all that the number of symbols required to prove a program correct is proportional to the number of symbols in the code itself. This is a huge assumption, and probably not at all correct in a lot of instances. However, it does give us a convenient proxy on the number of errors that are in a given piece of code: if the code is longer, or is more complex, then it has more errors.</p>

<table><tr>
    <td width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></td>
    <td> Note that in a functional language with dependent types, where the Curry-Howard isomorphism can actually apply, the proof of a function's correctness and it's implementation is literally the same code. So saying that the length of the proof is the length of the code is indeed a reasonable assumption to make.</td>
</tr></table>

<p>So at least one way to reduce the number of errors in code will be to reduce the number of symbols in the code itself. This sounds a lot like DRY. Note that code that is <em>terse</em> does not fit the bill for having less errors, as it still contains the same number of symbols. In this way, naming, styling, and indentation are ignored.</p>

<h2 id="my-recommendation">My Recommendation</h2>

<p>Programs regardless of paradigm are made out of functions. Well, maybe not in some cases, but they must be made of <em>something</em>. And in order for a discussion about code reuse to be meaningful there must be <em>something</em> in a programming language that can be reused. I’ll use “function” to mean the smallest reusable part of a program</p>

<p>Perhaps to the chagrin of an Object Orientated programmer, I will specifically not talk about objects being reusable. Objects can have multiple methods or members, so if an object is reusable, then that means that there is something <em>smaller</em> that is reusable too.</p>

<p>So if we consider a function to be the smallest reusable part of a program, then in order for our program to have the maximum reuse, any given function should:</p>

<ul>
  <li>be <strong>able</strong> to be reused as much as possible, and</li>
  <li>it should be as <strong>useful</strong> as possible, and</li>
  <li>it should be <strong>used</strong> as much as possible.</li>
</ul>

<p>In order to achieve these goals respectively:</p>

<ul>
  <li>A function should have the smallest possible set of preconditions</li>
  <li>A function should have the largest set of postconditions</li>
  <li>A function should perform the smallest non trivial amount of work</li>
</ul>

<h2 id="the-smallest-possible-set-of-preconditions">The Smallest Possible Set of Preconditions</h2>

<p>A maximally reusable function should be able to be called wherever it is applicable. Functions can only be called when the caller can fulfill the preconditions of the function. If the caller cannot fulfill the preconditions of a function, but calls the function anyway, then this is an error.</p>

<p>I’ll provide a short and not at all rigorous proof that maximally reusable functions have minimal preconditions using contradiction. Assume that there exists a maximally reusable function <code class="language-plaintext highlighter-rouge">f</code> which specifies a precondition that is unnecessary. That means that there exist potentially valid calling contexts where the function cannot be called, because the precondition cannot be satisfied. <code class="language-plaintext highlighter-rouge">f</code> can be made more reusable by removing the unnecessary precondition. Because <code class="language-plaintext highlighter-rouge">f</code> is already maximally reusable, this is a contradiction.</p>

<p>In fact, this must be the <em>only</em> thing that determines if a function is able to be used in as many places as possible. The only other places that <code class="language-plaintext highlighter-rouge">f</code> could potentially be used cannot satisfy necessary preconditions. Since it is already known that the function <code class="language-plaintext highlighter-rouge">f</code> has a minimal preconditions, any call to <code class="language-plaintext highlighter-rouge">f</code> in these locations is invalid.</p>

<p>In other words a function with minimal preconditions can be used anywhere it would be valid to call such a function, and the only places it cannot be called are all invalid anyway.</p>

<h3 id="example-1-generics">Example 1: Generics</h3>

<p>Say you have a function that takes the maximum of two integers. I use Haskell and Rust, because in a lot of cases, you can specify the preconditions as part of the function type signature.</p>

<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Haskell</span>
<span class="n">maxInt</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-&gt;</span> <span class="kt">Int</span> <span class="o">-&gt;</span> <span class="kt">Int</span>
<span class="n">maxInt</span> <span class="n">a</span> <span class="n">b</span> <span class="o">=</span> <span class="kr">if</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span> <span class="kr">then</span> <span class="n">a</span> <span class="kr">else</span> <span class="n">b</span>
</code></pre></div></div>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Rust</span>
<span class="k">fn</span> <span class="nf">max_int</span> <span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="nb">i32</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="nb">i32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">i32</span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span> <span class="p">{</span> <span class="n">a</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">b</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>In this example, the precondition that the numbers must be integers is unnecessary. The only preconditions that are truly required are that both arguments have the same type, and that they can be compared to each other. We can specify that both arguments have the same type with polymorphism, and specify that they can be compared using a type constraint:</p>

<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">maxAny</span> <span class="o">::</span> <span class="p">(</span><span class="kt">Ord</span> <span class="n">a</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="n">a</span>
<span class="n">maxAny</span> <span class="n">a</span> <span class="n">b</span> <span class="o">=</span> <span class="kr">if</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span> <span class="kr">then</span> <span class="n">a</span> <span class="kr">else</span> <span class="n">b</span>
</code></pre></div></div>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="n">max_any</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="nb">Ord</span><span class="o">&gt;</span> <span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="n">T</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">T</span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span> <span class="p">{</span> <span class="n">a</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="n">b</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The second examples are more reusable. This should be fairly obvious considering the second example is generic, where the first example is not. Not to say that I advocate making absolutely everything as generic as possible, only that more generic functions are more reusable. More specifically, the reason that generic functions are more reusable is because they specify a smaller set of preconditions.</p>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Use generics to make code more reusable.</th>
</tr></table>

<p>Although the above reasoning is agnostic regarding the programming paradigm used, those who are familiar with Object Orientated design idioms may find this familiar. Reducing the preconditions by making a function more generic corresponds to the ‘I’ and ‘D’ of SOLID. The ‘Interface Segregation’ principle recommends directly reducing the interface size, whilst the ‘Dependency Inversion’ principle recommends using interfaces in the first instance.</p>

<p>Those that are familiar with functional programming may see that the second example has been universally quantified. If the type signature of the above example can be thought of as a predicate in first order logic, then a universally quantified predicate is a stronger statement than an unquantified one.</p>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Use best practice for your preferred programming paradigm.</th>
</tr></table>

<h3 id="example-2-unnecessary-input">Example 2: Unnecessary Input</h3>

<p>Although making functions more generic will make them more reusable, it does not cover every use case. Most notably passing too much data into a function limits it’s reuse. I use TypeScript in this example as it is usually easy to understand:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Typescript</span>
<span class="kd">class</span> <span class="nc">Person</span> <span class="p">{</span>
    <span class="k">private</span> <span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
    <span class="k">private</span> <span class="nx">phoneNumber</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
    <span class="k">private</span> <span class="nx">age</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span>

    <span class="nf">constructor</span><span class="p">(</span><span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">phoneNumber</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">age</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">phoneNumber</span> <span class="o">=</span> <span class="nx">phoneNumber</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">age</span> <span class="o">=</span> <span class="nx">age</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nf">textMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">:</span> <span class="kr">string</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Message sent to </span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">phoneNumber</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`The message was: "</span><span class="p">${</span><span class="nx">message</span><span class="p">}</span><span class="s2">"`</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="p">(</span><span class="dl">"</span><span class="s2">John Doe</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">0491 570 110</span><span class="dl">"</span><span class="p">,</span> <span class="mi">35</span><span class="p">);</span>
<span class="nx">person</span><span class="p">.</span><span class="nf">textMessage</span><span class="p">(</span><span class="dl">"</span><span class="s2">Save on a new car with out promotional deal!</span><span class="dl">"</span><span class="p">);</span>
</code></pre></div></div>

<p>In this case, the <code class="language-plaintext highlighter-rouge">textMessage</code> method takes a <code class="language-plaintext highlighter-rouge">Person</code> object as <code class="language-plaintext highlighter-rouge">this</code>, and a string representing the message. The <code class="language-plaintext highlighter-rouge">textMessage</code> function only uses the <code class="language-plaintext highlighter-rouge">phoneNumber</code> property of <code class="language-plaintext highlighter-rouge">Person</code>. Requiring a <code class="language-plaintext highlighter-rouge">Person</code> is an unnecessary precondition. The <code class="language-plaintext highlighter-rouge">textMessage</code> function can be made more reusable by removing that precondition:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">textMessage</span><span class="p">(</span><span class="nx">phoneNumber</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">message</span><span class="p">:</span> <span class="kr">string</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Message sent to </span><span class="p">${</span><span class="nx">phoneNumber</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`The message was: "</span><span class="p">${</span><span class="nx">message</span><span class="p">}</span><span class="s2">"`</span><span class="p">);</span>
<span class="p">}</span>
<span class="nf">textMessage</span><span class="p">(</span><span class="dl">"</span><span class="s2">0491 570 110</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">Save on a new car with out promotional deal!</span><span class="dl">"</span><span class="p">)</span>
</code></pre></div></div>

<p>It should be possible to send a text message to any valid phone number, not just phone numbers that have been assigned to a particular person. It should also be possible to send a text message if the name or age of the person is unknown.</p>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th>Recommendation: Pass the minimum required data into a function.</th>
</tr></table>

<p>The larger the class is, the more unnecessary data will be passed to any given method. For example: if a class is responsible for two separate items, then methods which regard only the first item, or only the second will be passed unnecessary state as part of <code class="language-plaintext highlighter-rouge">this</code>.</p>

<p>Note that this ties back in with the ‘S’ of SOLID. The ‘Single Responsibility’ principle recommends breaking classes with many responsibilities into smaller classes.</p>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Keep classes and data structures small.</th>
</tr></table>

<h3 id="other-examples">Other Examples</h3>

<ul>
  <li>Functions that require more arguments than are necessary.</li>
  <li>Non <code class="language-plaintext highlighter-rouge">static</code> methods that can be made <code class="language-plaintext highlighter-rouge">static</code>.</li>
  <li>Making a function <code class="language-plaintext highlighter-rouge">async</code> when it doesn’t need to be.</li>
  <li>Using mutable references when immutable references would suffice.</li>
</ul>

<h2 id="the-largest-set-of-postconditions">The Largest Set of Postconditions</h2>

<p>In order for a function to be maximally reusable, it must be useful in as many places as possible. Each potential call site may place requirements on the result of the function. Therefore, it would make sense that the more strict the postconditions, the more places the function can satisfy the requirements of the call sites.</p>

<h3 id="example-1-return-the-parent-class">Example 1: Return the Parent Class</h3>

<p>In Object Orientated programming, a parent class can be used wherever a child class can be used, but not the other way around. To make the function as reusable as possible, return the parent class:</p>

<table><tr>
    <td width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></td>
    <td> For functional programs, returning a base class would be the equivalent of returning an existentially quantified data type.</td>
</tr></table>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Typescript</span>
<span class="kd">class</span> <span class="nc">Child</span> <span class="p">{</span>
    <span class="nf">childFunc</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">I'm a Child</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="nc">Parent</span> <span class="kd">extends</span> <span class="nc">Child</span> <span class="p">{</span>
    <span class="nf">parentFunc</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">I'm a Parent</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">factoryChild</span> <span class="p">():</span> <span class="nx">Child</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="nc">Parent</span><span class="p">();</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">factoryParent</span> <span class="p">():</span> <span class="nx">Parent</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="nc">Parent</span><span class="p">();</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">p1</span><span class="p">:</span> <span class="nx">Parent</span> <span class="o">=</span> <span class="nf">factoryParent</span><span class="p">();</span>
<span class="c1">// Error: Child does not implement parentFunc</span>
<span class="c1">// const p2: Parent = factoryChild();</span>

<span class="kd">const</span> <span class="nx">c1</span><span class="p">:</span> <span class="nx">Child</span> <span class="o">=</span> <span class="nf">factoryParent</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">c2</span><span class="p">:</span> <span class="nx">Child</span> <span class="o">=</span> <span class="nf">factoryChild</span><span class="p">();</span>
</code></pre></div></div>

<p>Note that it is often recommended elsewhere to use abstract factories which return interfaces, or virtual base classes instead of concretions. Returning the parent like I recommend in this case is therefore discouraged. If this makes you uncomfortable, you can always write a wrapper function to turn a concretion into an abstraction. This can’t be done the other way around:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Convert a concretion to an abstraction</span>
<span class="kd">function</span> <span class="nf">factoryChild2</span> <span class="p">():</span> <span class="nx">Child</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nf">factoryParent</span><span class="p">();</span>
<span class="p">}</span>

<span class="c1">// Cannot be done in reverse</span>
<span class="c1">// function factoryParent2 (): Parent {</span>
<span class="c1">//     return factoryChild();</span>
<span class="c1">// }</span>
</code></pre></div></div>

<p>Alternatively if the factory function could return multiple concretions, then the return type has to be an abstraction, so the above code doesn’t even apply:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Parent2</span> <span class="kd">extends</span> <span class="nc">Child</span> <span class="p">{</span>
    <span class="nf">parent2Func</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">I'm the second Parent</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Can't return a Parent type here. Returning</span>
<span class="c1">// a Child is the most minimal postcondition.</span>
<span class="kd">function</span> <span class="nf">abstractFactoryChild</span><span class="p">():</span> <span class="nx">Child</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nf">random</span><span class="p">()</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nc">Parent</span><span class="p">();</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nc">Parent2</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Return the most specific type possible.</th>
</tr></table>

<h3 id="example-2-validating-arguments">Example 2: Validating Arguments</h3>

<p>In the general case, throwing exceptions is a normal part of programming. Some things are just not in our control, so we just do the best we can, handle it and clean up the mess. If a function validates arguments and returns early on failure, then this indicates that the preconditions are too lenient:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Typescript</span>
<span class="kd">function</span> <span class="nf">mayHaveBadArgument</span><span class="p">(</span><span class="nx">argument</span><span class="p">:</span> <span class="kr">number</span> <span class="o">|</span> <span class="kc">null</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">argument</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="dl">"</span><span class="s2">Bad argument</span><span class="dl">"</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="nx">argument</span><span class="p">.</span><span class="nf">toString</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Perhaps this is too obvious an example and would not appear in the real world, I suspect something like the following is written more commonly:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">mayHaveBadArgument</span><span class="p">(</span><span class="nx">argument</span><span class="p">:</span> <span class="kr">number</span> <span class="o">|</span> <span class="kc">null</span><span class="p">):</span> <span class="kr">string</span> <span class="o">|</span> <span class="kc">null</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">argument</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="nx">argument</span><span class="p">.</span><span class="nf">toString</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>In this case, <code class="language-plaintext highlighter-rouge">null</code> is an invalid value, so why accept it as an argument at all? Maybe it would be better to just take a number and return a string, and make it up to the caller to check for the precondition.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">printNumber</span><span class="p">(</span><span class="nx">argument</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">argument</span><span class="p">.</span><span class="nf">toString</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Note that this is a bit controversial for two reasons. Firstly it gives stricter preconditions and stricter postconditions, when we would prefer stricter postconditions and more lenient preconditions. Secondly, argument checking code might end up being duplicated at a lot of call sites.</p>

<p>Both of these problems can be fixed by creating a second function that only validates the arguments. Note here, that in this toy example it doesn’t really provide any benefits, but the benefit may become more obvious in larger examples.</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">printNumberChecked</span><span class="p">(</span><span class="nx">argument</span><span class="p">:</span> <span class="kr">number</span> <span class="o">|</span> <span class="kc">null</span><span class="p">):</span> <span class="kr">string</span> <span class="o">|</span> <span class="kc">null</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">argument</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
    <span class="p">}</span>
    
    <span class="k">return</span> <span class="nf">printNumber</span><span class="p">(</span><span class="nx">argument</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>On one hand, the callers of <code class="language-plaintext highlighter-rouge">printNumber</code> do not have to check the return value for <code class="language-plaintext highlighter-rouge">null</code>. On the other hand, callers using <code class="language-plaintext highlighter-rouge">printNumberChecked</code> do not have to check <code class="language-plaintext highlighter-rouge">argument</code> for <code class="language-plaintext highlighter-rouge">null</code>. If <code class="language-plaintext highlighter-rouge">argument</code> is known not to be <code class="language-plaintext highlighter-rouge">null</code>, then use <code class="language-plaintext highlighter-rouge">printNumber</code>, otherwise, use <code class="language-plaintext highlighter-rouge">printNumberChecked</code>.</p>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Don't write a function that compromises lenient preconditions for strict postconditions or vice versa. Write two functions instead.</th>
</tr></table>

<p>This is the first recommendation that states that something is specifically a <em>bad</em> abstraction. Not every abstraction will be a good one, so there should be rules for things that specifically shouldn’t be done.</p>

<h4 id="advanced-usage-for-functional-programs">Advanced Usage for Functional Programs</h4>

<p>Note that for most languages <code class="language-plaintext highlighter-rouge">printNumberChecked</code> may not be that good an abstraction. It’s not reusable enough and does some fairly trivial checking. I wouldn’t stress if this appears in your code a lot. A functional programmer may notice that <code class="language-plaintext highlighter-rouge">T | null</code> is a functor, and <code class="language-plaintext highlighter-rouge">printNumberChecked</code> is a poorly written version of <code class="language-plaintext highlighter-rouge">map</code> or <code class="language-plaintext highlighter-rouge">fmap</code> specialized for <code class="language-plaintext highlighter-rouge">printNumber</code>:</p>

<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Haskell</span>
<span class="n">printNumber</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-&gt;</span> <span class="kt">String</span>
<span class="n">printNumber</span> <span class="o">=</span> <span class="n">show</span>

<span class="n">printNumberChecked</span> <span class="o">::</span> <span class="p">(</span><span class="kt">Functor</span> <span class="n">f</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">f</span> <span class="kt">Int</span> <span class="o">-&gt;</span> <span class="n">f</span> <span class="kt">String</span>
<span class="n">printNumberChecked</span> <span class="o">=</span> <span class="n">fmap</span> <span class="n">printNumber</span>
</code></pre></div></div>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Typescript</span>
<span class="kd">function</span> <span class="nf">mapOptional</span><span class="o">&lt;</span><span class="nx">T</span><span class="p">,</span> <span class="nx">R</span><span class="o">&gt;</span><span class="p">(</span><span class="nx">func</span><span class="p">:</span> <span class="p">(</span><span class="nx">arg</span><span class="p">:</span> <span class="nx">T</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">R</span><span class="p">):</span> <span class="p">(</span><span class="nx">arg</span><span class="p">:</span> <span class="nx">T</span> <span class="o">|</span> <span class="kc">null</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">R</span> <span class="o">|</span> <span class="kc">null</span> <span class="p">{</span>
    <span class="k">return </span><span class="p">(</span><span class="nx">arg</span><span class="p">:</span> <span class="nx">T</span> <span class="o">|</span> <span class="kc">null</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">arg</span> <span class="o">===</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="nf">func</span><span class="p">(</span><span class="nx">arg</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">printNumberChecked</span> <span class="o">=</span> <span class="nf">mapOptional</span><span class="p">(</span><span class="nx">printNumber</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">assert</span><span class="p">(</span><span class="nf">printNumberChecked</span><span class="p">(</span><span class="kc">null</span><span class="p">)</span> <span class="o">===</span> <span class="kc">null</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">assert</span><span class="p">(</span><span class="nf">printNumberChecked</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">5</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Don't use a function with side effects when a pure function will do.</th>
</tr></table>

<p>Note that this is generally not idiomatic code except for functional languages. I wouldn’t use this unless you, and all of you co-contributors are on the same page.</p>

<h2 id="perform-the-smallest-amount-of-non-trivial-work">Perform the Smallest Amount of Non-trivial Work</h2>

<p>In order for a program to actually realize the benefits of reusable code, the program must actually reuse it’s components. Whilst the above principles will help determine what abstractions are good to take, this principle determines how they should be applied.</p>

<p>If a function provides no benefit over writing the code inline, then I would consider it a trivial amount of work. That means trivial functions do not improve the ergonomics, prevent errors or improve any other measurable (or subjective) element of code.</p>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Don't write trivial abstractions.</th>
</tr></table>

<p>A function does not perform the smallest possible non-trivial work if it can be broken down into at least two smaller non-trivial pieces. For the sake of argument, say that a non-trivial function called <code class="language-plaintext highlighter-rouge">f</code> could be refactored into two smaller non-trivial functions called <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code> that could be recombined to form <code class="language-plaintext highlighter-rouge">f</code>. <code class="language-plaintext highlighter-rouge">f</code> must either contain duplicates of <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code> inside it’s body, or it must be defined in terms of <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code>.</p>

<p>Assume <code class="language-plaintext highlighter-rouge">f</code> is defined in terms of <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code>. <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code> would have smaller preconditions than <code class="language-plaintext highlighter-rouge">f</code>, so they would be able to be used in more places. If <code class="language-plaintext highlighter-rouge">f</code> is defined in terms of <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code>, it either contains the the smallest amount of non trivial work to combine <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code>, or it can be broken down further, in which case we do so and re-examine the components.</p>

<p>Either way, a function either contains duplicate code, contains preconditions that are too strict, or it performs the smallest amount of non-trivial work. In other words, large functions can be broken down into pieces to make them more reusable.</p>

<h3 id="examples">Examples</h3>

<p>I won’t talk much more about this topic as there appears to be a broad consensus that smaller composable functions are better than larger ones. I’ll link to <a href="http://web.eecs.umich.edu/~imarkov/10rules.pdf">NASA’s ten rules</a> for safety critical software, which states that functions written in C should not have more than a single page’s worth of code in them.</p>

<table><tr>
    <th width="64"><img src="/notepad/img/info_icon.png" alt="information" width="32" /></th>
    <th> Recommendation: Break large functions into smaller ones.</th>
</tr></table>

<h2 id="should-i-refactor-my-code">Should I Refactor my Code?</h2>

<ul>
  <li><strong>I have two similar functions, should I refactor them into one?</strong>
    <ul>
      <li>If you can combine the two functions without weakening the postconditions, or strengthening the preconditions: then go ahead. If the function is too big, consider splitting it into parts.</li>
    </ul>
  </li>
  <li><strong>I have two identical functions, should I refactor them into one?</strong>
    <ul>
      <li>Yes.</li>
    </ul>
  </li>
  <li><strong>I have a function that I think could be refactored based on the above principles but it isn’t duplicated anywhere, should I do it?</strong>
    <ul>
      <li>If you can weaken the preconditions, strengthen the postconditions, or if you think the function is too big, it should be OK to refactor. This assumes that any requirement could change anywhere in your program at any time.</li>
    </ul>
  </li>
  <li><strong>I have a function that I think might be big enough that it can be split into parts, but it’s borderline. Should I split it?</strong>
    <ul>
      <li>The triviality of a function is subjective. If you think that it improves ergonomics, makes the code easier to read, or reduces the possibility of errors compared to writing it inline, do it.</li>
    </ul>
  </li>
  <li><strong>I have a function that could be more generic, should I do it?</strong>
    <ul>
      <li>If you don’t weaken the postconditions in doing so, or make the function too big, then it should be fine. Caveat: sometimes the function already does it’s job and you don’t need it to be generic. Then it might not be worth the effort.</li>
    </ul>
  </li>
  <li><strong>I have a function where the return type could be made more specific, should I do it?</strong>
    <ul>
      <li>If you don’t weaken the preconditions, or make the function too big, then go ahead.</li>
    </ul>
  </li>
  <li><strong>What about return type polymorphism? Doesn’t that make code more reusable while making the postconditions weaker?</strong>
    <ul>
      <li>Return type polymorphism is equivalent to passing an (often zero sized) type as an argument, therefore weakening the preconditions. The three principles do not state if this is a good or a bad thing. Consider having both a specialized variant, and a generic one for different circumstances.</li>
    </ul>
  </li>
  <li><strong>I have an object that might be too large, should I split it into two?</strong>
    <ul>
      <li>If at least one of the methods does not need access to the whole object, consider splitting it. Exception: delegation, getters/setters.</li>
    </ul>
  </li>
  <li><strong>Is XXX is a good abstraction?</strong>
    <ul>
      <li>If you can define the preconditions, postconditions, and invariants well, then it should be OK, otherwise: probably not.</li>
    </ul>
  </li>
  <li><strong>Is XXX <em>object</em> a good abstraction?</strong>
    <ul>
      <li>Examine the methods individually, and apply the principles above. If all of the methods individually are OK, then the whole object should be too. This assumes that you only access the object through its methods.</li>
    </ul>
  </li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>DRY is a programming principle that has many limitations. An often cited limitation is the capacity of DRY to create inefficient abstractions. Heuristic solutions have been adopted to try to find a good medium. This article presents a different way of deriving DRY from some basic assumptions. It also provides three principles for writing abstractions that aim to be reusable. This allows programmers to write code with no information about the calling context whilst providing some guarantees that the code can and will be reused as many times as possible.</p>

<hr />

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="programming" /><category term="Don&apos;t Repeat Yourself" /><category term="DRY" /><category term="Typescript" /><category term="Rust" /><category term="Haskell" /><category term="Refactoring" /><summary type="html"><![CDATA[Summary]]></summary></entry><entry><title type="html">I made a game in Rust, Here’s what I learned</title><link href="/notepad/post/2019/11/30/game-off.html" rel="alternate" type="text/html" title="I made a game in Rust, Here’s what I learned" /><published>2019-11-30T00:00:00+00:00</published><updated>2019-11-30T00:00:00+00:00</updated><id>/notepad/post/2019/11/30/game-off</id><content type="html" xml:base="/notepad/post/2019/11/30/game-off.html"><![CDATA[<p>Recently I made a game and entered it into the <a href="https://itch.io/jam/game-off-2019">Github Game Off 2019</a>. The premise of the game is that there are a series of cows that run around following rules. The aim in the earlier levels is to get all of the cows into a green area. The aim in later levels is to use the cows to create and program a basic computer.</p>

<p>With these kinds of game jams, there is a restrictive time limit involved. In this case, 30 days. On day 0, you receive a theme in which to base your game upon: the theme was “Leaps And Bounds”. Generally there is not enough time to create a large, polished game given the limitations, and in my case, the game was largely unfinished. There was definitely enough gameplay for a few hours, but I had hopes for a bit more. Well, anyway, here’s how it went.</p>

<h2 id="brainstorming">Brainstorming</h2>

<p>For the first day or two, I tried to come up with ideas on how my game was going to work. I wanted to make a puzzle game of some description, and hopefully something that I would have fun playing as well. As the puzzle maker, it’s almost a given that you know the solution, but there are some problems which you can give yourself a blank palette, describe what you want, and then fill in the gaps. This gives the player (and me) a wide artistic license to solve the problems in their own way.</p>

<p>I had an idea for a tile based automation based on <a href="https://en.wikipedia.org/wiki/Befunge">Befunge</a> where the stack was part of the main memory. A basic language would need an instruction pointer and a stack pointer. In a game scenario, it would make sense that the instruction pointer and stack pointer would be physical entities. I ended up settling on cows, since I could reuse some assets from the last game jam I entered.</p>

<p><img src="/notepad/img/2019-12-01-screenshot-cows.png" alt="You wanted a complete game?" /></p>

<p>In addition, if I was going to create a computer, I needed to give it some limitations. If I made it too easy to write programs, then it would just be programming, however, if I add some artificial limitations, then it becomes a puzzle that needs to be solved.</p>

<h2 id="initial-sprint">Initial sprint</h2>

<p>With only 30 days, I decided to try to remain with things that I already know, which would give me a predictable time limit to complete the game. I knew that I would not need a physics or collision engine, and decided to just create a game that works on a canvas in HTML with no framework. I thought that the game was minimal enough that learning additional frameworks or libraries would have simply wasted time, as the majority of the effort would be spent writing original code anyway.</p>

<p>In hindsight, this was a huge mistake, and I should’ve gone straight to Godot or a well established game engine. Just bundling the program at the end took almost half a day due to various reasons, but Godot would have instantly given me a cross platform binary, and a web version to boot!</p>

<p>For a few days, I used plain Javascript, but it became apparent that some things were going to eat up a lot of time. I would have spent too much time creating persistent data structures for the undo functionality for example. In addition, it became apparent that some of the data was not well suited to JavaScript’s weak typing. As much as JavaScript is quick to prototype, it is largely difficult to refactor.</p>

<p>Given my abilities as a programmer, I decided that it would be faster to switch to a language which has much stronger guarantees about the program at compile time, so that I can offload as much of my mental effort as possible onto the compiler.
My personal experience with Rust is that it requires significantly less thinking while programming; the compiler just <em>tells</em> you what you’ve done wrong.</p>

<p>It took me a day and a half to rewrite what I had in Rust and compile to web assembly. I strongly believe that my productivity increased significantly after the change. In addition, the quality of my code was better than if I had written JavaScript. The reduced debugging ability of Rust on web assembly was largely offset by the fact that most bugs were caught <em>before the program compiled</em>. The bugs that did get past the compiler were easier to fix than JavaScript anyway.</p>
<h2 id="the-first-mistake">The First Mistake</h2>

<p>Theres a saying that if you only have a hammer, then everything starts looking like a nail. I’m no artist or sound designer. I write programs. The main mistake that I made was thinking that this game was going to be a technical exercise in programming. The reality of game design is far different.</p>

<p>Many modern game engines advertise that users can create significant portions of their game without writing any code at all. This is without a doubt a true statement. Unfortunately for me, I had (stupidly) decided not to use a game engine. I had vastly underestimated how much of a game was created by using the tools of an editor.</p>

<p>All of the luxuries that make your life easier with a fully featured game engine were not present. Every animation had to be coded by hand. Every graphic on the sprite sheet was manually selected. The level editor was hand coded. I even ended creating an ad-hoc component system and scene manager. All of this code was strictly unnecessary, and wasted time that I didn’t really have.</p>

<p><img src="/notepad/img/2019-12-01-complete_game.png" alt="You wanted a complete game?" /></p>

<p>I suppose the other benefit to a game engine is having everything already set up for you. With Rust, I had to deal with the JavaScript foreign function interface. Using a foreign function interface is not great even at the best of times, so spending a lot of time getting trivial things to work was a bit stifling sometimes.</p>

<p>It’s not all a downside: some of the code I wrote would have been difficult to write correctly in a dynamic language (although I am of the opinion that <em>all</em> code is a little bit more difficult to write correctly in a dynamic language). However, in my opinion, 90% of code is usually “dumb” code, which just marshals around data from here to there, and 10% is “smart” code which does something interesting from a computer science standpoint. That means I’m only really worried about making 10% of my code more difficult to write. Godot has official support for many languages, so I’m sure that the benefits would have completely outweighed the downside.</p>

<p>In essence, I would have benefitted greatly by using an engine to create my game. Some of the smaller things that were easier in the past were more difficult. Therefore, some of the more important parts of the gameplay were missing; there simply wasn’t enough time to complete all of it.</p>

<h2 id="the-second-mistake">The Second Mistake</h2>

<p>Apart from not using an engine. My other error was to think of the game as a technical coding exercise rather than a piece of entertainment. Some of the greatest games are not technical masterpieces, and nobody gives wide acclaim to a game and attributes that exclusively to the quality of its code. In reality, if a game is programmed well, then nobody will know.</p>

<p>Unfortunately I’m not an artist or a musician. Therefore, these aspects were left on the back burner until the very end, an afterthought. In reality, I should have given these parts equal, or more attention than the code itself. If 90% of my code is just marshaling data, then maybe I could have eliminated some of it by using the built in engine capabilities, and spent the rest of my time creating assets that look and feel good.</p>

<p>If I could go back and do it again, I would probably create a series of assets which are more cohesive and atmospheric. Certainly making cows move around a paddock is not particularly dramatic, but I suspect that the graphics could have made a bit more sense.</p>

<h2 id="thats-it">That’s it!</h2>

<p>That was exhausting! 30 days of game-making in your free time is hard work! For 30 days and no engine, I’m quite happy with the result (even if it is incomplete). I made myself a puzzle game that even I had trouble with solving. If nobody else enjoys it, I still had fun, and learned a few things about the relevant technologies.</p>

<p>More importantly, I learned some things that aren’t purely technical: Use the right tools for the right job; manage your time effectively; don’t reinvent the wheel; and if you’re making a game, make it fun to play!</p>

<p>I hope you enjoyed this article, if you want to try the game in all of it’s unfinished glory, you can play it <a href="https://pilotinpyjamas.itch.io/cows">here</a>. The real puzzles start in the second world. Any feedback is welcome.</p>

<hr />

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="post" /><category term="Rust" /><category term="Programming" /><category term="Game Jam" /><category term="Game Design" /><category term="Github Game off" /><summary type="html"><![CDATA[Recently I made a game and entered it into the Github Game Off 2019. The premise of the game is that there are a series of cows that run around following rules. The aim in the earlier levels is to get all of the cows into a green area. The aim in later levels is to use the cows to create and program a basic computer.]]></summary></entry><entry><title type="html">Easy persistent data structures in Rust</title><link href="/notepad/notes/2019/10/26/persistant_data.html" rel="alternate" type="text/html" title="Easy persistent data structures in Rust" /><published>2019-10-26T00:00:00+00:00</published><updated>2019-10-26T00:00:00+00:00</updated><id>/notepad/notes/2019/10/26/persistant_data</id><content type="html" xml:base="/notepad/notes/2019/10/26/persistant_data.html"><![CDATA[<h3 id="summary">Summary</h3>

<ul>
  <li>A persistent data structure can easily keep track of previous versions of itself with little overhead.</li>
  <li>A regular data structure can be converted into a persistent one by replacing instances of <code class="language-plaintext highlighter-rouge">Box</code> with <code class="language-plaintext highlighter-rouge">Rc</code>, and replacing mutable dereferences with <code class="language-plaintext highlighter-rouge">Rc::make_mut</code>.</li>
  <li>The resulting structure is both more performant and uses less memory if you plan on performing lots of clones.</li>
</ul>

<h2 id="what-is-a-persistent-data-structure">What is a persistent data structure?</h2>

<p>Data structures are persistent when they can keep track of all of their old states. Every time a modification is made, a new structure is created instead of modifying the original data. Persistent data structures are often referred to as immutable, because the original data is left untouched.</p>

<p>A naive persistent version of any data structure is trivial to make: Just clone the entire structure every time a change is made, and then commit the relevant changes to the new version. That way the old version is kept. However, for anything larger than a trivially small structure, this is going to be problematic.</p>

<p>There is a better way to create persistent data structures. Instead of copying the entire structure each time a modification is made, only the parts that have been modified need to be copied. The rest of the data is shared between old and new versions. This can be performed through the use of clone-on-write pointers.</p>

<p><img src="/notepad/img/2019-10-27-tree.jpg" alt="When modifying a tree, many of the nodes are shared." /></p>

<p>Rust provides three clone-on-write pointers in the standard library: <code class="language-plaintext highlighter-rouge">Cow</code>, <code class="language-plaintext highlighter-rouge">Rc</code> and <code class="language-plaintext highlighter-rouge">Arc</code>. <code class="language-plaintext highlighter-rouge">Cow</code> only sometimes owns it’s own data, so is not suitable for these kinds of data structure. In this article, <code class="language-plaintext highlighter-rouge">Rc</code> will be used, but <code class="language-plaintext highlighter-rouge">Arc</code> is equally valid.</p>

<p>Note that in Rust, instead of creating a new version every time a structure is modified, the persistent structures will have both a cheap clone function, and will share memory with older versions of themselves, but will otherwise share an API with their non-persistent counterparts.</p>

<h2 id="example-1-a-singly-linked-list">Example 1: A singly linked list.</h2>

<p>Let’s get stuck into into it. Consider a simple implementation of a non persistent singly linked list using <code class="language-plaintext highlighter-rouge">Box</code>. Mind you, that I don’t recommend using this kind of data structure for everyday use for well known reasons.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">#[derive(Debug,</span> <span class="nd">Clone)]</span>
<span class="k">pub</span> <span class="k">enum</span> <span class="n">ListBox</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">Nil</span><span class="p">,</span>
    <span class="nf">Cons</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="n">ListBox</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;&gt;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="n">ListBox</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nn">ListBox</span><span class="p">::</span><span class="n">Nil</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">cons</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">elem</span><span class="p">:</span> <span class="n">A</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">tail</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">replace</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="nn">ListBox</span><span class="p">::</span><span class="n">Nil</span><span class="p">);</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">list</span> <span class="o">=</span> <span class="nn">ListBox</span><span class="p">::</span><span class="nf">Cons</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nn">Box</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">tail</span><span class="p">));</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">swap</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">list</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">uncons</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">list</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">replace</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="nn">ListBox</span><span class="p">::</span><span class="n">Nil</span><span class="p">);</span>
        <span class="k">match</span> <span class="n">list</span> <span class="p">{</span>
            <span class="nn">ListBox</span><span class="p">::</span><span class="n">Nil</span> <span class="k">=&gt;</span> <span class="nb">None</span><span class="p">,</span>
            <span class="nn">ListBox</span><span class="p">::</span><span class="nf">Cons</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="k">mut</span> <span class="n">tail</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">swap</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">tail</span><span class="p">);</span>
                <span class="nf">Some</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Seems simple enough. <code class="language-plaintext highlighter-rouge">new</code> creates an empty list and <code class="language-plaintext highlighter-rouge">cons</code> adds an element to a pre-existing list. To read from the list, <code class="language-plaintext highlighter-rouge">uncons</code> removes the first element. Essentially, this list acts like a stack where <code class="language-plaintext highlighter-rouge">cons</code> is <code class="language-plaintext highlighter-rouge">push</code> and <code class="language-plaintext highlighter-rouge">uncons</code> is <code class="language-plaintext highlighter-rouge">pop</code>.</p>

<p>To test this list, a dummy structure is used which implements <code class="language-plaintext highlighter-rouge">Clone</code>. This can be used to track how many clones are performed at runtime:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">#[derive(Debug)]</span>
<span class="k">struct</span> <span class="nf">CloneTracker</span><span class="p">(</span><span class="nb">u32</span><span class="p">);</span>
<span class="k">impl</span> <span class="nb">Clone</span> <span class="k">for</span> <span class="n">CloneTracker</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">clone</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"Cloning {}..."</span><span class="p">,</span> <span class="k">self</span><span class="na">.0</span><span class="p">);</span>
        <span class="n">CloneTracker</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The list works as expected:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">list_box</span> <span class="o">=</span> <span class="nn">ListBox</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
<span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">0</span><span class="o">..</span><span class="mi">10</span> <span class="p">{</span>
    <span class="n">list_box</span><span class="nf">.cons</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">i</span><span class="p">));</span>
<span class="p">}</span>

<span class="c1">// prints "Cloning x..." ten times</span>
<span class="k">let</span> <span class="n">_clone</span> <span class="o">=</span> <span class="n">list_box</span><span class="nf">.clone</span><span class="p">();</span>

<span class="n">list_box</span><span class="nf">.cons</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">20</span><span class="p">));</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">list_box</span><span class="nf">.uncons</span><span class="p">(),</span> <span class="nf">Some</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">20</span><span class="p">)));</span>

<span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="mi">10</span><span class="p">)</span><span class="nf">.rev</span><span class="p">()</span> <span class="p">{</span>
    <span class="nd">assert_eq!</span><span class="p">(</span><span class="n">list_box</span><span class="nf">.uncons</span><span class="p">(),</span> <span class="nf">Some</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">i</span><span class="p">)));</span>
<span class="p">}</span>

<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">list_box</span><span class="nf">.uncons</span><span class="p">(),</span> <span class="nb">None</span><span class="p">);</span>
</code></pre></div></div>

<p>The list is cloned to keep an older version of it for later. Every element in the list is cloned which is confirmed by the output produced by the <code class="language-plaintext highlighter-rouge">CloneTracker</code>.</p>

<p>To make the list persistent, two modifications are required: Firstly, change any <code class="language-plaintext highlighter-rouge">Box</code> to an <code class="language-plaintext highlighter-rouge">Rc</code>. Secondly, whenever a <code class="language-plaintext highlighter-rouge">Box</code> was mutably dereferenced in the old code, replace it with <code class="language-plaintext highlighter-rouge">Rc::make_mut</code>:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">#[derive(Debug,</span> <span class="nd">Clone)]</span>
<span class="k">pub</span> <span class="k">enum</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">Nil</span><span class="p">,</span>
    <span class="nf">Cons</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="nb">Rc</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;&gt;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">A</span><span class="p">:</span> <span class="nb">Clone</span><span class="o">&gt;</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nn">List</span><span class="p">::</span><span class="n">Nil</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">cons</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">elem</span><span class="p">:</span> <span class="n">A</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">tail</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">replace</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="nn">List</span><span class="p">::</span><span class="n">Nil</span><span class="p">);</span>
        <span class="k">let</span> <span class="k">mut</span> <span class="n">list</span> <span class="o">=</span> <span class="nn">List</span><span class="p">::</span><span class="nf">Cons</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="nn">Rc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">tail</span><span class="p">));</span>
        <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">swap</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">list</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">uncons</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">list</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">replace</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="nn">List</span><span class="p">::</span><span class="n">Nil</span><span class="p">);</span>
        <span class="k">match</span> <span class="n">list</span> <span class="p">{</span>
            <span class="nn">List</span><span class="p">::</span><span class="n">Nil</span> <span class="k">=&gt;</span> <span class="nb">None</span><span class="p">,</span>
            <span class="nn">List</span><span class="p">::</span><span class="nf">Cons</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="k">mut</span> <span class="n">tail</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="nn">std</span><span class="p">::</span><span class="nn">mem</span><span class="p">::</span><span class="nf">swap</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="nn">Rc</span><span class="p">::</span><span class="nf">make_mut</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">tail</span><span class="p">));</span>
                <span class="nf">Some</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>To confirm that the list is correct, it is tested:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">list</span> <span class="o">=</span> <span class="nn">List</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>
<span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">0</span><span class="o">..</span><span class="mi">10</span> <span class="p">{</span>
    <span class="n">list</span><span class="nf">.cons</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">i</span><span class="p">));</span>
<span class="p">}</span>

<span class="c1">// prints "Cloning x..." once!</span>
<span class="k">let</span> <span class="n">_clone</span> <span class="o">=</span> <span class="n">list</span><span class="nf">.clone</span><span class="p">();</span>

<span class="n">list</span><span class="nf">.cons</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">20</span><span class="p">));</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">list</span><span class="nf">.uncons</span><span class="p">(),</span> <span class="nf">Some</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">20</span><span class="p">)));</span>

<span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="mi">10</span><span class="p">)</span><span class="nf">.rev</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// prints "Cloning i..."</span>
    <span class="nd">assert_eq!</span><span class="p">(</span><span class="n">list</span><span class="nf">.uncons</span><span class="p">(),</span> <span class="nf">Some</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">i</span><span class="p">)));</span>
<span class="p">}</span>

<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">list</span><span class="nf">.uncons</span><span class="p">(),</span> <span class="nb">None</span><span class="p">);</span>
</code></pre></div></div>

<p>This works almost identically to the previous example. The difference is that the clones are performed at different times. In the first example The clones are performed at the <code class="language-plaintext highlighter-rouge">clone</code> call. In the second example, the clones are delayed until the list is actually modified. You can confirm that this is the case by commenting out the lines in question.</p>

<p>It turns out that the original list and its clone share the majority of the data. During a modification, only the data that needs to be modified is cloned, and the rest remains shared. In essence, each list pretends that it holds a clone of all of its own data, but in reality, the clone operation only occurs when the data is written.</p>

<h2 id="example-2-a-tree">Example 2: A tree.</h2>

<p>Next consider a simple implementation of a tree using <code class="language-plaintext highlighter-rouge">Box</code>. For brevity, this will not be a balanced tree. Again, this implementation is overly simplified and I would not recommend using this structure in practice:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">#[derive(Debug)]</span>
<span class="k">pub</span> <span class="k">enum</span> <span class="n">TreeBox</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">Leaf</span><span class="p">,</span>
    <span class="nf">Node</span><span class="p">(</span><span class="nb">Box</span><span class="o">&lt;</span><span class="n">TreeBox</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;&gt;</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="n">TreeBox</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;&gt;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">A</span><span class="p">:</span> <span class="nb">Ord</span><span class="o">&gt;</span> <span class="n">TreeBox</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nn">TreeBox</span><span class="p">::</span><span class="n">Leaf</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">singleton</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nn">TreeBox</span><span class="p">::</span><span class="nf">Node</span><span class="p">(</span><span class="nn">Box</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">TreeBox</span><span class="p">::</span><span class="n">Leaf</span><span class="p">),</span> <span class="n">value</span><span class="p">,</span> <span class="nn">Box</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">TreeBox</span><span class="p">::</span><span class="n">Leaf</span><span class="p">))</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">insert</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">input</span><span class="p">:</span> <span class="n">A</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">match</span> <span class="o">*</span><span class="k">self</span> <span class="p">{</span>
            <span class="nn">TreeBox</span><span class="p">::</span><span class="n">Leaf</span> <span class="k">=&gt;</span> <span class="o">*</span><span class="k">self</span> <span class="o">=</span> <span class="nn">TreeBox</span><span class="p">::</span><span class="nf">singleton</span><span class="p">(</span><span class="n">input</span><span class="p">),</span>
            <span class="nn">TreeBox</span><span class="p">::</span><span class="nf">Node</span><span class="p">(</span><span class="k">ref</span> <span class="k">mut</span> <span class="n">left</span><span class="p">,</span> <span class="k">ref</span> <span class="n">value</span><span class="p">,</span> <span class="k">ref</span> <span class="k">mut</span> <span class="n">right</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">if</span> <span class="o">&amp;</span><span class="n">input</span> <span class="o">&lt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="n">left</span><span class="nf">.insert</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">&amp;</span><span class="n">input</span> <span class="o">&gt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="n">right</span><span class="nf">.insert</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">find</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">elem</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">bool</span> <span class="p">{</span>
        <span class="k">match</span> <span class="o">*</span><span class="k">self</span> <span class="p">{</span>
            <span class="nn">TreeBox</span><span class="p">::</span><span class="n">Leaf</span> <span class="k">=&gt;</span> <span class="k">false</span><span class="p">,</span>
            <span class="nn">TreeBox</span><span class="p">::</span><span class="nf">Node</span><span class="p">(</span><span class="k">ref</span> <span class="n">left</span><span class="p">,</span> <span class="k">ref</span> <span class="n">value</span><span class="p">,</span> <span class="k">ref</span> <span class="n">right</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">if</span> <span class="n">elem</span> <span class="o">&lt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="n">left</span><span class="nf">.find</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">elem</span> <span class="o">&gt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="n">right</span><span class="nf">.find</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                    <span class="k">true</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">new</code> creates an empty tree and <code class="language-plaintext highlighter-rouge">singleton</code> creates a tree with a single element. <code class="language-plaintext highlighter-rouge">insert</code> is used to build a tree by inserting elements, and <code class="language-plaintext highlighter-rouge">find</code> will return <code class="language-plaintext highlighter-rouge">true</code> if the element exists in the tree. Most of the implementation of a tree is omitted, but you get the idea.</p>

<p>The tree can be tested to ensure that it works correctly:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">extern</span> <span class="k">crate</span> <span class="n">rand</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">rand</span><span class="p">::</span><span class="nn">seq</span><span class="p">::</span><span class="n">SliceRandom</span><span class="p">;</span>

<span class="k">let</span> <span class="k">mut</span> <span class="n">tree</span> <span class="o">=</span> <span class="nn">TreeBox</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

<span class="c1">// even numbers only.</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">numbers</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="mi">50</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">x</span><span class="p">|</span> <span class="n">x</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span><span class="nf">.collect</span><span class="p">();</span>
<span class="n">numbers</span><span class="nf">.shuffle</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="nn">rand</span><span class="p">::</span><span class="nf">thread_rng</span><span class="p">());</span>

<span class="k">for</span> <span class="n">num</span> <span class="k">in</span> <span class="n">numbers</span><span class="nf">.clone</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">tree</span><span class="nf">.insert</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">num</span><span class="p">));</span>
<span class="p">}</span>

<span class="c1">// prints "Cloning x..." 50 times.</span>
<span class="k">let</span> <span class="n">_clone</span> <span class="o">=</span> <span class="n">tree</span><span class="nf">.clone</span><span class="p">();</span>

<span class="n">tree</span><span class="nf">.insert</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">47</span><span class="p">));</span>
<span class="n">tree</span><span class="nf">.insert</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">15</span><span class="p">));</span>

<span class="k">for</span> <span class="n">num</span> <span class="k">in</span> <span class="n">numbers</span> <span class="p">{</span>
    <span class="nd">assert_eq!</span><span class="p">(</span><span class="n">tree</span><span class="nf">.find</span><span class="p">(</span><span class="o">&amp;</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">num</span><span class="p">)),</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">tree</span><span class="nf">.find</span><span class="p">(</span><span class="o">&amp;</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">47</span><span class="p">)),</span> <span class="kc">true</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">tree</span><span class="nf">.find</span><span class="p">(</span><span class="o">&amp;</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">15</span><span class="p">)),</span> <span class="kc">true</span><span class="p">);</span>
</code></pre></div></div>

<p>Note that when the clone operation is performed, all of the nodes are cloned. This behaves exactly as you would normally expect. To store an old version of the structure, twice the memory of the original structure is required.</p>

<p>Again, if we make the same modifications: replacing every instance of <code class="language-plaintext highlighter-rouge">Box</code> with <code class="language-plaintext highlighter-rouge">Rc</code> and using <code class="language-plaintext highlighter-rouge">Rc::make_mut</code> every time we want a mutable reference, the structure requires far less cloning:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">pub</span> <span class="k">enum</span> <span class="n">Tree</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">Leaf</span><span class="p">,</span>
    <span class="nf">Node</span><span class="p">(</span><span class="nb">Rc</span><span class="o">&lt;</span><span class="n">Tree</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;&gt;</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="nb">Rc</span><span class="o">&lt;</span><span class="n">Tree</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;&gt;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">A</span><span class="p">:</span> <span class="nb">Ord</span> <span class="o">+</span> <span class="nb">Clone</span><span class="o">&gt;</span> <span class="n">Tree</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nn">Tree</span><span class="p">::</span><span class="n">Leaf</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">singleton</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nn">Tree</span><span class="p">::</span><span class="nf">Node</span><span class="p">(</span><span class="nn">Rc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Tree</span><span class="p">::</span><span class="n">Leaf</span><span class="p">),</span> <span class="n">value</span><span class="p">,</span> <span class="nn">Rc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">Tree</span><span class="p">::</span><span class="n">Leaf</span><span class="p">))</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">insert</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">input</span><span class="p">:</span> <span class="n">A</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">match</span> <span class="o">*</span><span class="k">self</span> <span class="p">{</span>
            <span class="nn">Tree</span><span class="p">::</span><span class="n">Leaf</span> <span class="k">=&gt;</span> <span class="o">*</span><span class="k">self</span> <span class="o">=</span> <span class="nn">Tree</span><span class="p">::</span><span class="nf">singleton</span><span class="p">(</span><span class="n">input</span><span class="p">),</span>
            <span class="nn">Tree</span><span class="p">::</span><span class="nf">Node</span><span class="p">(</span><span class="k">ref</span> <span class="k">mut</span> <span class="n">left</span><span class="p">,</span> <span class="k">ref</span> <span class="n">value</span><span class="p">,</span> <span class="k">ref</span> <span class="k">mut</span> <span class="n">right</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">if</span> <span class="o">&amp;</span><span class="n">input</span> <span class="o">&lt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="nn">Rc</span><span class="p">::</span><span class="nf">make_mut</span><span class="p">(</span><span class="n">left</span><span class="p">)</span><span class="nf">.insert</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">&amp;</span><span class="n">input</span> <span class="o">&gt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="nn">Rc</span><span class="p">::</span><span class="nf">make_mut</span><span class="p">(</span><span class="n">right</span><span class="p">)</span><span class="nf">.insert</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">find</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">elem</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">bool</span> <span class="p">{</span>
        <span class="k">match</span> <span class="o">*</span><span class="k">self</span> <span class="p">{</span>
            <span class="nn">Tree</span><span class="p">::</span><span class="n">Leaf</span> <span class="k">=&gt;</span> <span class="k">false</span><span class="p">,</span>
            <span class="nn">Tree</span><span class="p">::</span><span class="nf">Node</span><span class="p">(</span><span class="k">ref</span> <span class="n">left</span><span class="p">,</span> <span class="k">ref</span> <span class="n">value</span><span class="p">,</span> <span class="k">ref</span> <span class="n">right</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
                <span class="k">if</span> <span class="n">elem</span> <span class="o">&lt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="n">left</span><span class="nf">.find</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
                <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">elem</span> <span class="o">&gt;</span> <span class="n">value</span> <span class="p">{</span>
                    <span class="n">right</span><span class="nf">.find</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span>
                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                    <span class="k">true</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If the exact same test is performed as above, the results are markedly different. The difference only increases as the tree becomes larger.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">tree</span> <span class="o">=</span> <span class="nn">Tree</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

<span class="c1">// even numbers only.</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">numbers</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="mi">50</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">x</span><span class="p">|</span> <span class="n">x</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span><span class="nf">.collect</span><span class="p">();</span>
<span class="n">numbers</span><span class="nf">.shuffle</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="nn">rand</span><span class="p">::</span><span class="nf">thread_rng</span><span class="p">());</span>

<span class="k">for</span> <span class="n">num</span> <span class="k">in</span> <span class="n">numbers</span><span class="nf">.clone</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">tree</span><span class="nf">.insert</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">num</span><span class="p">));</span>
<span class="p">}</span>

<span class="c1">// prints "Cloning x..." only once!</span>
<span class="k">let</span> <span class="n">_clone</span> <span class="o">=</span> <span class="n">tree</span><span class="nf">.clone</span><span class="p">();</span>

<span class="c1">// prints "Cloning x..." a few times.</span>
<span class="n">tree</span><span class="nf">.insert</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">47</span><span class="p">));</span>
<span class="c1">// prints "Cloning x..." a few times.</span>
<span class="n">tree</span><span class="nf">.insert</span><span class="p">(</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">15</span><span class="p">));</span>

<span class="k">for</span> <span class="n">num</span> <span class="k">in</span> <span class="n">numbers</span> <span class="p">{</span>
    <span class="nd">assert_eq!</span><span class="p">(</span><span class="n">tree</span><span class="nf">.find</span><span class="p">(</span><span class="o">&amp;</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="n">num</span><span class="p">)),</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">tree</span><span class="nf">.find</span><span class="p">(</span><span class="o">&amp;</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">47</span><span class="p">)),</span> <span class="kc">true</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">tree</span><span class="nf">.find</span><span class="p">(</span><span class="o">&amp;</span><span class="nf">CloneTracker</span><span class="p">(</span><span class="mi">15</span><span class="p">)),</span> <span class="kc">true</span><span class="p">);</span>
</code></pre></div></div>

<p>During the clone call, only the root node is cloned. During the insertion, only the nodes that have been modified are cloned. This can be confirmed by commenting out the relevant sections of code. The rest of the data is shared between the old version and the new version.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Data structures that involve <code class="language-plaintext highlighter-rouge">Box</code> can be converted easily into persistent versions by replacing <code class="language-plaintext highlighter-rouge">Box</code> with <code class="language-plaintext highlighter-rouge">Rc</code>. These structures easily keep track of their previous state without much overhead. In Rust, this means that the structures have a minimal cost when performing a clone operation, and the clone is performed incrementally as the structure is modified. The performance is greater and the memory usage is smaller for persistent structures than their traditional counterparts if clones are expected often.</p>

<hr />

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="Functional programming" /><category term="data structures" /><category term="Rust" /><category term="Programming" /><summary type="html"><![CDATA[Summary]]></summary></entry><entry><title type="html">Shared mutability in Rust Part 2: Acyclic graphs</title><link href="/notepad/notes/2019/09/17/shared_mutability_part_2.html" rel="alternate" type="text/html" title="Shared mutability in Rust Part 2: Acyclic graphs" /><published>2019-09-17T00:00:00+00:00</published><updated>2019-09-17T00:00:00+00:00</updated><id>/notepad/notes/2019/09/17/shared_mutability_part_2</id><content type="html" xml:base="/notepad/notes/2019/09/17/shared_mutability_part_2.html"><![CDATA[<h3 id="summary">Summary</h3>

<ul>
  <li>Child entities which are both mutable and shared can make any, or all of their parents invalid.</li>
  <li>In freeform shared mutability, we cannot cache any calculation that depends on a shared mutable entity.</li>
  <li>If we limit the scope of sharing to code we trust not to invalidate our cache, then we can cache results as much as we like.</li>
  <li>Limiting the scope of sharing implies that we have some kind of container entity: an Arena.</li>
</ul>

<h2 id="interfaces-encapsulation-and-references">Interfaces, encapsulation and references.</h2>

<p>First of all a disclaimer. I’m going to use the terms such as “interface” and “encapsulation”, and I’m going to define them a little bit differently to normal. It may be a bit strange, but hopefully it will make sense.</p>

<p>Instead of writing some code and trying to fix it, let’s try creating some good code first try. I won’t guarantee that it’s performant, but I’ll settle for (mostly) correct. To do that, we have to somehow prove that our code works. Generally speaking, we start off logical derivation with some definitions.</p>

<p>We imagine an entity <code class="language-plaintext highlighter-rouge">A</code> which is part of your program. <code class="language-plaintext highlighter-rouge">A</code> holds some data, which can either be in a valid state or invalid. If <code class="language-plaintext highlighter-rouge">A</code> ever manages to get into an invalid state and stay there, then we say that our program is broken. Sometimes we need to break <code class="language-plaintext highlighter-rouge">A</code> temporarily when we are transitioning from two valid states. To ensure that <code class="language-plaintext highlighter-rouge">A</code> doesn’t stay broken, we draw a box around it. Code inside the box can break <code class="language-plaintext highlighter-rouge">A</code> and code outside the box can’t. <code class="language-plaintext highlighter-rouge">A</code> is always valid outside the box. The barrier between the two areas, we’ll call the <strong>interface</strong>. To make it easy to understand, I’ll call the area inside the box the <strong>danger zone</strong> and code outside the box the <strong>safe zone</strong>.</p>

<p><img src="/notepad/img/2019-09-17/20190903_084059.jpg" alt="Untitled" /></p>

<p>Now I won’t discuss how to construct an interface, or what it should look like. It’s going to be different for every language. Safe to say that we can run any code we like in the safe zone and it will not break <code class="language-plaintext highlighter-rouge">A</code>, because that’s what we defined the interface to be.</p>

<p>Code from the safe zone can call code in the danger zone, but it must go through the interface. When the code from the danger zone returns, <code class="language-plaintext highlighter-rouge">A</code> must be valid. It must be valid because that’s how we defined our interface. In between, <code class="language-plaintext highlighter-rouge">A</code> could be made invalid temporarily, as long as when we return to the safe zone, we have a valid <code class="language-plaintext highlighter-rouge">A</code>.</p>

<p><img src="/notepad/img/2019-09-17/20190903_092427.jpg" alt="Untitled" /></p>

<p>A function that we can call from the safe zone interface but exists inside the danger zone, we will call a <em>public function</em>. A public function is allowed to assume that the entity is valid when it starts, and has a responsibility to ensure that the entity is valid when it exits.</p>

<p>So now we have some idea of what an interface is. Let’s talk about <strong>encapsulation</strong>. Let’s say that we want to make the danger zone as small as possible so that the amount of code that can break <code class="language-plaintext highlighter-rouge">A</code> is minimised. I’ll define <strong>encapsulation</strong> as an attempt to make the danger zone as small as reasonably possible.</p>

<p>If the danger zone extends out forever and encompasses our entire program, then we always have to worry if we might break <code class="language-plaintext highlighter-rouge">A</code> by accident when we write code. We don’t want to worry about breaking every other part of our program when we modify any other part. That’s too much thinking. If we make the danger zone small, then we only have to worry about breaking <code class="language-plaintext highlighter-rouge">A</code> when we’re inside it.</p>

<p>We’ll also introduce one more definition. The definition of a <strong>reference</strong>. Let’s say we have two entities, a parent and a child. If you can break the parent by modifying the child or making it invalid, we say that the parent holds a reference to the child. We’ll define a reference this way whether or not an entity holds a physical pointer to the other entity. I might get slack and say that an entity “knows about” another.</p>

<p>In this article we will only deal with the case where there are no circular references.</p>

<h2 id="shared-mutability">Shared mutability</h2>

<p>Consider that we have two entities in out program <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code>. <code class="language-plaintext highlighter-rouge">A</code> knows about <code class="language-plaintext highlighter-rouge">B</code>, but <code class="language-plaintext highlighter-rouge">B</code> doesn’t know about <code class="language-plaintext highlighter-rouge">A</code>. We’ll draw this like so:</p>

<p><img src="/notepad/img/2019-09-17/20190903_093756.jpg" alt="Untitled" /></p>

<p><code class="language-plaintext highlighter-rouge">B</code> doesn’t know about <code class="language-plaintext highlighter-rouge">A</code>, so the interface for <code class="language-plaintext highlighter-rouge">B</code> could just be around <code class="language-plaintext highlighter-rouge">B</code>. The opposite is not true. <code class="language-plaintext highlighter-rouge">A</code> knows about <code class="language-plaintext highlighter-rouge">B</code> and could be made invalid if <code class="language-plaintext highlighter-rouge">B</code> were invalid. To encapsulate <code class="language-plaintext highlighter-rouge">A</code>, we must surround the danger zone for <code class="language-plaintext highlighter-rouge">B</code> as well.</p>

<p><img src="/notepad/img/2019-09-17/20190903_094207.jpg" alt="Untitled" /></p>

<p>We can now figure out the correct size for the interface for any entity using the following rules.</p>

<ul>
  <li>The danger zone for <code class="language-plaintext highlighter-rouge">A</code> contains <code class="language-plaintext highlighter-rouge">A</code> itself.</li>
  <li>If an entity <code class="language-plaintext highlighter-rouge">A</code> knows about another entity <code class="language-plaintext highlighter-rouge">B</code>, then the danger zone for <code class="language-plaintext highlighter-rouge">A</code> includes the danger zone for <code class="language-plaintext highlighter-rouge">B</code>.</li>
  <li>If an entity <code class="language-plaintext highlighter-rouge">A</code> does not know about another entity <code class="language-plaintext highlighter-rouge">B</code>, then <code class="language-plaintext highlighter-rouge">B</code> is outside the danger zone for <code class="language-plaintext highlighter-rouge">A</code>, because <code class="language-plaintext highlighter-rouge">B</code> can’t make <code class="language-plaintext highlighter-rouge">A</code> invalid by our definition of a reference.</li>
</ul>

<p>We have a problem with shared mutability. Consider two objects <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> which do not know about each other, but have a shared child called <code class="language-plaintext highlighter-rouge">C</code> that they both know about. The danger zone for <code class="language-plaintext highlighter-rouge">A</code> encompasses <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">C</code>, and the danger zone for <code class="language-plaintext highlighter-rouge">B</code> encompasses <code class="language-plaintext highlighter-rouge">B</code> and <code class="language-plaintext highlighter-rouge">C</code>. Because <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> don’t know about each other, they don’t belong in each other’s danger zones. If it were possible that <code class="language-plaintext highlighter-rouge">B</code> could cause <code class="language-plaintext highlighter-rouge">A</code> to break, then it would imply that <code class="language-plaintext highlighter-rouge">A</code> knows about <code class="language-plaintext highlighter-rouge">B</code>: a contradiction.</p>

<p><img src="/notepad/img/2019-09-17/20190903_095008.jpg" alt="Untitled" /></p>

<p>Now we can see this issue. The interfaces of <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> cross over. In order to modify <code class="language-plaintext highlighter-rouge">C</code> we must go into both the danger zones for <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> first. Potentially we have a situation where <code class="language-plaintext highlighter-rouge">A</code> could modify <code class="language-plaintext highlighter-rouge">C</code> and make <code class="language-plaintext highlighter-rouge">B</code> invalid, or vice versa. This problem only becomes worse if we have more parents. We will discuss two ways to manage this issue.</p>

<h2 id="example-problem">Example problem.</h2>

<p>For the purposes of this article we will look at a series of entities called <strong>tasks</strong>. Each <strong>task</strong> has a <strong>duration</strong> (in days) and a <strong>name</strong>. A <strong>task</strong> can only be completed after all of its dependencies have been completed. A task with no dependencies starts straight away. For this article, We’ll use the following example:</p>

<p><img src="/notepad/img/2019-09-17/20190903_150425.jpg" alt="Untitled" /></p>

<h2 id="solution-1-freeform-shared-mutability">Solution 1: Freeform shared mutability.</h2>

<p>In safe rust, we can share ownership using <code class="language-plaintext highlighter-rouge">Rc</code>. This means we don’t have to worry about how long something is going to live for; it will automatically be dropped when nothing else references it. To have shared mutability in a single threaded context, we can use <code class="language-plaintext highlighter-rouge">RefCell</code>. If we combine the two we can generate arbitrary graph like structures which have shared mutability. I mention this implementation for completeness, and advise that with almost certainty a <code class="language-plaintext highlighter-rouge">RefCell</code> inside of an <code class="language-plaintext highlighter-rouge">Rc</code> is an anti-pattern.</p>

<p>We begin by defining our data type. It has a name, duration, and a list of dependencies. We wrap this all up inside our <code class="language-plaintext highlighter-rouge">Rc</code>, <code class="language-plaintext highlighter-rouge">RefCell</code> sandwich:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">cell</span><span class="p">::</span><span class="n">RefCell</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">rc</span><span class="p">::</span><span class="nb">Rc</span><span class="p">;</span>

<span class="nd">#[derive(Clone,</span> <span class="nd">Eq,</span> <span class="nd">PartialEq,</span> <span class="nd">Debug,</span> <span class="nd">PartialOrd,</span> <span class="nd">Ord)]</span>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">InnerTask</span> <span class="p">{</span>
    <span class="n">name</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">'static</span> <span class="nb">str</span><span class="p">,</span>
    <span class="n">duration</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="n">dependencies</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Task</span><span class="o">&gt;</span><span class="p">,</span>
<span class="p">}</span>
<span class="nd">#[derive(Clone,</span> <span class="nd">Eq,</span> <span class="nd">PartialEq,</span> <span class="nd">Debug,</span> <span class="nd">PartialOrd,</span> <span class="nd">Ord)]</span>
<span class="k">struct</span> <span class="nf">Task</span><span class="p">(</span><span class="nb">Rc</span><span class="o">&lt;</span><span class="n">RefCell</span><span class="o">&lt;</span><span class="n">InnerTask</span><span class="o">&gt;&gt;</span><span class="p">);</span>
</code></pre></div></div>

<p>We have seen from the <a href="https://medium.com/swlh/shared-mutability-in-rust-part-1-of-3-21dc9803c623">previous part</a> that we cannot have shared mutability and this idea of “internal consistency” simultaneously. This means that we are forced to calculate, on the fly any result that depends on children. We solve the danger zone problem by asserting that the parent isn’t allowed to <em>care</em> what the child’s value is, only that it <em>has</em> a value. This is important if we want to use a <code class="language-plaintext highlighter-rouge">RefCell</code> based implementation:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Task</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span> <span class="p">(</span><span class="n">name</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">'static</span> <span class="nb">str</span><span class="p">,</span> <span class="n">duration</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span> <span class="n">dependencies</span><span class="p">:</span> <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Task</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nf">Task</span><span class="p">(</span><span class="nn">Rc</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="nn">RefCell</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">InnerTask</span> <span class="p">{</span>
            <span class="n">name</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
            <span class="n">duration</span><span class="p">:</span> <span class="n">duration</span><span class="p">,</span>
            <span class="n">dependencies</span><span class="p">:</span> <span class="n">dependencies</span><span class="p">,</span>
        <span class="p">})))</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">set_duration</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">duration</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="na">.0</span><span class="nf">.borrow_mut</span><span class="p">()</span><span class="py">.duration</span> <span class="o">=</span> <span class="n">duration</span><span class="p">;</span>
    <span class="p">}</span> 
    <span class="k">fn</span> <span class="nf">start_time</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="na">.0</span><span class="nf">.borrow</span><span class="p">()</span><span class="py">.dependencies</span><span class="p">)</span>
            <span class="nf">.into_iter</span><span class="p">()</span>
            <span class="nf">.map</span><span class="p">(|</span><span class="n">dependency</span><span class="p">|</span> <span class="n">dependency</span><span class="nf">.end_time</span><span class="p">())</span>
            <span class="nf">.max</span><span class="p">()</span>
            <span class="nf">.unwrap_or</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">end_time</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="nf">.start_time</span><span class="p">()</span> <span class="o">+</span> <span class="k">self</span><span class="na">.0</span><span class="nf">.borrow</span><span class="p">()</span><span class="py">.duration</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The start time of a <code class="language-plaintext highlighter-rouge">Task</code> is the maximum of all of its children’s end times. The end time is just the start time plus the duration of the task.</p>

<p>As you can see, <code class="language-plaintext highlighter-rouge">start_time</code> accesses every dependency in turn to get a result. In our small example this will be trivial, but in more complicated graphs, we could perform an exponentially increasing number of calls. We are not allowed to cache the results, because some other part of our program could modify one of the other tasks, and make the start and end times invalid.</p>

<p>This is a simple implementation. I provide no methods to modify dependencies; with a <code class="language-plaintext highlighter-rouge">RefCell</code> inside an <code class="language-plaintext highlighter-rouge">Rc</code>, we have to be careful about creating circular references. We limit ourselves to only creating a <code class="language-plaintext highlighter-rouge">Task</code> using older <code class="language-plaintext highlighter-rouge">Task</code>s.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">lay_foundation</span> <span class="o">=</span> 
        <span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Lay Foundation"</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="nd">vec!</span><span class="p">[]);</span>
    <span class="k">let</span> <span class="n">build_walls</span> <span class="o">=</span> 
        <span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Build Walls"</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="nd">vec!</span><span class="p">[</span><span class="n">lay_foundation</span><span class="nf">.clone</span><span class="p">()]);</span>
    <span class="k">let</span> <span class="n">build_roof</span> <span class="o">=</span> 
        <span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Build Roof"</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="nd">vec!</span><span class="p">[</span><span class="n">build_walls</span><span class="nf">.clone</span><span class="p">()]);</span>
    <span class="k">let</span> <span class="n">paint_walls</span> <span class="o">=</span> 
        <span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Paint Walls"</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="nd">vec!</span><span class="p">[</span><span class="n">build_walls</span><span class="nf">.clone</span><span class="p">()]);</span>
    <span class="k">let</span> <span class="n">furnish_house</span> <span class="o">=</span> 
        <span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Furnish House"</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="nd">vec!</span><span class="p">[</span><span class="n">build_roof</span><span class="nf">.clone</span><span class="p">(),</span> <span class="n">paint_walls</span><span class="nf">.clone</span><span class="p">()]);</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Days require to finish house: {}"</span><span class="p">,</span> <span class="n">furnish_house</span><span class="nf">.end_time</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This works, but I don’t recommend it. It is up to the programmer to guarantee that we never cache the results of any of our calculations, however tempting it may be. In addition, this is asymptotically slow. The start and end time for <code class="language-plaintext highlighter-rouge">lay_foundation</code> has to be calculated multiple times. In more complicated examples, it may have to be calculated an exponential number of times.</p>

<h2 id="solution-2-an-arena">Solution 2: An Arena.</h2>

<p>The previous example has shared mutability, but no “<a href="https://medium.com/swlh/shared-mutability-in-rust-part-1-of-3-21dc9803c623">internal consistency</a>”. However, if we limit the spread of mutable references to entities that we trust not to break our structure, we can cache the results as much as we like. All the nodes themselves must be “trusted” since they could have a reference to any other node, and we can only give mutable references to “trusted” entities.</p>

<p>In order to create a place where only trusted entities can modify our nodes, we have to create an interface. Inside the interface, we have trusted code, and outside, we have everything else. We call the entity that holds the interface <code class="language-plaintext highlighter-rouge">P</code>.</p>

<p>We don’t allow <code class="language-plaintext highlighter-rouge">P</code> to hand out mutable references to individual nodes to the safe zone, because outside of <code class="language-plaintext highlighter-rouge">P</code> isn’t trusted not to break our structure by our definition of <code class="language-plaintext highlighter-rouge">P</code>. <code class="language-plaintext highlighter-rouge">P</code> must therefore have exclusive write access to all of the individual nodes. Considering that <code class="language-plaintext highlighter-rouge">P</code> is an entity with an interface, that has exclusive write access to its individual nodes, we can say <code class="language-plaintext highlighter-rouge">P</code> is an arena.</p>

<p>You might note that I don’t say that <code class="language-plaintext highlighter-rouge">P</code> an object. <code class="language-plaintext highlighter-rouge">P</code> could be anything. It could be a <code class="language-plaintext highlighter-rouge">struct</code>, and <code class="language-plaintext highlighter-rouge">enum</code>, a combination of objects or any other entity that could be defined. I only state that whatever <code class="language-plaintext highlighter-rouge">P</code> is, it happens to have two properties: all code inside <code class="language-plaintext highlighter-rouge">P</code> is trusted not to break it, and it has exclusive mutable access to all of its nodes.</p>

<p>Like the previous article, in order to solve our shared mutability problem, we get rid of the sharing part, and say that all mutable access is through public functions for <code class="language-plaintext highlighter-rouge">P</code>.</p>

<p>Note that in order to cache the results of calculations we <em>must</em> have an interface and its associated entity <code class="language-plaintext highlighter-rouge">P</code>, and we know that <code class="language-plaintext highlighter-rouge">P</code> <em>must</em> have exclusive write access to its members. An arena is not the “best” way of solving the problem of mutability with internal consistency, it’s the <em>only</em> way. Einstein said to make things “as simple as possible, but no simpler”. Although an arena may not be simple, it is the simplest way to write our code whilst remaining correct.</p>

<p>To implement this, we can create a <code class="language-plaintext highlighter-rouge">Graph</code> data structure which is just a collection of nodes with unique id’s. A <code class="language-plaintext highlighter-rouge">GraphNode</code> contains some data, and a set of incoming and outgoing edges.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">collections</span><span class="p">::{</span><span class="n">HashMap</span><span class="p">,</span> <span class="n">HashSet</span><span class="p">};</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">hash</span><span class="p">::</span><span class="n">Hash</span><span class="p">;</span>

<span class="k">use</span> <span class="nn">uuid</span><span class="p">::</span><span class="n">Uuid</span><span class="p">;</span>

<span class="nd">#[derive(Debug,</span> <span class="nd">Clone,</span> <span class="nd">Eq,</span> <span class="nd">PartialEq)]</span>
<span class="k">struct</span> <span class="n">GraphNode</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">data</span><span class="p">:</span> <span class="n">T</span><span class="p">,</span>
    <span class="n">incoming</span><span class="p">:</span> <span class="n">HashSet</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="n">outgoing</span><span class="p">:</span> <span class="n">HashSet</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="o">&gt;</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">GraphNode</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span> <span class="p">(</span><span class="n">data</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="n">GraphNode</span> <span class="p">{</span>
            <span class="n">data</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span>
            <span class="n">incoming</span><span class="p">:</span> <span class="nn">HashSet</span><span class="p">::</span><span class="nf">new</span><span class="p">(),</span>
            <span class="n">outgoing</span><span class="p">:</span> <span class="nn">HashSet</span><span class="p">::</span><span class="nf">new</span><span class="p">(),</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nd">#[derive(Debug,</span> <span class="nd">Clone)]</span>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">Graph</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="nb">Eq</span> <span class="o">+</span> <span class="n">Hash</span><span class="o">&gt;</span> <span class="p">(</span>
    <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="p">,</span> <span class="n">GraphNode</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span>
<span class="p">);</span>
</code></pre></div></div>

<p>This is a very simple implementation of a graph. We have some basic functionality that I will brush over for the most part revolving around adding, deleting and querying nodes. There are more efficient implementations, but they are not relevant to this article:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="nb">Eq</span> <span class="o">+</span> <span class="n">Hash</span><span class="o">&gt;</span> <span class="n">Graph</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">new</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="nf">Graph</span><span class="p">(</span><span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">())</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">add_edge</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">start</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">,</span> <span class="n">end</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="na">.0</span><span class="nf">.get_mut</span><span class="p">(</span><span class="n">start</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">node</span><span class="p">|</span> <span class="p">{</span>
            <span class="n">node</span><span class="py">.outgoing</span><span class="nf">.insert</span><span class="p">(</span><span class="o">*</span><span class="n">end</span><span class="p">);</span>
        <span class="p">});</span>
        <span class="k">self</span><span class="na">.0</span><span class="nf">.get_mut</span><span class="p">(</span><span class="n">end</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">node</span><span class="p">|</span> <span class="p">{</span>
            <span class="n">node</span><span class="py">.incoming</span><span class="nf">.insert</span><span class="p">(</span><span class="o">*</span><span class="n">start</span><span class="p">);</span>
        <span class="p">});</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">remove_edge</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">start</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">,</span> <span class="n">end</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="na">.0</span><span class="nf">.get_mut</span><span class="p">(</span><span class="n">start</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">node</span><span class="p">|</span> <span class="p">{</span>
            <span class="n">node</span><span class="py">.outgoing</span><span class="nf">.remove</span><span class="p">(</span><span class="n">end</span><span class="p">);</span>
        <span class="p">});</span>
        <span class="k">self</span><span class="na">.0</span><span class="nf">.get_mut</span><span class="p">(</span><span class="n">end</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">node</span><span class="p">|</span> <span class="p">{</span>
            <span class="n">node</span><span class="py">.incoming</span><span class="nf">.remove</span><span class="p">(</span><span class="n">start</span><span class="p">);</span>
        <span class="p">});</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">remove_node</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">node_id</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">T</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">node</span> <span class="o">=</span> <span class="k">self</span><span class="na">.0</span><span class="nf">.remove</span><span class="p">(</span><span class="n">node_id</span><span class="p">)</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"remove_node: invalid key"</span><span class="p">);</span>
        <span class="k">for</span> <span class="n">start</span> <span class="k">in</span> <span class="n">node</span><span class="py">.incoming</span><span class="nf">.iter</span><span class="p">()</span> <span class="p">{</span>
            <span class="k">self</span><span class="na">.0</span><span class="nf">.get_mut</span><span class="p">(</span><span class="n">start</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">start_node</span><span class="p">|</span> <span class="p">{</span>
                <span class="n">start_node</span><span class="py">.outgoing</span><span class="nf">.remove</span><span class="p">(</span><span class="n">node_id</span><span class="p">);</span>
            <span class="p">});</span>
        <span class="p">}</span>
        <span class="k">for</span> <span class="n">end</span> <span class="k">in</span> <span class="n">node</span><span class="py">.outgoing</span><span class="nf">.iter</span><span class="p">()</span> <span class="p">{</span>
            <span class="k">self</span><span class="na">.0</span><span class="nf">.get_mut</span><span class="p">(</span><span class="n">end</span><span class="p">)</span><span class="nf">.map</span><span class="p">(|</span><span class="n">end_node</span><span class="p">|</span> <span class="p">{</span>
                <span class="n">end_node</span><span class="py">.incoming</span><span class="nf">.remove</span><span class="p">(</span><span class="n">node_id</span><span class="p">);</span>
            <span class="p">});</span>
        <span class="p">}</span>
        <span class="n">node</span><span class="py">.data</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">add_node</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">node</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">Uuid</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">key</span> <span class="o">=</span> <span class="nn">Uuid</span><span class="p">::</span><span class="nf">new_v4</span><span class="p">();</span>
        <span class="k">self</span><span class="na">.0</span><span class="nf">.insert</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="nn">GraphNode</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="n">node</span><span class="p">));</span>
        <span class="n">key</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">get</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="o">&amp;</span><span class="n">T</span> <span class="p">{</span>
        <span class="o">&amp;</span><span class="k">self</span><span class="na">.0</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"get: invalid key."</span><span class="p">)</span><span class="py">.data</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">get_outgoing</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="o">&amp;</span><span class="n">HashSet</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="o">&amp;</span><span class="k">self</span><span class="na">.0</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"get_outgoing: invalid key."</span><span class="p">)</span><span class="py">.outgoing</span>
    <span class="p">}</span>
    <span class="k">pub</span> <span class="k">fn</span> <span class="nf">get_incoming</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="o">&amp;</span><span class="n">HashSet</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="o">&amp;</span><span class="k">self</span><span class="na">.0</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="nf">.expect</span><span class="p">(</span><span class="s">"get_incoming: invalid key."</span><span class="p">)</span><span class="py">.incoming</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We implement our actual <code class="language-plaintext highlighter-rouge">Task</code> struct which contains <code class="language-plaintext highlighter-rouge">name</code> and <code class="language-plaintext highlighter-rouge">duration</code> fields and nothing else. One of the advantages of using an arena is that we can separate the data that represents relations between nodes from the nodes themselves. This means that a node can therefore uphold its own invariants that don’t depend on it being part of a larger structure:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">#[derive(Clone,</span> <span class="nd">Eq,</span> <span class="nd">PartialEq,</span> <span class="nd">Hash,</span> <span class="nd">Debug,</span> <span class="nd">PartialOrd,</span> <span class="nd">Ord)]</span>
<span class="k">pub</span> <span class="k">struct</span> <span class="n">Task</span> <span class="p">{</span>
    <span class="n">name</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">'static</span> <span class="nb">str</span><span class="p">,</span>
    <span class="n">duration</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">impl</span> <span class="n">Task</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span> <span class="p">(</span><span class="n">name</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">'static</span> <span class="nb">str</span><span class="p">,</span> <span class="n">duration</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="n">Task</span> <span class="p">{</span>
            <span class="n">name</span><span class="p">:</span> <span class="n">name</span><span class="p">,</span>
            <span class="n">duration</span><span class="p">:</span> <span class="n">duration</span><span class="p">,</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Like the previous article, we create a “view” of the graph, that freezes it temporarily. This allows us to cache the results of calculations as much as we like. When we modify any of the nodes, or the structure of the graph, we have to discard the cache because it’s no longer valid. The view struct contains a cache of start times and end times:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">GraphView</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">graph</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'a</span> <span class="n">Graph</span><span class="o">&lt;</span><span class="n">Task</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="n">start_times</span><span class="p">:</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="p">,</span> <span class="nb">u32</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="n">end_times</span><span class="p">:</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="p">,</span> <span class="nb">u32</span><span class="o">&gt;</span><span class="p">,</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If we wanted to cache the results we can use a little bit of boilerplate and write something like the following:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span> <span class="n">GraphView</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span> <span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'a</span> <span class="n">Graph</span><span class="o">&lt;</span><span class="n">Task</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="n">GraphView</span> <span class="p">{</span>
            <span class="n">graph</span><span class="p">:</span> <span class="n">graph</span><span class="p">,</span>
            <span class="n">start_times</span><span class="p">:</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">(),</span>
            <span class="n">end_times</span><span class="p">:</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">(),</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">end_time</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="c1">// Boilerplate</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.end_times</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">result</span><span class="nf">.clone</span><span class="p">();</span>
        <span class="p">}</span>
        
        <span class="c1">// Actual query</span>
        <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="k">self</span><span class="py">.graph</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="py">.duration</span> <span class="o">+</span> <span class="k">self</span><span class="nf">.start_time</span><span class="p">(</span><span class="n">key</span><span class="p">);</span>

        <span class="c1">// Boilerplate</span>
        <span class="k">self</span><span class="py">.end_times</span><span class="nf">.insert</span><span class="p">(</span><span class="n">key</span><span class="nf">.clone</span><span class="p">(),</span> <span class="n">result</span><span class="p">);</span>
        <span class="n">result</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">start_time</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="c1">// Boilerplate</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.start_times</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">result</span><span class="nf">.clone</span><span class="p">();</span>
        <span class="p">}</span>

        <span class="c1">// Actual query.</span>
        <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="k">self</span><span class="py">.graph</span><span class="nf">.get_incoming</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
            <span class="nf">.into_iter</span><span class="p">()</span>
            <span class="nf">.map</span><span class="p">(|</span><span class="n">key_out</span><span class="p">|</span> <span class="k">self</span><span class="nf">.end_time</span><span class="p">(</span><span class="n">key_out</span><span class="p">))</span>
            <span class="nf">.max</span><span class="p">()</span>
            <span class="nf">.unwrap_or</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>

        <span class="c1">// Boilerplate</span>
        <span class="k">self</span><span class="py">.start_times</span><span class="nf">.insert</span><span class="p">(</span><span class="n">key</span><span class="nf">.clone</span><span class="p">(),</span> <span class="n">result</span><span class="p">);</span>
        <span class="n">result</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The boilerplate simply checks if we have already calculated the value. If we have, we just return the value, otherwise, we calculate the value, and insert the result into the <code class="language-plaintext highlighter-rouge">HashMap</code>. This is actually just depth first search in disguise.</p>

<p>This allows us to write any kind of graph traversing query in a declarative manner. We can write what we want the result to be based on other nodes in the graph and not have to worry about the actual execution of the query.</p>

<p>Mind you that this implementation is asymptotically efficient for both read heavy and write heavy use cases. In read heavy implementations, we cache the results of intermediary calculations, and lazily perform the minimal number of steps required to produce a result. In write heavy loads, we discard the cache entirely, and only have to update the essential data in the individual nodes themselves, and nothing else.</p>

<p>We can use the graph like the following:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">graph</span> <span class="o">=</span> <span class="nn">Graph</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

    <span class="k">let</span> <span class="n">lay_foundation</span> <span class="o">=</span> <span class="n">graph</span><span class="nf">.add_node</span><span class="p">(</span><span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Lay foundation"</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span>
    <span class="k">let</span> <span class="n">build_walls</span> <span class="o">=</span> <span class="n">graph</span><span class="nf">.add_node</span><span class="p">(</span><span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Build walls"</span><span class="p">,</span> <span class="mi">2</span><span class="p">));</span>
    <span class="n">graph</span><span class="nf">.add_edge</span><span class="p">(</span><span class="o">&amp;</span><span class="n">lay_foundation</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">build_walls</span><span class="p">);</span>

    <span class="k">let</span> <span class="n">build_roof</span> <span class="o">=</span> <span class="n">graph</span><span class="nf">.add_node</span><span class="p">(</span><span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Build roof"</span><span class="p">,</span> <span class="mi">4</span><span class="p">));</span>
    <span class="n">graph</span><span class="nf">.add_edge</span><span class="p">(</span><span class="o">&amp;</span><span class="n">build_walls</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">build_roof</span><span class="p">);</span>

    <span class="k">let</span> <span class="n">paint_walls</span> <span class="o">=</span> <span class="n">graph</span><span class="nf">.add_node</span><span class="p">(</span><span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Paint walls"</span><span class="p">,</span> <span class="mi">8</span><span class="p">));</span>
    <span class="n">graph</span><span class="nf">.add_edge</span><span class="p">(</span><span class="o">&amp;</span><span class="n">build_walls</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">paint_walls</span><span class="p">);</span>

    <span class="k">let</span> <span class="n">furnish_house</span> <span class="o">=</span> <span class="n">graph</span><span class="nf">.add_node</span><span class="p">(</span><span class="nn">Task</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Furnish house"</span><span class="p">,</span> <span class="mi">16</span><span class="p">));</span>
    <span class="n">graph</span><span class="nf">.add_edge</span><span class="p">(</span><span class="o">&amp;</span><span class="n">paint_walls</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">furnish_house</span><span class="p">);</span>

    <span class="k">let</span> <span class="k">mut</span> <span class="n">view</span> <span class="o">=</span> <span class="nn">GraphView</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">graph</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Days require to finish house: {:?}"</span><span class="p">,</span> <span class="n">view</span><span class="nf">.end_time</span><span class="p">(</span><span class="o">&amp;</span><span class="n">furnish_house</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This solution is verbose, but has strong guarantees. We can extend this structure in multiple ways. If we need nodes of different types, we can have one collection of nodes for each type inside our <code class="language-plaintext highlighter-rouge">Graph</code> structure. If we need different kinds of connections between nodes, we can modify our <code class="language-plaintext highlighter-rouge">GraphNode</code> structure to have more fields than just <code class="language-plaintext highlighter-rouge">incoming</code> and <code class="language-plaintext highlighter-rouge">outgoing</code>. We can even detect cycles if we modify the view code slightly:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">GraphView2</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">graph</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'a</span> <span class="n">Graph</span><span class="o">&lt;</span><span class="n">Task</span><span class="o">&gt;</span><span class="p">,</span>
    <span class="c1">// Store an Option rather than the value itself.</span>
    <span class="c1">// None means a circular reference</span>
    <span class="n">start_times</span><span class="p">:</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="p">,</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;&gt;</span><span class="p">,</span>
    <span class="n">end_times</span><span class="p">:</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">Uuid</span><span class="p">,</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;&gt;</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span> <span class="n">GraphView2</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span> <span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'a</span> <span class="n">Graph</span><span class="o">&lt;</span><span class="n">Task</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="n">GraphView2</span> <span class="p">{</span>
            <span class="n">graph</span><span class="p">:</span> <span class="n">graph</span><span class="p">,</span>
            <span class="n">start_times</span><span class="p">:</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">(),</span>
            <span class="n">end_times</span><span class="p">:</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">(),</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">end_time</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.end_times</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">result</span><span class="nf">.clone</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="c1">// We assume that a node is part of a circular reference</span>
        <span class="c1">// until proved otherwise.</span>
        <span class="k">self</span><span class="py">.end_times</span><span class="nf">.insert</span><span class="p">(</span><span class="n">key</span><span class="nf">.clone</span><span class="p">(),</span> <span class="nb">None</span><span class="p">);</span>
        
        <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="k">self</span><span class="nf">.start_time</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
            <span class="nf">.map</span><span class="p">(|</span><span class="n">time</span><span class="p">|</span> <span class="n">time</span> <span class="o">+</span> <span class="k">self</span><span class="py">.graph</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="py">.duration</span><span class="p">);</span>

        <span class="k">self</span><span class="py">.end_times</span><span class="nf">.insert</span><span class="p">(</span><span class="n">key</span><span class="nf">.clone</span><span class="p">(),</span> <span class="n">result</span><span class="p">);</span>
        <span class="n">result</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">start_time</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Uuid</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">u32</span><span class="o">&gt;</span> <span class="p">{</span>
        <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">result</span><span class="p">)</span> <span class="o">=</span> <span class="k">self</span><span class="py">.start_times</span><span class="nf">.get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="n">result</span><span class="nf">.clone</span><span class="p">();</span>
        <span class="p">}</span>
        <span class="k">self</span><span class="py">.start_times</span><span class="nf">.insert</span><span class="p">(</span><span class="n">key</span><span class="nf">.clone</span><span class="p">(),</span> <span class="nb">None</span><span class="p">);</span>

        <span class="k">let</span> <span class="n">result</span> <span class="o">=</span> <span class="k">self</span><span class="py">.graph</span><span class="nf">.get_incoming</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
            <span class="nf">.into_iter</span><span class="p">()</span>
            <span class="nf">.map</span><span class="p">(|</span><span class="n">key_out</span><span class="p">|</span> <span class="k">self</span><span class="nf">.end_time</span><span class="p">(</span><span class="n">key_out</span><span class="p">))</span>
            <span class="nf">.fold</span><span class="p">(</span><span class="nf">Some</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="p">|</span><span class="n">max_time</span><span class="p">,</span> <span class="n">end_time</span><span class="p">|</span> <span class="nf">Some</span><span class="p">(</span><span class="n">max_time</span><span class="o">?</span><span class="nf">.max</span><span class="p">(</span><span class="n">end_time</span><span class="o">?</span><span class="p">)));</span>

        <span class="k">self</span><span class="py">.start_times</span><span class="nf">.insert</span><span class="p">(</span><span class="n">key</span><span class="nf">.clone</span><span class="p">(),</span> <span class="n">result</span><span class="p">);</span>
        <span class="n">result</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>In this example <code class="language-plaintext highlighter-rouge">start_time</code> and <code class="language-plaintext highlighter-rouge">end_time</code> return <code class="language-plaintext highlighter-rouge">None</code> if the nodes are part of a circular reference, so we can detect them and handle them accordingly.</p>

<h2 id="conclusion">Conclusion</h2>

<p>I present two ways to construct code that has shared mutability in some kind of arbitrary acyclic graph structure in Rust. On one hand we have a freeform structure which involves <code class="language-plaintext highlighter-rouge">Rc</code> and <code class="language-plaintext highlighter-rouge">RefCell</code>. The disadvantage of this kind of structure is that we cannot cache results that depend on other entities. In addition, we have to be careful not to introduce reference cycles. It appears simple but has some complicated caveats.</p>

<p>On the other hand, we can create some kind of arena. I provide an example implementation: a graph. I can separate the data that represents relations between nodes from the data of the nodes themselves. The graph can be temporarily frozen to mutation so we can perform queries. It does not use <code class="language-plaintext highlighter-rouge">RefCell</code>, so it has stronger static guarantees regarding borrowing. It is asymptotically efficient for a variety of use cases. We can write declarative queries and have them efficiently executed. It can also be extended in a variety of manners. It is my opinion that this is the simplest “correct” implementation.</p>

<p>In the next article, I will discuss structures which contain reference cycles.</p>

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="Rust" /><category term="graph" /><category term="acyclic" /><category term="mutability" /><category term="references" /><summary type="html"><![CDATA[Summary]]></summary></entry><entry><title type="html">Shared mutability in rust.</title><link href="/notepad/notes/2019/08/25/shared_mutability.html" rel="alternate" type="text/html" title="Shared mutability in rust." /><published>2019-08-25T00:00:00+00:00</published><updated>2019-08-25T00:00:00+00:00</updated><id>/notepad/notes/2019/08/25/shared_mutability</id><content type="html" xml:base="/notepad/notes/2019/08/25/shared_mutability.html"><![CDATA[<h3 id="summary">Summary</h3>

<ul>
  <li>For the majority of code, shared mutability is usually not required.</li>
  <li>We cannot have sharing, mutability and “internal consistency”. A program that tries to have all three is provably incorrect.</li>
  <li>If we want sharing, and mutability but do not need “internal consistency”, we can use a file, a database handle, a mutex, or any other similar structure.</li>
  <li>If we need mutability, and “internal consistency” but do not need sharing, we can have all modifications go through a common ancestor.</li>
  <li>If we need sharing, and “internal consistency” but not mutability, we can freeze our data, or have persistent data structures.</li>
</ul>

<h3 id="the-problem-with-shared-mutability">The problem with shared mutability.</h3>

<p>Safe Rust provides us with some guarantees: namely safe memory access, no undefined behavior, and no data races. In addition to this, safe Rust makes it difficult (but not impossible) to have memory leaks, mutate structures through immutable references, or create memory cycles.</p>

<p>I’ll start by saying that these things are made difficult to do because they are difficult to reason about. Safe rust introduces some resistance so that programmers are more likely to design their programs in such a way that they are more likely to be correct.</p>

<p>If we ignore IO or interior mutability for a moment, safe Rust has property that whenever you hold an immutable reference to an object, the holder of the reference doesn’t know (or doesn’t care) if other structures also hold a reference to it. If you wanted to, you could clone the data and it would make no difference to the program.</p>

<p>To illustrate this point, let’s draw a diagram where circles are objects, and an arrow means that an object “knows” about the other. We have objects <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> which are regular objects that don’t know about each other. We also have object <code class="language-plaintext highlighter-rouge">C</code> for “Child”. Both <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> know about <code class="language-plaintext highlighter-rouge">C</code>, but not necessarily the other way around. We won’t talk about the case where <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> know about each other, because then we would have a circular reference, which is beyond the scope of this article.</p>

<p><img src="/notepad/img/20190826_1.jpg" alt="Rust programs behave the same if different objects have their own copy of an object if they hold immutable references" /></p>

<p>As long as you don’t try to change the child <code class="language-plaintext highlighter-rouge">C</code>, it doesn’t matter if you had your own copy or not. The program behaves exactly the same way if every object had their own copy of <code class="language-plaintext highlighter-rouge">C</code>, or if they all pointed to the same one.</p>

<p>However, this makes it difficult when you want to write a program with shared mutability. Specifically when you have an object with multiple owners, when one owner changes the data, we want the other owner to be able to see that the data has changed. We now require that the owners have a reference to the same object.</p>

<p><img src="/notepad/img/20190826_2.jpg" alt="Mutable references do not hold this property" /></p>

<p>This presents us with a problem. If we need to ask <code class="language-plaintext highlighter-rouge">B</code> about something that depends on <code class="language-plaintext highlighter-rouge">C</code>, then we have to recalculate it every single time because it could have been changed by <code class="language-plaintext highlighter-rouge">A</code>. As far as <code class="language-plaintext highlighter-rouge">B</code> is concerned, <code class="language-plaintext highlighter-rouge">C</code> could be anything because <code class="language-plaintext highlighter-rouge">B</code> doesn’t know about <code class="language-plaintext highlighter-rouge">A</code>.</p>

<p>If this is your use case, and <code class="language-plaintext highlighter-rouge">C</code> is a database connection, a webpage, a file, a mutex, or some other kind of IO. then you don’t have to continue reading. You will have to refresh the webpage, or perform a new database request, or obtain the mutex lock if you want your data to be up to date (which I will refer to now as “internally consistent” or just “consistent”). If you don’t trust the data to be unmodified between requests you have no choice but to recalculate every time:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">A</span><span class="o">&lt;</span><span class="nv">'c</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">value</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="c1">// we consider the child volatile, so we have to check it every time.</span>
    <span class="n">child</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'c</span> <span class="nn">std</span><span class="p">::</span><span class="nn">cell</span><span class="p">::</span><span class="n">RefCell</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="nv">'c</span><span class="o">&gt;</span> <span class="n">A</span><span class="o">&lt;</span><span class="nv">'c</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="c1">// we need to calculate this every time we query it.</span>
    <span class="k">fn</span> <span class="nf">total</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.value</span> <span class="o">+</span> <span class="k">self</span><span class="py">.child</span><span class="nf">.borrow</span><span class="p">()</span><span class="py">.value</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="n">B</span><span class="o">&lt;</span><span class="nv">'c</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">value</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="n">child</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'c</span> <span class="nn">std</span><span class="p">::</span><span class="nn">cell</span><span class="p">::</span><span class="n">RefCell</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="nv">'c</span><span class="o">&gt;</span> <span class="n">B</span><span class="o">&lt;</span><span class="nv">'c</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="c1">// we need to calculate this every time we query it.</span>
    <span class="k">fn</span> <span class="nf">difference</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.value</span> <span class="o">-</span> <span class="k">self</span><span class="py">.child</span><span class="nf">.borrow</span><span class="p">()</span><span class="py">.value</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="n">C</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="n">value</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">c</span> <span class="o">=</span> <span class="nn">std</span><span class="p">::</span><span class="nn">cell</span><span class="p">::</span><span class="nn">RefCell</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="n">C</span> <span class="p">{</span><span class="n">value</span><span class="p">:</span> <span class="mi">10</span><span class="p">});</span>
    <span class="k">let</span> <span class="n">a</span> <span class="o">=</span> <span class="n">A</span> <span class="p">{</span><span class="n">value</span><span class="p">:</span> <span class="mi">15</span><span class="p">,</span> <span class="n">child</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">c</span><span class="p">};</span>
    <span class="k">let</span> <span class="n">b</span> <span class="o">=</span> <span class="n">B</span> <span class="p">{</span><span class="n">value</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span> <span class="n">child</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">c</span><span class="p">};</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"A's total: {}"</span><span class="p">,</span> <span class="n">a</span><span class="nf">.total</span><span class="p">());</span>               <span class="c1">// 25</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"B's difference: {}"</span><span class="p">,</span> <span class="n">b</span><span class="nf">.difference</span><span class="p">());</span>     <span class="c1">// 20</span>

    <span class="n">c</span><span class="nf">.borrow_mut</span><span class="p">()</span><span class="py">.value</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"A's total: {}"</span><span class="p">,</span> <span class="n">a</span><span class="nf">.total</span><span class="p">());</span>               <span class="c1">// 20</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"B's difference: {}"</span><span class="p">,</span> <span class="n">b</span><span class="nf">.difference</span><span class="p">());</span>     <span class="c1">// 25</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="the-internal-consistency-problem">The “Internal Consistency Problem”</h3>

<p>If this is not your use case, and you want your data to remain consistent without having to recalculate for <code class="language-plaintext highlighter-rouge">C</code> every single time, then we need to make some changes.</p>

<p>In this case, <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> are going to need to be notified when <code class="language-plaintext highlighter-rouge">C</code> changes, so they know that their old data is no longer valid. In order to do this, there must be some object, let’s say <code class="language-plaintext highlighter-rouge">P</code> for “Parent” which knows about <code class="language-plaintext highlighter-rouge">A</code>, <code class="language-plaintext highlighter-rouge">B</code>, and the common child <code class="language-plaintext highlighter-rouge">C</code>.</p>

<p><img src="/notepad/img/20190826_3.jpg" alt="There must exist some object P" /></p>

<p>Any time we need to change the child <code class="language-plaintext highlighter-rouge">C</code>, we go though the parent <code class="language-plaintext highlighter-rouge">P</code>. That way <code class="language-plaintext highlighter-rouge">P</code> can tell both <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> that <code class="language-plaintext highlighter-rouge">C</code> has changed, and our data is internally consistent. We’re not allowed to modify <code class="language-plaintext highlighter-rouge">C</code> through <code class="language-plaintext highlighter-rouge">A</code> or <code class="language-plaintext highlighter-rouge">B</code> anymore, because <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> don’t know about each other.</p>

<p>We now realize that <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> don’t need to know about <code class="language-plaintext highlighter-rouge">C</code>. Every time <code class="language-plaintext highlighter-rouge">C</code> changes, <code class="language-plaintext highlighter-rouge">P</code> tells <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> all the necessary information about the change. <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> are then updated accordingly. In fact, <code class="language-plaintext highlighter-rouge">A</code> and <code class="language-plaintext highlighter-rouge">B</code> <em>can’t</em> know about <code class="language-plaintext highlighter-rouge">C</code>. If they knew about <code class="language-plaintext highlighter-rouge">C</code>, then we have the same problem that we started with, except now we have shared mutability between three objects not just two.</p>

<p><img src="/notepad/img/20190826_5.jpg" alt="P owning A, B and C" /></p>

<p>Now <code class="language-plaintext highlighter-rouge">P</code> is now the only object which has mutable access to <code class="language-plaintext highlighter-rouge">C</code>. We solved the problems of shared mutability by not having sharing. We had to make the changes above if we wanted our data to remain internally consistent. If we take this to the extreme, we can say that <code class="language-plaintext highlighter-rouge">A</code>, <code class="language-plaintext highlighter-rouge">B</code> and <code class="language-plaintext highlighter-rouge">P</code> are the same object. Below is an implementation:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">P</span> <span class="p">{</span>
    <span class="n">a</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="n">b</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="n">c</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="n">a_plus_c</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="n">b_minus_c</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">impl</span> <span class="n">P</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span> <span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span> <span class="n">c</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="n">P</span> <span class="p">{</span>
            <span class="n">a</span><span class="p">:</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">:</span> <span class="n">c</span><span class="p">,</span>
            <span class="n">a_plus_c</span><span class="p">:</span> <span class="n">a</span> <span class="o">+</span> <span class="n">c</span><span class="p">,</span>
            <span class="n">b_minus_c</span><span class="p">:</span> <span class="n">b</span> <span class="o">-</span> <span class="n">c</span><span class="p">,</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">set_c</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">,</span> <span class="n">c</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.c</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>
        <span class="k">self</span><span class="py">.a_plus_c</span> <span class="o">=</span> <span class="k">self</span><span class="py">.a</span> <span class="o">+</span> <span class="k">self</span><span class="py">.c</span><span class="p">;</span>
        <span class="k">self</span><span class="py">.b_minus_c</span> <span class="o">=</span> <span class="k">self</span><span class="py">.b</span> <span class="o">-</span> <span class="k">self</span><span class="py">.c</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="c1">// we don't need to recalculate each time.</span>
    <span class="k">fn</span> <span class="nf">total</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.a_plus_c</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">difference</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.b_minus_c</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">p</span> <span class="o">=</span> <span class="nn">P</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"A's total: {}"</span><span class="p">,</span> <span class="n">p</span><span class="nf">.total</span><span class="p">());</span>               <span class="c1">// 25</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"B's difference: {}"</span><span class="p">,</span> <span class="n">p</span><span class="nf">.difference</span><span class="p">());</span>     <span class="c1">// 20</span>

    <span class="n">p</span><span class="nf">.set_c</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"A's total: {}"</span><span class="p">,</span> <span class="n">p</span><span class="nf">.total</span><span class="p">());</span>               <span class="c1">// 20</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"B's difference: {}"</span><span class="p">,</span> <span class="n">p</span><span class="nf">.difference</span><span class="p">());</span>     <span class="c1">// 25</span>
<span class="p">}</span>
</code></pre></div></div>

<p>We draw the conclusion that shared mutability and internal consistency are mutually exclusive. We have to choose one or the other. Choosing both at the same time will lead to incoherent programs, and we have no reason to be writing incoherent programs.</p>

<h3 id="prevent-mutability">Prevent mutability.</h3>

<p>We have already seen one solution to the “internal consistency problem”: make all modifications go through a common ancestor. That basically means we get rid of the “sharing” part of “shared mutability”. We can also try rid ourselves of the “mutability” part of “shared mutability”.</p>

<p>First of all we split our objects into two parts. The part of the object that doesn’t depend on <code class="language-plaintext highlighter-rouge">C</code> and the part that does. We’ll use subscript to denote that the object depends on <code class="language-plaintext highlighter-rouge">C</code>.</p>

<p><img src="/notepad/img/20190826_7.jpg" alt="Split A and B in half" /></p>

<p>We know that <code class="language-plaintext highlighter-rouge">A</code> does not depend on <code class="language-plaintext highlighter-rouge">C</code>, so if <code class="language-plaintext highlighter-rouge">C</code> changes, we don’t have to notify <code class="language-plaintext highlighter-rouge">A</code>. This is the same with <code class="language-plaintext highlighter-rouge">B</code>. We can make any modifications we like to <code class="language-plaintext highlighter-rouge">A</code>, <code class="language-plaintext highlighter-rouge">B</code> and <code class="language-plaintext highlighter-rouge">C</code>, and they’ll all be correct. <code class="language-plaintext highlighter-rouge">Ac</code> and <code class="language-plaintext highlighter-rouge">Bc</code> however, have the same problems that we had before.</p>

<p>Instead of trying to keep <code class="language-plaintext highlighter-rouge">Ac</code> and <code class="language-plaintext highlighter-rouge">Bc</code> up to date all the time every time we change <code class="language-plaintext highlighter-rouge">C</code>, we can <em>freeze</em> <code class="language-plaintext highlighter-rouge">P</code> to stop it from becoming modified, then (and only then), we <em>create</em> <code class="language-plaintext highlighter-rouge">Ac</code> and <code class="language-plaintext highlighter-rouge">Bc</code>. As long as <code class="language-plaintext highlighter-rouge">P</code> and it’s children remain unmodified, <code class="language-plaintext highlighter-rouge">Ac</code> and <code class="language-plaintext highlighter-rouge">Bc</code> will be correct.</p>

<p><img src="/notepad/img/20190826_6.jpg" alt="A &quot;view&quot; of the object." /></p>

<p>We can freeze an object in Rust by taking an immutable reference of it. The following code implements this idea:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">P2</span> <span class="p">{</span>
    <span class="k">pub</span> <span class="n">a</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="k">pub</span> <span class="n">b</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="k">pub</span> <span class="n">c</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">struct</span> <span class="n">View</span><span class="o">&lt;</span><span class="nv">'p</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">_lock</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'p</span> <span class="n">P2</span><span class="p">,</span>
    <span class="n">total</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
    <span class="n">difference</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">impl</span><span class="o">&lt;</span><span class="nv">'p</span><span class="o">&gt;</span> <span class="n">View</span><span class="o">&lt;</span><span class="nv">'p</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">parent</span><span class="p">:</span> <span class="o">&amp;</span><span class="nv">'p</span> <span class="n">P2</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="n">View</span> <span class="p">{</span>
            <span class="n">_lock</span><span class="p">:</span> <span class="n">parent</span><span class="p">,</span>
            <span class="n">total</span><span class="p">:</span> <span class="n">parent</span><span class="py">.a</span> <span class="o">+</span> <span class="n">parent</span><span class="py">.c</span><span class="p">,</span>
            <span class="n">difference</span><span class="p">:</span> <span class="n">parent</span><span class="py">.b</span> <span class="o">-</span> <span class="n">parent</span><span class="py">.c</span><span class="p">,</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">total</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.total</span>
    <span class="p">}</span>
    <span class="k">fn</span> <span class="nf">difference</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.difference</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">p2</span> <span class="o">=</span> <span class="n">P2</span> <span class="p">{</span><span class="n">a</span><span class="p">:</span> <span class="mi">15</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span> <span class="n">c</span><span class="p">:</span> <span class="mi">10</span><span class="p">};</span>
    <span class="p">{</span>
        <span class="c1">// p2 is locked to mutable access for the duration of 'p.</span>
        <span class="k">let</span> <span class="n">view</span> <span class="o">=</span> <span class="nn">View</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p2</span><span class="p">);</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"A's total: {}"</span><span class="p">,</span> <span class="n">view</span><span class="nf">.total</span><span class="p">());</span>               <span class="c1">// 25</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"B's difference: {}"</span><span class="p">,</span> <span class="n">view</span><span class="nf">.difference</span><span class="p">());</span>     <span class="c1">// 20</span>
        <span class="c1">// The lock is released here</span>
    <span class="p">}</span>

    <span class="n">p2</span><span class="py">.c</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>

    <span class="p">{</span>
        <span class="c1">// p2 is locked to mutable access for the duration of 'p.</span>
        <span class="k">let</span> <span class="n">view</span> <span class="o">=</span> <span class="nn">View</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="o">&amp;</span><span class="n">p2</span><span class="p">);</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"A's total: {}"</span><span class="p">,</span> <span class="n">view</span><span class="nf">.total</span><span class="p">());</span>               <span class="c1">// 25</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"B's difference: {}"</span><span class="p">,</span> <span class="n">view</span><span class="nf">.difference</span><span class="p">());</span>     <span class="c1">// 20</span>
        <span class="c1">// The lock is released here</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="conclusion">Conclusion.</h3>

<p>Sometimes your program design calls for some shared mutability. Unfortunately, it is impossible for arbitrary data to remain consistent in the presence of shared mutability. We have to choose to get rid of one of sharing, mutability, or the expectation of consistency. I have presented two ways to structure programs which solve typical use cases for shared mutability, whilst still remaining correct.</p>

<p>In the next article, I will use the knowledge discovered here to discuss making arbitrary directed acyclic graphs in Rust.</p>

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="Rust" /><category term="graph" /><category term="acyclic" /><category term="mutability" /><category term="references" /><summary type="html"><![CDATA[Summary]]></summary></entry><entry><title type="html">Understanding closures, fn, Fn, FnMut and FnOnce.</title><link href="/notepad/notes/2019/06/23/on_closures.html" rel="alternate" type="text/html" title="Understanding closures, fn, Fn, FnMut and FnOnce." /><published>2019-06-23T00:00:00+00:00</published><updated>2019-06-23T00:00:00+00:00</updated><id>/notepad/notes/2019/06/23/on_closures</id><content type="html" xml:base="/notepad/notes/2019/06/23/on_closures.html"><![CDATA[<h3 id="summary">Summary</h3>

<ul>
  <li>Closures are a combination of a function pointer (<code class="language-plaintext highlighter-rouge">fn</code>) and a context.</li>
  <li>A closure with no context is just a function pointer.</li>
  <li>A closure which has an immutable context belongs to <code class="language-plaintext highlighter-rouge">Fn</code>.</li>
  <li>A closure which has a mutable context belongs to <code class="language-plaintext highlighter-rouge">FnMut</code>.</li>
  <li>A closure that owns it’s context belongs to <code class="language-plaintext highlighter-rouge">FnOnce</code>.</li>
</ul>

<h2 id="understanding-the-different-types-of-closures-in-rust">Understanding the different types of closures in Rust.</h2>

<p><img src="/notepad/img/2019-06-23-fn_types.jpg" alt="The different kinds of function traits" /></p>

<p>Unlike some other languages, Rust is explicit about our use of the <code class="language-plaintext highlighter-rouge">self</code> parameter. We have to specify <code class="language-plaintext highlighter-rouge">self</code> to be the first parameter of a function signature when we are implementing a struct:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">MyStruct</span> <span class="p">{</span>
    <span class="n">text</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">'static</span> <span class="nb">str</span><span class="p">,</span>
    <span class="n">number</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>

<span class="k">impl</span> <span class="n">MyStruct</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">new</span> <span class="p">(</span><span class="n">text</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">'static</span> <span class="nb">str</span><span class="p">,</span> <span class="n">number</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">MyStruct</span> <span class="p">{</span>
        <span class="n">MyStruct</span> <span class="p">{</span>
            <span class="n">text</span><span class="p">:</span> <span class="n">text</span><span class="p">,</span>
            <span class="n">number</span><span class="p">:</span> <span class="n">number</span><span class="p">,</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="c1">// We have to specify that 'self' is an argument.</span>
    <span class="k">fn</span> <span class="nf">get_number</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.number</span>
    <span class="p">}</span>
    <span class="c1">// We can specify different kinds of ownership and mutability of self.</span>
    <span class="k">fn</span> <span class="nf">inc_number</span> <span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.number</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="c1">// There are three different types of 'self'</span>
    <span class="k">fn</span> <span class="nf">destructor</span> <span class="p">(</span><span class="k">self</span><span class="p">)</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"Destructing {}"</span><span class="p">,</span> <span class="k">self</span><span class="py">.text</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>As a result, the following two styles are identical:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">obj</span><span class="nf">.get_number</span><span class="p">();</span>
<span class="nn">MyStruct</span><span class="p">::</span><span class="nf">get_number</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj</span><span class="p">);</span>
</code></pre></div></div>

<p>This is in contrast to other languages where <code class="language-plaintext highlighter-rouge">self</code> (or <code class="language-plaintext highlighter-rouge">this</code>) is often implied. Simply associating a function with an object or structure in these languages can imply that the first argument is <code class="language-plaintext highlighter-rouge">self</code>. Demonstrated above, we have four options for <code class="language-plaintext highlighter-rouge">self</code>: an immutable reference, a mutable reference, an owned value, or to not use <code class="language-plaintext highlighter-rouge">self</code> as an argument at all.</p>

<p>As a result, <code class="language-plaintext highlighter-rouge">self</code> implies some sort of context for the execution of the function. it is explicit in Rust, but often implicit elsewhere.</p>

<p>Also in this post we will use the following functions:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="n">is_fn</span> <span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">R</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_x</span><span class="p">:</span> <span class="k">fn</span><span class="p">(</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">R</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">fn</span> <span class="n">is_Fn</span> <span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">F</span><span class="p">:</span> <span class="nf">Fn</span><span class="p">(</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">R</span><span class="o">&gt;</span> <span class="p">(</span><span class="n">_x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">F</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">fn</span> <span class="n">is_FnMut</span> <span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">F</span><span class="p">:</span> <span class="nf">FnMut</span><span class="p">(</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">R</span><span class="o">&gt;</span> <span class="p">(</span><span class="n">_x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">F</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">fn</span> <span class="n">is_FnOnce</span> <span class="o">&lt;</span><span class="n">A</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">F</span><span class="p">:</span> <span class="nf">FnOnce</span><span class="p">(</span><span class="n">A</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="n">R</span><span class="o">&gt;</span> <span class="p">(</span><span class="n">_x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">F</span><span class="p">)</span> <span class="p">{}</span>
</code></pre></div></div>

<p>The only purpose of these functions is to typecheck. For example, if <code class="language-plaintext highlighter-rouge">is_FnMut(&amp;func)</code> compiles, then we know that <code class="language-plaintext highlighter-rouge">func</code> belongs to the <code class="language-plaintext highlighter-rouge">FnMut</code> trait.</p>

<h2 id="no-context-and-the-fn-lowercase-f-type">No Context and the <code class="language-plaintext highlighter-rouge">fn</code> (lowercase f) type</h2>

<p>With this in mind, consider some examples of closures using <code class="language-plaintext highlighter-rouge">MyStruct</code> above:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">obj1</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span>
<span class="k">let</span> <span class="n">obj2</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"More Text"</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

<span class="k">let</span> <span class="n">closure1</span> <span class="o">=</span> <span class="p">|</span><span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">|</span> <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span><span class="p">;</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">closure1</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj1</span><span class="p">),</span> <span class="mi">18</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">closure1</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">13</span><span class="p">);</span>
</code></pre></div></div>

<p>This is about as simple as we can get. This closure adds three to the number of any object of type <code class="language-plaintext highlighter-rouge">MyStruct</code> it has been given. It can be executed anywhere without any issues, and the compiler will not give you any trouble. We can quite easily write <code class="language-plaintext highlighter-rouge">closure1</code> like this instead:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// It doesn't matter what code appears here, the function will behave</span>
<span class="c1">// exactly the same.</span>

<span class="k">fn</span> <span class="nf">func1</span> <span class="p">(</span><span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
    <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span> <span class="o">+</span> <span class="mi">3</span>
<span class="p">}</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">func1</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj1</span><span class="p">),</span> <span class="mi">18</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">func1</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">13</span><span class="p">);</span>
</code></pre></div></div>

<p>This function does not depend on it’s context. It will behave exactly the same no matter what happens before or after it. We can use <code class="language-plaintext highlighter-rouge">func1</code> and <code class="language-plaintext highlighter-rouge">closure1</code> (almost) interchangeably.</p>

<p>When a closure does not depend on context at all, the type of our closure is <code class="language-plaintext highlighter-rouge">fn</code>:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// compiles successfully.</span>
<span class="nf">is_fn</span><span class="p">(</span><span class="n">closure1</span><span class="p">);</span> 
<span class="nf">is_Fn</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure1</span><span class="p">);</span>
<span class="nf">is_FnMut</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure1</span><span class="p">);</span>
<span class="nf">is_FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure1</span><span class="p">);</span>
</code></pre></div></div>

<h2 id="immutable-context-and-the-fn-capital-f-trait">Immutable context and the <code class="language-plaintext highlighter-rouge">Fn</code> (Capital F) trait</h2>

<p>Compared to the above, we can add a context to a closure.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">obj1</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span>
<span class="k">let</span> <span class="n">obj2</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"More Text"</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

<span class="c1">// obj1 is borrowed by the closure immutably.</span>
<span class="k">let</span> <span class="n">closure2</span> <span class="o">=</span> <span class="p">|</span><span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">|</span> <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span> <span class="o">+</span> <span class="n">obj1</span><span class="nf">.get_number</span><span class="p">();</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">closure2</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">25</span><span class="p">);</span>

<span class="c1">// We can borrow obj1 again immutably...</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">obj1</span><span class="nf">.get_number</span><span class="p">(),</span> <span class="mi">15</span><span class="p">);</span>

<span class="c1">// But we can't borrow it mutably.</span>
<span class="c1">// obj1.inc_number();               // ERROR</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">closure2</code> depends on the value of <code class="language-plaintext highlighter-rouge">obj1</code> and contains information about the surrounding scope. In this case, <code class="language-plaintext highlighter-rouge">closure2</code> will borrow <code class="language-plaintext highlighter-rouge">obj1</code> so that it can use it in the function body. We can still borrow <code class="language-plaintext highlighter-rouge">obj1</code> immutably, but if we were attempt to mutate <code class="language-plaintext highlighter-rouge">obj1</code> afterwards, we would get a borrowing error.</p>

<p>If we try to rewrite our closure using <code class="language-plaintext highlighter-rouge">fn</code> syntax, everything we need to know inside of the function must be passed to it as an argument, so we add an additional argument to represent the context of the function:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Context</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">'a</span> <span class="n">MyStruct</span><span class="p">);</span>

<span class="k">let</span> <span class="n">obj1</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span>
<span class="k">let</span> <span class="n">obj2</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"More Text"</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

<span class="k">let</span> <span class="n">ctx</span> <span class="o">=</span> <span class="nf">Context</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj1</span><span class="p">);</span>

<span class="k">fn</span> <span class="nf">func2</span> <span class="p">(</span><span class="n">context</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">Context</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
    <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span> <span class="o">+</span> <span class="n">context</span><span class="na">.0</span><span class="nf">.get_number</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Which behaves almost identically to our closure:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">func2</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ctx</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">25</span><span class="p">);</span>

<span class="c1">// We can borrow obj1 again immutably...</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="n">obj1</span><span class="nf">.get_number</span><span class="p">(),</span> <span class="mi">15</span><span class="p">);</span>

<span class="c1">// But we can't borrow it mutably.</span>
<span class="c1">// obj1.inc_number(); // ERROR</span>
</code></pre></div></div>

<p>Note that the <code class="language-plaintext highlighter-rouge">Context</code> struct contains an immutable reference to <code class="language-plaintext highlighter-rouge">MyStruct</code> indicating that we won’t be able to modify it inside the function.</p>

<p>When we call <code class="language-plaintext highlighter-rouge">closure1</code> it is <em>implied</em> that we pass the surrounding context as an argument to the closure, like we had to do it with our <code class="language-plaintext highlighter-rouge">fn</code>. Like in some other languages where we don’t have to specify that we pass <code class="language-plaintext highlighter-rouge">self</code> as an argument, Rust doesn’t need us to explicitly specify that we pass our context as an argument.</p>

<p>When a closure takes a context as an immutable reference, we say that it implements the <code class="language-plaintext highlighter-rouge">Fn</code> trait. That tells us that we can call our function multiple times without modifying the context:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Does not compile:</span>
<span class="c1">// is_fn(closure2);</span>

<span class="c1">// Compiles successfully:</span>
<span class="nf">is_Fn</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure2</span><span class="p">);</span>
<span class="nf">is_FnMut</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure2</span><span class="p">);</span>
<span class="nf">is_FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure2</span><span class="p">);</span>
</code></pre></div></div>

<h2 id="mutable-context-and-the-fnmut-trait">Mutable context and the <code class="language-plaintext highlighter-rouge">FnMut</code> trait</h2>

<p>If we modify <code class="language-plaintext highlighter-rouge">obj1</code> inside the closure, we get different results:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">obj1</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span>
<span class="k">let</span> <span class="n">obj2</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"More Text"</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

<span class="c1">// obj1 is borrowed by the closure mutably.</span>
<span class="k">let</span> <span class="k">mut</span> <span class="n">closure3</span> <span class="o">=</span> <span class="p">|</span><span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">|</span> <span class="p">{</span>
    <span class="n">obj1</span><span class="nf">.inc_number</span><span class="p">();</span>
    <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span> <span class="o">+</span> <span class="n">obj1</span><span class="nf">.get_number</span><span class="p">()</span>
<span class="p">};</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">closure3</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">26</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">closure3</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">27</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">closure3</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">28</span><span class="p">);</span>

<span class="c1">// We can't borrow obj1 mutably or immutably</span>
<span class="c1">// assert_eq!(obj1.get_number(), 18);   // ERROR</span>
<span class="c1">// obj1.inc_number();                   // ERROR</span>
</code></pre></div></div>

<p>This time we can’t borrow <code class="language-plaintext highlighter-rouge">obj1</code> mutably or immutably. We also have to annotate the closure as <code class="language-plaintext highlighter-rouge">mut</code>. If we wish to rewrite this function using <code class="language-plaintext highlighter-rouge">fn</code> syntax, we get the following:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Context</span><span class="o">&lt;</span><span class="nv">'a</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="nv">'a</span> <span class="k">mut</span> <span class="n">MyStruct</span><span class="p">);</span>

<span class="k">let</span> <span class="k">mut</span> <span class="n">obj1</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span>
<span class="k">let</span> <span class="n">obj2</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"More Text"</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

<span class="k">let</span> <span class="k">mut</span> <span class="n">ctx</span> <span class="o">=</span> <span class="nf">Context</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">obj1</span><span class="p">);</span>

<span class="c1">// obj1 is borrowed by the closure mutably.</span>
<span class="k">fn</span> <span class="nf">func3</span> <span class="p">(</span><span class="n">context</span><span class="p">:</span> <span class="o">&amp;</span><span class="k">mut</span> <span class="n">Context</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
    <span class="n">context</span><span class="na">.0</span><span class="nf">.inc_number</span><span class="p">();</span>
    <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span> <span class="o">+</span> <span class="n">context</span><span class="na">.0</span><span class="nf">.get_number</span><span class="p">()</span>
<span class="p">};</span>
</code></pre></div></div>

<p>This behaves the same way as <code class="language-plaintext highlighter-rouge">closure3</code>:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">func3</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">ctx</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">26</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">func3</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">ctx</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">27</span><span class="p">);</span>
<span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">func3</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="n">ctx</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">28</span><span class="p">);</span>

<span class="c1">// We can't borrow obj1 mutably or immutably</span>
<span class="c1">// assert_eq!(obj1.get_number(), 18);       // ERROR</span>
<span class="c1">// obj1.inc_number();                       // ERROR</span>
</code></pre></div></div>

<p>Note that we have to pass our context with a mutable reference. This indicates that we may get different results every time we call our function.</p>

<p>When a closure takes it’s context using a mutable reference, we say that it belongs to the <code class="language-plaintext highlighter-rouge">FnMut</code> trait:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Does not compile:</span>
<span class="c1">// is_fn(closure3);</span>
<span class="c1">// is_Fn(&amp;closure3);</span>

<span class="c1">// Compiles successfully:</span>
<span class="nf">is_FnMut</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure3</span><span class="p">);</span>
<span class="nf">is_FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure3</span><span class="p">);</span>
</code></pre></div></div>

<h2 id="owned-context">Owned Context:</h2>

<p>For our last example we’ll take ownership of <code class="language-plaintext highlighter-rouge">obj1</code>:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">obj1</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span>
<span class="k">let</span> <span class="n">obj2</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"More Text"</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

<span class="c1">// obj1 is owned by the closure</span>
<span class="k">let</span> <span class="n">closure4</span> <span class="o">=</span> <span class="p">|</span><span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">|</span> <span class="p">{</span>
    <span class="n">obj1</span><span class="nf">.destructor</span><span class="p">();</span>
    <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span>
<span class="p">};</span>
</code></pre></div></div>

<p>We have to check the type of <code class="language-plaintext highlighter-rouge">closure4</code> <em>before</em> we use it:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Does not compile:</span>
<span class="c1">// is_fn(closure4);</span>
<span class="c1">// is_Fn(&amp;closure4);</span>
<span class="c1">// is_FnMut(&amp;closure4);</span>

<span class="c1">// Compiles successfully:</span>
<span class="nf">is_FnOnce</span><span class="p">(</span><span class="o">&amp;</span><span class="n">closure4</span><span class="p">);</span>
</code></pre></div></div>

<p>Now we can check the behavior of it:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">closure4</span><span class="p">(</span><span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">10</span><span class="p">);</span>

<span class="c1">// We can't call closure4 twice...</span>
<span class="c1">// assert_eq!(closure4(&amp;obj2), 10);             //ERROR</span>

<span class="c1">// We can't borrow obj1 mutably or immutably</span>
<span class="c1">// assert_eq!(obj1.get_number(), 15);           // ERROR</span>
<span class="c1">// obj1.inc_number();                           // ERROR</span>
</code></pre></div></div>

<p>In this example, we can only call the function once. Once we have called it the first time, we have destroyed <code class="language-plaintext highlighter-rouge">obj1</code>, so it no longer exists for the second call. Rust gives us an error about using a value after it has been moved. That’s why we have to check the types beforehand.</p>

<p>Writing this with an <code class="language-plaintext highlighter-rouge">fn</code> we get the following:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="nf">Context</span><span class="p">(</span><span class="n">MyStruct</span><span class="p">);</span>

<span class="k">let</span> <span class="n">obj1</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"Hello"</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span>
<span class="k">let</span> <span class="n">obj2</span> <span class="o">=</span> <span class="nn">MyStruct</span><span class="p">::</span><span class="nf">new</span><span class="p">(</span><span class="s">"More Text"</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>

<span class="k">let</span> <span class="n">ctx</span> <span class="o">=</span> <span class="nf">Context</span><span class="p">(</span><span class="n">obj1</span><span class="p">);</span>

<span class="c1">// obj1 is owned by the closure</span>
<span class="k">fn</span> <span class="nf">func4</span> <span class="p">(</span><span class="n">context</span><span class="p">:</span> <span class="n">Context</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">MyStruct</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
    <span class="n">context</span><span class="na">.0</span><span class="nf">.destructor</span><span class="p">();</span>
    <span class="n">x</span><span class="nf">.get_number</span><span class="p">()</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Which, as expected, behaves the same as our closure:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">assert_eq!</span><span class="p">(</span><span class="nf">func4</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj2</span><span class="p">),</span> <span class="mi">10</span><span class="p">);</span>

<span class="c1">// We can't call func4 twice...</span>
<span class="c1">// assert_eq!(func4(ctx, &amp;obj2), 10);             //ERROR</span>

<span class="c1">// We can't borrow obj1 mutably or immutably</span>
<span class="c1">// assert_eq!(obj1.get_number(), 15);           // ERROR</span>
<span class="c1">// obj1.inc_number();                           // ERROR</span>
</code></pre></div></div>

<p>When we write our closure using <code class="language-plaintext highlighter-rouge">fn</code> we have to use a <code class="language-plaintext highlighter-rouge">Context</code> struct that owns it’s value. When a closure takes ownership of it’s context, we say that it implements <code class="language-plaintext highlighter-rouge">FnOnce</code>. We can only call the function once, because after that, the context has been destroyed.</p>

<h2 id="conclusion">Conclusion</h2>

<ul>
  <li>Functions that require no context have the <code class="language-plaintext highlighter-rouge">fn</code> type, and can be called anywhere.</li>
  <li>Functions that only need immutable access to their context belong to the <code class="language-plaintext highlighter-rouge">Fn</code> trait, and can be called anywhere as long as the context is still in scope.</li>
  <li>Functions that need mutable access to their context implement the <code class="language-plaintext highlighter-rouge">FnMut</code> trait, which can be called anywhere the context is valid, but may do something different each time.</li>
  <li>Functions that take ownership of their context can only be called once.</li>
</ul>

<hr />

<p>This post was originally posted on <a href="/notepad/">Andrew’s Notepad</a></p>]]></content><author><name></name></author><category term="notes" /><category term="rust" /><category term="closures" /><category term="call" /><category term="function" /><category term="context" /><category term="functional programming." /><summary type="html"><![CDATA[Summary]]></summary></entry></feed>