<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Jacob Thomas Errington's blog</title>
    <link href="https://jerrington.me/atom.xml" rel="self" />
    <link href="https://jerrington.me" />
    <id>https://jerrington.me/atom.xml</id>
    <author>
        <name>Jacob Thomas Errington</name>
        <email>blog@mail.jerrington.me</email>
    </author>
    <updated>2025-12-23T00:00:00Z</updated>
    <entry>
    <title>Grids without indices</title>
    <link href="https://jerrington.me/posts/2025-12-23-grids-without-indices.html" />
    <id>https://jerrington.me/posts/2025-12-23-grids-without-indices.html</id>
    <published>2025-12-23T00:00:00Z</published>
    <updated>2025-12-23T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on December 23, 2025
    
</div>

<p>Working with grids in Haskell (or any purely functional language, I’m sure) can
be pretty painful, but it doesn’t have to be. The reason it’s so painful is
that we’re tempted to manipulate grids using indices.
Now maybe if we’re using a nice array library such as <code>vector</code>, then index-based
manipulations aren’t so gross, but in this article, I’ll show you a way to
manipulate grids that is based on good ol’ lists, and which generalizes to
structures beyond grids.</p>
<p>A common problem involving grids is to construct a new one based on an old one
by looking in a neighbourhood around each point in the grid. For example,
Conway’s <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Game of Life</a>, which is what’s called a <em>cellular automaton</em>, is
such a problem. The idea is that we have a grid, and each cell is either dead or
alive. Each iteration constructs a new grid from the current grid by applying
the following process to each cell simultaneously:</p>
<ul>
<li>A dead cell becomes alive if it has exactly three live neighbours.</li>
<li>A live cell remains alive if it has two or three live neighbours.</li>
<li>Any cell dies or remains dead otherwise.</li>
</ul>
<p>The challenge with this problem is that each cell is not completely independent:
each cell needs to know something about its neighbours in order to update. The
upshot is that we can’t just map over the grid to do an update. We need some
kind of “context-aware” map. The ultimate goal of this article will be to arrive
at exactly such an abstraction.</p>
<h2 id="one-dimension">One dimension</h2>
<p>Yes, Game of Life is flashy, but let’s start with a 1D cellular automaton called
<a href="https://en.wikipedia.org/wiki/Rule_110">Rule 110</a>. I’ll skip the details of this automaton and instead let
you look at this beautiful gif that illustrates how the next generation is
constructed.</p>
<figure>
<img src="https://upload.wikimedia.org/wikipedia/commons/b/b5/One-d-cellular-automaton-rule-110.gif" alt="licence" />
<figcaption aria-hidden="true"><a href="https://commons.wikimedia.org/wiki/File:One-d-cellular-automaton-rule-110.gif">licence</a></figcaption>
</figure>
<p>In short, each cell looks at at itself and its left and right neighbours to
decide what state it should be in (on or off) in the next generation.</p>
<p>A 1D grid is just a list, but remember, we have this requirement of some kind of
context awareness. So let’s just add a notion of a “focus” to a list. We end up
with a structure that I’ll call <code>Z</code>.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List.NonEmpty</span> ( <span class="dt">NonEmpty</span>(..) )</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.List.NonEmpty</span> <span class="kw">as</span> <span class="dt">N</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Z</span> a <span class="ot">=</span> <span class="dt">Z</span> [a] a [a] <span class="kw">deriving</span> (<span class="dt">Functor</span>, <span class="dt">Foldable</span>, <span class="dt">Traversable</span>)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="ot">fromList ::</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> a</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>fromList (x <span class="op">:|</span> xs) <span class="ot">=</span> <span class="dt">Z</span> [] x xs</span></code></pre></div>
<p>We can of course extract the focused element from the <code>Z</code>.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">extractZ ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>extractZ (<span class="dt">Z</span> _ x _) <span class="ot">=</span> x</span></code></pre></div>
<p>We can also move the focus around. In particular, we can move it to the left, or
to the right, provided there’s still stuff remaining in the relevant list.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">left ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Z</span> a)</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>left (<span class="dt">Z</span> [] _ _ ) <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>left (<span class="dt">Z</span> (l<span class="op">:</span>ls) x rs) <span class="ot">=</span> <span class="dt">Just</span> (<span class="dt">Z</span> ls l (x<span class="op">:</span>rs))</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="ot">right ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Z</span> a)</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>right (<span class="dt">Z</span> _ _ []) <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>right (<span class="dt">Z</span> ls x (r<span class="op">:</span>rs)) <span class="ot">=</span> <span class="dt">Just</span> (<span class="dt">Z</span> (x<span class="op">:</span>ls) r rs)</span></code></pre></div>
<p>Visually, here’s what moving left and right looks like, using <code>|</code> to isolate the
focus.</p>
<pre><code>Initially:   ... a  b |c| d e ...
Moving left: ... a |b| c  d e ...</code></pre>
<p>The resulting structure has the same list inside of it; all that’s changed is
our point of view.
Now that isn’t particularly mindblowing. But here’s what is: what if we
collected <em>all</em> the different possible focuses? In other words, we want a
structure that has a version of this <code>Z</code> with <code>a</code> selected, and one with <code>b</code>
selected, and one with <code>c</code> selected, and so on. Then, we can map over this
structure in order to implement Rule 110.</p>
<p>Let’s call this “collect all the different versions” operation “<code>duplicateZ</code>”.
We provide <code>duplicateZ</code> with a particular <code>Z a</code>, which is focusing on some <code>a</code>.
This input <code>Z a</code> must appear in the output, since it’s one of the ways we can
look at the list that underlies the <code>Z a</code>.</p>
<p>To represent the output of <code>duplicateZ</code>, let’s use the type <code>Z</code> itself!
This choice might sound a bit arbitrary at first, but it has some very nice
benefits. First, it explains why we called it <code>duplicateZ</code>; have a look at the
type now:</p>
<pre><code>duplicateZ :: Z a -&gt; Z (Z a)</code></pre>
<p>It’s the <code>Z</code> that gets duplicated!</p>
<p>To sort out the implementation of <code>duplicateZ</code>, let’s look at some properties we
would like it to have:</p>
<ol type="1">
<li>The input <code>Z a</code> ought to be the focused element of the output, meaning that
<code>extract (duplicateZ z)</code> gives us back the input <code>z</code>.</li>
<li>Moving left and right should commute with duplication, namely
<code>duplicateZ &lt;$&gt; left z</code> should equal <code>left (duplicateZ z)</code> (and likewise for
<code>right</code>).</li>
</ol>
<p>To implement <code>duplicateZ</code> satisfying these properties, we need a way to
collect all the left and right moves from the input. We’ll need a helper.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">iterateMaybe ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>iterateMaybe f x <span class="ot">=</span> x <span class="op">:</span> <span class="fu">maybe</span> [] (iterateMaybe f) (f x)</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="ot">duplicateZ ::</span> <span class="dt">Z</span> a <span class="ot">-&gt;</span> <span class="dt">Z</span> (<span class="dt">Z</span> a)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>duplicateZ z <span class="ot">=</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span> (<span class="fu">tail</span> <span class="op">$</span> iterateMaybe left z) z (<span class="fu">tail</span> <span class="op">$</span> iterateMaybe right z)</span></code></pre></div>
<p>Remember the property we expected to hold? Look closely at the implementation
above to convince yourself that it holds. We can generalize the property a bit
more: if we extract from all the positions generated by the duplication, we get
back the original structure. Of course, since <code>Z</code> is also a Functor, we can use
<code>fmap</code> to extract at every position.</p>
<pre><code>fmap extractZ . duplicateZ = id</code></pre>
<p>This property is one of the <em>comonad laws</em>. Yes, <code>Z</code> is what’s called a comonad!
The ability to extract from and duplicate the structure in such a way that these
operations ‘cancel out’ when composed is the essence of what it means to be a
comonad. There is a further operation we can derive from these two, namely a
function to apply a transformation at every possible focused position. We’ll
call this operation <code>extend</code>.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> w <span class="ot">=&gt;</span> <span class="dt">Comonad</span> w <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  duplicate ::</span> w a <span class="ot">-&gt;</span> w (w a)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  extract ::</span> w a <span class="ot">-&gt;</span> a</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  extend ::</span> (w a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> w a <span class="ot">-&gt;</span> w b</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  extend k <span class="ot">=</span> <span class="fu">fmap</span> k <span class="op">.</span> duplicate</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Comonad</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  duplicate <span class="ot">=</span> duplicateZ</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>  extract <span class="ot">=</span> extractZ</span></code></pre></div>
<p>Extend is implemented by duplicating the structure (which collects all the
focuses into a new structure) and then using <code>fmap</code> to apply the transformation
everywhere. What’s fascinating about <code>extend</code> is that it looks <em>almost</em> like
<code>fmap</code>. The difference is that the input to the function parameter gets a <code>w a</code>
instead of merely an <code>a</code>. Concretely for <code>Z</code>, what this means is
that the passed function can inspect what’s <em>around</em> the focus in order to
compute the <code>b</code>. Tying this back to cellular automata, we can use <code>extend</code> to
represent the process of simultaneously applying the rule of the automaton to
every position in the strip (or grid, as we’ll see in 2D).</p>
<aside>
<p>Let’s briefly
look at comonads versus monads, on the level of types.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Applicative</span> m <span class="ot">=&gt;</span> <span class="dt">Monad</span> m <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  pure ::</span> a <span class="ot">-&gt;</span> m a</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  join ::</span> m (m a) <span class="ot">-&gt;</span> m a</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  bind ::</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> w <span class="ot">=&gt;</span> <span class="dt">Comonad</span> w <span class="kw">where</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="ot">  extract ::</span> w a <span class="ot">-&gt;</span> a</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="ot">  duplicate ::</span> w a <span class="ot">-&gt;</span> w (w a)</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="ot">  extend ::</span> (w a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> w a <span class="ot">-&gt;</span> w b</span></code></pre></div>
Comonads are dual to monads, as you can see in the types: the operations are all
backwards. (This is also why we often see <code>w</code> for a comonad: it’s an upside down <code>m</code>.)
</aside>
<p>Now let’s implement the cellular automaton, Rule 110.
We’ll write a function <code>rule110 :: Z Bool -&gt; Bool</code> which, given a focused cell,
decides whether that cell should be alive or dead in the next iteration.
To handle the boundaries, we will consider that a cell outside the bounds of the
strip are dead.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">rule110 ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>rule110 z <span class="ot">=</span> <span class="kw">case</span> (get left, extract z, get right) <span class="kw">of</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">False</span>, <span class="dt">False</span>, <span class="dt">False</span>) <span class="ot">-&gt;</span> <span class="dt">False</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">False</span>, <span class="dt">False</span>, <span class="dt">True</span>) <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">False</span>, <span class="dt">True</span>, <span class="dt">False</span>) <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">False</span>, <span class="dt">True</span>, <span class="dt">True</span>) <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">True</span>, <span class="dt">False</span>, <span class="dt">False</span>) <span class="ot">-&gt;</span> <span class="dt">False</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">True</span>, <span class="dt">False</span>, <span class="dt">True</span>) <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">True</span>, <span class="dt">True</span>, <span class="dt">False</span>) <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">True</span>, <span class="dt">True</span>, <span class="dt">True</span>) <span class="ot">-&gt;</span> <span class="dt">False</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>    get f <span class="ot">=</span> <span class="fu">maybe</span> <span class="dt">False</span> extract (f z)</span></code></pre></div>
<p>This function determines whether a particular cell is dead or alive in the next
iteration.
Using <code>extend</code>, we can upgrade this to a function that computes the whole next
strip.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">step ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Z</span> <span class="dt">Bool</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>step <span class="ot">=</span> extend rule110</span></code></pre></div>
<p>And finally, we can upgrade this stepping function to one that computes, given
an initial strip, the infinite list of its evolution.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">steps ::</span> <span class="dt">Z</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> [<span class="dt">Z</span> <span class="dt">Bool</span>]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>steps <span class="ot">=</span> <span class="fu">iterate</span> step</span></code></pre></div>
<p>Overall, comonads give us an elegant language to express <em>contextual</em> computations. The computation
of the cellular automaton Rule 110 is contextual: each cell’s future state depends not only on its
current state, but also on the current state of both its neighbours.</p>
<h2 id="two-dimensions">Two dimensions</h2>
<p>Let’s solve a real problem, with an eye towards efficiency. What problem could be more real than
this year’s <a href="https://adventofcode.com/2025/day/4">Advent of Code, Day 4</a>?
It’s a problem about grids that look like this.</p>
<pre><code>..@@.@@@@.
@@@.@.@.@@
@@@@@.@.@@
@.@@@@..@.
@@.@@@@.@@
.@@@@@@@.@
.@.@.@.@@@
@.@@@.@@@@
.@@@@@@@@.
@.@.@@@.@.</code></pre>
<p>In part 1, we want to count how many <code>@</code> cells have fewer than 4 other <code>@</code>s in their eight-square
neighbourhood.</p>
<p>We could – and I certainly did, in the past – construct a two-dimensional variation on what we
did above. However, the resulting structure, being built entirely out of linked lists, is
enormously inefficient. Not only that, but it will end up privileging certain movements: if we
designed this grid in a row-major way, then moving to an adjacent row is instant, but
moving to an adjacent column requires shifting <em>every row.</em> This is unacceptable.</p>
<p>Instead, let’s bust out the trusty <code>vector</code> library, with its <span class="math inline">\(O(1)\)</span> indexing. This way,
rather than represent the current focus directly in the structure of the data as we did with <code>Z</code>,
we’ll store an index.</p>
<p>Sounds like I lied, right? Whatever happened to the “grids without indices”?
As an unfortunate consequence of desiring efficiency, our <code>Grid</code> module will house a few index
calculations, but the actual application logic that solves the problem will not. So I only
half-lied.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Grid</span> <span class="kw">where</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">G</span> a <span class="ot">=</span> <span class="dt">G</span> <span class="op">!</span>(<span class="dt">Vector</span> (<span class="dt">Vector</span> a)) <span class="op">!</span><span class="dt">Int</span> <span class="op">!</span><span class="dt">Int</span> <span class="co">-- row and column indices</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="ot">out ::</span> <span class="dt">G</span> a <span class="ot">-&gt;</span> <span class="dt">Vector</span> (<span class="dt">Vector</span> a)</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>out (<span class="dt">G</span> v _ _) <span class="ot">=</span> v</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>width,<span class="ot"> height ::</span> <span class="dt">G</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>width (<span class="dt">G</span> v _ _) <span class="ot">=</span> V.length (v <span class="op">V.!</span> <span class="dv">0</span>)</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>height (<span class="dt">G</span> v _ _) <span class="ot">=</span> V.length v</span></code></pre></div>
<p>Next, we need to write <code>Comonad</code> instance for <code>G</code> – this is the interesting part.</p>
<ul>
<li><code>extract :: G a -&gt; a</code> will use the underlying vectors’ indexing to obtain the focused element.</li>
<li><code>duplicate :: G a -&gt; G (G a)</code> will construct a grid of grids. This sounds like it will absolutely
explode the memory usage of the program, but in fact, the underlying grid we start with will be
shared unchanged among all the new <code>G</code> objects we’ll create. These objects will merely differ in
which element is focused, i.e. in what indices they store.</li>
<li><code>extend :: (G a -&gt; b) -&gt; G a -&gt; G b</code> will function as a fusion of <code>duplicate</code> together with an
<code>fmap</code> of the transformation.</li>
</ul>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Comonad</span> <span class="dt">G</span> <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  extract (<span class="dt">G</span> v i j) <span class="ot">=</span> v <span class="op">V.!</span> i <span class="op">V.!</span> j</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  duplicate g<span class="op">@</span>(<span class="dt">G</span> v i j) <span class="ot">=</span> <span class="dt">G</span> v&#39; i j <span class="kw">where</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    v&#39; <span class="ot">=</span> V.generate (height g) <span class="op">$</span> \i <span class="ot">-&gt;</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>      V.generate (width g) <span class="op">$</span> \j <span class="ot">-&gt;</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>        <span class="dt">G</span> v i j</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>  extend f g<span class="op">@</span>(<span class="dt">G</span> v i j) <span class="ot">=</span> <span class="dt">G</span> v&#39; i j <span class="kw">where</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    v&#39; <span class="ot">=</span> V.generate (height g) <span class="op">$</span> \i <span class="ot">-&gt;</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>      V.generate (width g) <span class="op">$</span> \j <span class="ot">-&gt;</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>        f (<span class="dt">G</span> v i j)</span></code></pre></div>
<p>Although we could define <code>extend f = fmap f . duplicate</code>, I’m unsure of whether this will fuse away
the intermediate grid. Better safe than sorry.</p>
<p>Finally, our Grid module will be complete with some functions for moving the focus around, either
absolutely or relatively.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">seek ::</span> <span class="dt">G</span> a <span class="ot">-&gt;</span> (<span class="dt">Int</span>, <span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">G</span> a)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>seek g<span class="op">@</span>(<span class="dt">G</span> v _ _) (i, j)</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dv">0</span> <span class="op">&lt;=</span> i <span class="op">&amp;&amp;</span> i <span class="op">&lt;</span> height g</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">&amp;&amp;</span> <span class="dv">0</span> <span class="op">&lt;=</span> j <span class="op">&amp;&amp;</span> j <span class="op">&lt;</span> width g <span class="ot">=</span> <span class="dt">Just</span> (<span class="dt">G</span> v i j)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="ot">move ::</span> <span class="dt">G</span> a <span class="ot">-&gt;</span> (<span class="dt">Int</span>, <span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">G</span> a)</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>move (<span class="dt">G</span> v i j) (di, dj) <span class="ot">=</span> seek (<span class="dt">G</span> v i j) (di <span class="op">+</span> i, dj <span class="op">+</span> j)</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- the 8 relative offsets for the neighbourhood of interest</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>dir8 <span class="ot">=</span> [(<span class="op">-</span><span class="dv">1</span>, <span class="op">-</span><span class="dv">1</span>), (<span class="op">-</span><span class="dv">1</span>, <span class="dv">0</span>), (<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>), (<span class="dv">0</span>, <span class="dv">1</span>), (<span class="dv">1</span>, <span class="dv">1</span>), (<span class="dv">1</span>, <span class="dv">0</span>), (<span class="dv">1</span>, <span class="op">-</span><span class="dv">1</span>), (<span class="dv">0</span>, <span class="op">-</span><span class="dv">1</span>)]</span></code></pre></div>
<p>Now we’re ready to tackle solving part 1 of the coding challenge. Remember, we want to count the
<code>@</code>s that have fewer than 4 <code>@</code>s in the 8-square neighbourhood around them. We encode this as a
predicate <code>G Cell -&gt; Bool</code> that decides whether the focused cell of the grid is an accessible <code>@</code>.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Cell</span> <span class="ot">=</span> <span class="dt">Empty</span> <span class="op">|</span> <span class="dt">Full</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> <span class="dt">Enum</span> <span class="co">-- to convert Empty to 0 and Full to 1</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="co">-- Is the focused cell an accessible roll of paper?</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="ot">accessible ::</span> <span class="dt">G</span> <span class="dt">Cell</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>accessible g</span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Full</span> <span class="ot">&lt;-</span> extract g <span class="ot">=</span> (<span class="op">&lt;</span> <span class="dv">4</span>) <span class="op">.</span> <span class="fu">sum</span> <span class="op">$</span> <span class="fu">maybe</span> <span class="dv">0</span> (<span class="fu">fromEnum</span> <span class="op">.</span> extract) <span class="op">.</span> move g <span class="op">&lt;$&gt;</span> dir8</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">False</span></span></code></pre></div>
<ul>
<li><code>move g &lt;$&gt; dir8</code> moves in all 8 relative directions given by the list <code>dir8</code>. Since this could
go out of bounds, each result in wrapped with <code>Maybe</code>.</li>
<li><code>maybe 0 (fromEnum . extract)</code> converts a single result into <code>1</code> only if the movement was in
bounds and then focuses on an <code>@</code>.</li>
</ul>
<p>With this predicate defined, we can finally express the solution to part 1.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">part1 ::</span> <span class="dt">Vector</span> (<span class="dt">Vector</span> <span class="dt">Cell</span>) <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>part1 v <span class="ot">=</span> go (<span class="dt">G</span> v <span class="dv">0</span> <span class="dv">0</span>) <span class="kw">where</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>    go <span class="ot">=</span> <span class="fu">sum</span> <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">sum</span> <span class="op">.</span> out <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">fromEnum</span> <span class="op">.</span> extend accessible</span></code></pre></div>
<ul>
<li><code>extend accessible</code> gives us a grid of booleans each saying whether the cell at the corresponding
position is an accessible <code>@</code>.</li>
<li><code>fmap fromEnum</code> changes the booleans into integers.</li>
<li><code>sum . fmap sum . out</code> throws out the focus and adds everything up.</li>
</ul>
<p>While we’re here, we may as well do part2. It’s not much harder. We’re asked to repeatedly remove
all accessible <code>@</code>s from the grid, counting how many we remove in total.</p>
<p>To solve this, let’s express a new contextual computation that builds on <code>accessible</code>. Rather than
merely map to a boolean, we’ll map to a tuple consisting of a count (zero or one) and a new value
for the cell under focus. I have no good name for this, so let’s use a greek letter.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>rho g <span class="ot">=</span> <span class="kw">if</span> accessible g <span class="kw">then</span> (<span class="dv">1</span>, <span class="dt">Empty</span>) <span class="kw">else</span> (<span class="dv">0</span>, extract g)</span></code></pre></div>
<p>Applying this everywhere in the grid via <code>extend</code> will give us a grid of tuples. We’ll unzip this
to get a grid of ones and zeros – we add them up to get the count of removed <code>@</code>s – and a new
grid with fewer <code>@</code>s in it.</p>
<p>Then, it suffices to iterate this process to produce an infinite stream of counts of removed <code>@</code>s
in each iteration. This stream will eventually reach zero, staying there forever, so we’ll take the
nonzero prefix and add that all up.</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">part2 ::</span> <span class="dt">Vector</span> (<span class="dt">Vector</span> <span class="dt">Cell</span>) <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>part2 v <span class="ot">=</span> go (<span class="dt">G</span> v <span class="dv">0</span> <span class="dv">0</span>) <span class="kw">where</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>    go <span class="ot">=</span> <span class="fu">sum</span> <span class="op">.</span> <span class="fu">takeWhile</span> (<span class="op">&gt;</span> <span class="dv">0</span>) <span class="op">.</span> unfoldr (<span class="dt">Just</span> <span class="op">.</span> phi) <span class="kw">where</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>        phi <span class="ot">=</span> first (<span class="fu">sum</span> <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">sum</span> <span class="op">.</span> out) <span class="op">.</span> funzip <span class="op">.</span> extend rho</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>funzip f <span class="ot">=</span> (<span class="fu">fst</span> <span class="op">&lt;$&gt;</span> f, <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> f)</span></code></pre></div>
<p>See, I promised there would be no indices in the solution, and I delivered! The resulting solution
crucially uses <code>extend</code> to apply a contextually-aware transformation everywhere in the grid. All
index manipulation is relegated to the Grid module’s <code>jump</code> function. Overall, I find that this
approach to solving problems about grids to be delightfully declarative. Sometimes it’s really just
a matter of finding the right abstraction.</p>
<p>P.S.</p>
<p>I originally did most of this development using Haskell’s quasi-dependent types. This was necessary
in order to use a <a href="https://hackage-content.haskell.org/package/adjunctions-4.4.3/docs/Control-Comonad-Representable-Store.html">store comonad parameterized by a representable
functor</a>.
Phew. I used this Store comonad because of its touted ability to memoize results. The generality of
this technique cut against me, however, as it required me to find a type to serve as an index into
the grid. <code>(Int, Int)</code> didn’t cut it, because of the further requirement that there be no “out of
bounds” values in the index type. Well this is where the dependent types came in. I decided to use
bounded natural numbers as indices. This did actually give a workable solution, but it was all
quite disgusting.</p>
<p>It hit me a little later that I didn’t need to use this highly general machinery. I could just
define a Comonad instance myself for a 2D vector + coordinates, so that’s the approach that ended
up in this article.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Refunctionalizing an integer?</title>
    <link href="https://jerrington.me/posts/2025-10-19-refunctionalizing-an-integer.html" />
    <id>https://jerrington.me/posts/2025-10-19-refunctionalizing-an-integer.html</id>
    <published>2025-10-19T00:00:00Z</published>
    <updated>2025-10-19T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on October 19, 2025
    
</div>

<p>First imagine that the OCaml type <code>int</code> is infinite. Now what happens when you refunctionalize an
infinite datatype?</p>
<p>Let make a concrete program to work with. This will be a stateful generator that outputs the
integers, starting at <code>0</code>, and ending at an exclusive limit <code>n</code>.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> &#39;a gen = { next : <span class="dt">unit</span> -&gt; &#39;a <span class="dt">option</span> }</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> range n =</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> r = <span class="dt">ref</span> <span class="dv">0</span> <span class="kw">in</span> {</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>        next = <span class="kw">fun</span> () -&gt;</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> i = !r <span class="kw">in</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> i &lt; n <span class="kw">then</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Some</span> (r := i+<span class="dv">1</span>; i)</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>                <span class="dt">None</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div>
<p>This program stores an integer in a reference cell, and branches on it to produce two different
behaviours. Our goal is to replace the integer in the cell with a function in the cell that will
just do the right thing (i.e. perform the right one of these two behaviours) without needing to
branch on the integer to decide what to do.</p>
<p>We will need to store some initial function inside the reference. This function, when called, needs
to emit <code>0</code> and also update its own reference cell to be the function that will emit <code>1</code>. But this
new function must also do more: when <em>it’s</em> called it also needs to update its own reference to be
the function that emits <code>2</code>, and so on.</p>
<p>So I lied: we’re not going to <em>get rid</em> of the integer, as we would expect from a standard
r17n. We just won’t be storing it directly. We’ll be storing it indirectly, somehow.</p>
<p>To see how we’ll store this integer, let’s begin translating the function, leaving blanks for the
parts we aren’t sure about yet.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> range n =</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> r = <span class="dt">ref</span> (<span class="kw">fun</span> () -&gt; ???; <span class="dv">0</span>) <span class="kw">in</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    { next = <span class="kw">fun</span> () -&gt; !r () }</span></code></pre></div>
<p>What must go in the question marks is our logic to update the reference cell to be the “next”
function in the sequence. Let’s encapsulate this update logic into a function <code>update</code>. Crucially
this function will take an integer as input, to identify the next function in the sequence. To
identify the next function to store, the update function must decide whether the real sequence, of
integers, is finished. In that case, it stores a function that simply outputs <code>None</code>. If the
real sequence isn’t finished, then <code>update</code> must store a function that will contain a recursive
call to <code>update</code>, but on the next integer.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> range n =</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> r = <span class="dt">ref</span> (<span class="kw">fun</span> () -&gt; update <span class="dv">1</span>; <span class="dv">0</span>)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">and</span> update i =</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> i &lt; n <span class="kw">then</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>            r := <span class="kw">fun</span> () -&gt; update (i+<span class="dv">1</span>); <span class="dt">Some</span> i</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>            r := <span class="kw">fun</span> () -&gt; <span class="dt">None</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    { next = <span class="kw">fun</span> () -&gt; !r () }</span></code></pre></div>
<p>There is a slight issue with this implementation: it’s incorrect on an edge case. How about <code>range 0</code>? This generator should start out by returning <code>None</code>, but our implementation would have any
generator constructed from <code>range n</code> begin by emitting <code>0</code> unconditionally.</p>
<p>The insight we need to patch this up is to recognize that we can make the initial function stored
in the reference cell begin by calling <code>update 0</code>. This will check whether <code>0</code> is in bounds before
proceeding to store the appropriate function in the reference. Therefore, our new initial function,
after calling <code>update 0</code>, can then dereference <code>r</code> to obtain the <em>new</em> handler, for the <code>0</code> case,
and call it.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> range n =</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> r = <span class="dt">ref</span> (<span class="kw">fun</span> () -&gt; update <span class="dv">0</span>; !r ())</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">and</span> update i =</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> i &lt; n <span class="kw">then</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>            r := <span class="kw">fun</span> () -&gt; update (i+<span class="dv">1</span>); <span class="dt">Some</span> i</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>            r := <span class="kw">fun</span> () -&gt; <span class="dt">None</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    { next = <span class="kw">fun</span> () -&gt; !r () }</span></code></pre></div>
<p>Indeed, the integer is still alive and well, but it isn’t what we store in the reference cell
anymore, at least not directly. Instead, we store the closure <code>fun () -&gt; update (i+1); Some i</code>,
which has captured the integer <code>i</code>.</p>
<p>Did our transformation in any way <em>improve</em> the program we wrote? No way. But you have to agree,
there’s something mysterious and exciting about using a mutable variable to store a recursive
function that updates the mutable variable that houses that function.</p>
<p>Getting back to the title of this post now, did we really refunctionalize an integer? I’d actually
say we did. R17n would have us write down one function for each of the values in the first-order
datatype we’re refunctionalizing. Doing this for a datatype with several billion values, like the
integers, is practically infeasible. However, since there were just two <em>behaviours,</em> depending on
the relationship between the index <code>i</code> and the limit <code>n</code>, there are really just two different
functions we need to store. One of those is <code>fun () -&gt; None</code>, and the other is <code>fun () -&gt; update (i+1); Some i</code>. This latter code snippet, having a free variable <code>i</code>, actually determines a
<em>family</em> of functions indexed by <code>i</code>. For a fixed limit <code>n</code>, we implemented the function <code>update</code>
that maps each integer to a function that simulates the behaviour in the original program.</p>
<p>Taking a more general stance, when we attempt to refunctionalize a datatype with
infinitely many values – or with so many values that we can approximate the count to be infinite
– we end up needing to describe a systematic way of translating each of the values into a
corresponding function. In other words, we implement a function to translate each value into its
refunctionalized form.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Implementing dependent types: how hard could it be? (Part 2)</title>
    <link href="https://jerrington.me/posts/2025-07-31-depty-impl-part-2.html" />
    <id>https://jerrington.me/posts/2025-07-31-depty-impl-part-2.html</id>
    <published>2025-07-31T00:00:00Z</published>
    <updated>2025-07-31T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on July 31, 2025
    
</div>

<p>Short answer: hard, but not as hard as I thought.</p>
<p>This is part 2 of a series of posts on the implementation of a dependently-typed lambda-calculus.
In part 1, we discussed the need for normalization of terms, and used a powerful, extensible
approach called Normalization by Evaluation to implement a normalization procedure.
In this post, we’ll implement the typechecking procedure for our small calculus, and crucially use
the normalization procedure to do.</p>
<h2 id="bidirectional-typechecking">Bidirectional typechecking</h2>
<p>Bidirectional typechecking is a technique that exploits a duality within terms to reduce the amount
of typing information required from the programmer. We divide the syntax of terms into <em>normal
terms</em> and <em>neutral terms,</em> precisely as we did for values, giving a syntactic characterization of
beta-normal terms.</p>
<ul>
<li><strong>Normal terms</strong> are associated with <em>constructors</em> and are those terms whose typechecking is
also type-directed. In other words, we <em>check</em> that a given normal term has a <em>given</em> type.
Normal terms are also sometimes called <em>checkable terms.</em></li>
<li><strong>Neutral terms</strong> are associated with <em>eliminators</em> and are those terms from which their type may
be <em>synthesized.</em> In other words, we <em>infer</em> the type of a neutral term in a given context.
Neutral terms are therefore sometimes called <em>synthesizable</em> or <em>inferrable</em> terms.</li>
</ul>
<p>For example, in order to appropriately extend the context during typechecking, we classify a lambda
abstraction as a normal term. Hence, its type is given, making the context extension
straightforward to compute. In picking apart the given type of the lambda abstraction, we obtain
the expected type of the abstraction’s body, so we equally classify the abstraction body as normal.</p>
<p>Dually, we expect a function application to be neutral. To infer the type of an application, we
first infer the type of its subject – requiring that the function be neutral assures
beta-normality – and insist that the type be a Pi-type <code>(x:A) -&gt; B</code>. This in turn reveals the
expected type <code>A</code> of the function’s argument, so we let the argument be normal.</p>
<p>Here’s a BNF grammar.</p>
<pre><code>Normal terms  t, A, B  ::= λx.t | () | (x:A) -&gt; B | ⊤ | ★ | s
Neutral terms       s  ::= x | s t</code></pre>
<p>This exposition shows intuitively that typechecking beta-normal terms is in some way easier. We
begin by typechecking a normal term against its given type. The term, being a stack of introduction
forms, is structurally aligned with its type. In doing so, we can easily extend the context at
binding sites. Typechecking switches modes into type inference, when the normal term switches to a
neutral term. Information stored in the context comes into play upon encountering a variable, and
furthermore when inferring the type of the subject of a function application.</p>
<p>We express this bimodal typechecking scheme formally using a pair of mutually defined judgments.</p>
<ul>
<li><code>G |- t &lt;= A</code> normal term <code>t</code> checks against given type <code>A</code> in context <code>G</code>.</li>
<li><code>G |- s =&gt; A</code> neutral term <code>s</code> synthesizes type <code>A</code> in context <code>G</code>.</li>
</ul>
<p>These judgments are defined inductively by the following rules. Let’s start with some
straightforward ones.</p>
<pre><code>    G, x:A |- t &lt;= B              G(x) = A
---------------------------    ------------
  G |- λx.t &lt;= (x:A) -&gt; B        G |- x =&gt; A


  G |- t =&gt; (x:A) -&gt; B    G |- t&#39; &lt;= A
--------------------------------------    --------------
         G |- t t&#39; =&gt; [t&#39;/x]B              G |- () &lt;= ⊤

  G |- A &lt;= ★    G, x:A |- B &lt;= ★
---------------------------------     --------------
       G |- (x:A) -&gt; B &lt;= ★              G |- ⊤ &lt;= ★


--------------
  G |- ★ &lt;= ★</code></pre>
<p>Yes, at the bottom there is the type-in-type rule, meaning that the resulting system is unsound.
I’ll explore later how we might introduce universes to address that.</p>
<pre><code> G |- s =&gt; B    G |- A ≡ B : ★
-------------------------------
         G |- s &lt;= A</code></pre>
<p>This rule captures mode-switching, from checking to inference. When we need to check a
synthesizable term against a given type, we synthesize the type of that term before checking that
the expected and actual type are equal as types <code>G |- A ≡ B : ★</code>. In practice, we’ll already have
<code>A</code> and <code>B</code> be in normal form, so the equality check is merely syntactic!</p>
<p>Now it suffices to encode these rules into a pair of functions in OCaml. The hard case will be
function application, as there’s a substitution there and we don’t yet know how to compute those.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> check (cG : ctx) (t : tm) (tA : tp) : <span class="dt">unit</span> =</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> tA, t <span class="kw">with</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    | Star, Top -&gt; <span class="kw">true</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    | Star, Star -&gt; <span class="kw">true</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    | Star, Pi ((x, tA), tB) -&gt;</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>        check cG tA Star;</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>        check ((x, tA)::cG) tB Star</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    | Top, Unit -&gt; <span class="kw">true</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    | Pi ((_x, tA), tB), Lam (x, t) -&gt;</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>        check ((x, tA)::cG) t tB</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>    | tA, s -&gt;</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> tA&#39; = synth cG s <span class="kw">in</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>        <span class="co">(* and now we need to check that tA&#39; = tA *)</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> synth (cG : ctx) (t : tm) : tp =</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">List</span>.nth cG i |&gt; <span class="dt">snd</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>    | App (s, t) -&gt;</span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> synth cG s <span class="kw">with</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>        | Pi ((x, tA), tB) -&gt;</span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>            check cG t tA;</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a>            <span class="co">(* and now we need to compute and return [t/x]tB *)</span></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span></code></pre></div>
<p>In the code above, there are two TODOs to resolve. The first one is easy. We’ll insist that before
the initial call to <code>check</code>, we have already normalized the given type <code>tA</code>. Then, we’ll need to
insist that <code>synth</code> also return a type in normal form. Hence we resolve the first TODO by
performing a syntactic equality check on <code>tA</code> and <code>tA'</code>. If we had used a completely nameless
representation, it would suffice to use OCaml’s built-in equality <code>tA' = tA</code>, but on account of our
compromise of keeping some names, we’ll actually need to implement a <code>tm_eq</code> function that ignores
names. I’ll omit the code of that function.</p>
<p>The second TODO is more sensitive. Even if we assume that <code>t</code> and <code>tB</code> are in normal form, the
result of the substitution <code>[t/x]tB</code> might not be.</p>
<h2 id="substitution">Substitution</h2>
<p>As a first approach, we might implement a function <code>subst : (tm * ix) -&gt; tm -&gt; tm</code> such that <code>subst (t, x) tB</code> computes the substitution <code>[t/x]tB</code>, then use the NbE procedure from part 1 of the
series to normalize.</p>
<p>This first approach sucks for two reasons. First, implementing substitution on nameless terms
requires implementing various shifting (weakening) helpers to account for those situations where
the substitution crosses a binder such as a lambda abstraction. Second, we end up effectively
traversing the term <code>tB</code> <em>three times</em>: once for the substitution, then twice during normalization
(once for <code>eval</code>, and once for <code>quote</code>).</p>
<p>Funny enough, we already implemented a clever substitution procedure that addresses both those
issues! Remember <code>eval</code>? It replaces all free variables in a term with the values held in an
environment. The values in the environment crucially represent variables using de Bruijn <em>levels,</em>
not indices, which gives us weakening for free. No need for any shifting.</p>
<p>It suffices to construct an appropriate environment for the substitution we wish to perform, use
<code>eval</code> to perform it, and use <code>quote</code> to convert back to syntax. We therefore avoid the tricky
business of implementing nameless substitutions entirely, and cut down on the number of term
traversals required.</p>
<p>To build the environment we need, consider that <code>t</code> lives in context <code>cG</code> and <code>tB</code> lives in context
<code>(x, tA)::cG</code> – those contexts tell us how many free variables appear in these terms. We need to
convert the context <code>cG</code> into a ‘dummy environment’ <code>eG</code> that maps each variable back to itself.
Then, we can evaluate <code>t</code> in the environment <code>eG</code> to get a value <code>v</code> to form the
environment <code>(x, v)::eG</code> to finally evaluate <code>tB</code>. This will replace the variable <code>x</code> with <code>v</code>, as
required!</p>
<p>To convert a context into such a ‘dummy environment’, let’s implement <code>ctx2env</code>.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> vvar l = VN (NVar l)</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> ctx2env (cG : ctx) : env * <span class="dt">int</span> = <span class="kw">match</span> cG <span class="kw">with</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    | [] -&gt; ([], <span class="dv">0</span>)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    | (x, _)::cG -&gt;</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> eG, n = ctx2env cG <span class="kw">in</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>        ((x, vvar n)::eG, n+<span class="dv">1</span>)</span></code></pre></div>
<p>In order to ‘count backwards’ to compute the correct levels, <code>ctx2env</code> also computes as a
by-product the length of the context.</p>
<p>Next, let’s fill in the second TODO of the typechecker, following the gameplan I outlined above.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> check (cG : ctx) (t : tm) (tA : tp) : <span class="dt">unit</span> = ...</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> synth (cG : ctx) (t : tm) : tp =</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">List</span>.nth cG i</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    | App (s, t) -&gt;</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> synth cG s <span class="kw">with</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>        | Pi ((x, tA), tB) -&gt;</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>            check cG t tA;</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> eG, n = ctx2env cG <span class="kw">in</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> v = eval eG t <span class="kw">in</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> vB = eval ((x, v)::eG) tB <span class="kw">in</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>            <span class="co">(* </span><span class="al">TODO</span><span class="co">: `quote vB` *)</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span></code></pre></div>
<p>Quoting <code>vB</code> is a bit tricky. Recall from part 1 that quoting is type-directed, so we need to
supply the type at which we’re quoting, and a typing environment that maps each free variable to
its semantic type. We needed this typing information in order to perform correct eta-expansion.</p>
<p>The type at which we’re quoting is easy. Since we’re quoting a type, we’re quoting <em>at type</em>
<code>VStar</code>. The typing environment, on the other hand, is harder to come by. We need to evaluate each
of the types in <code>cG</code>. But then each entry in cG lives in the subcontext of remaining entries. Yuck.
Let’s implement a helper <code>ctx2tyenv</code> that can at least leverage the <code>eG</code> we already computed.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> ctx2tyenv (cG : ctx) (eG : env) : tp_env =</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> cG, eG <span class="kw">with</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    | [], [] -&gt; []</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    | (x, tA)::cG, _::eG -&gt;</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>        <span class="co">(* cG |- tA : ★</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="co">           and eG is the dummy env of cG *)</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> vA = eval eG tA <span class="kw">in</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>        (x, vA) :: ctx2tyenv cG eG</span></code></pre></div>
<p>Finally we can quote <code>vB</code>.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> check (cG : ctx) (t : tm) (tA : tp) : <span class="dt">unit</span> = ...</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> synth (cG : ctx) (t : tm) : tp =</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">List</span>.nth cG i</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    | App (s, t) -&gt;</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> synth cG s <span class="kw">with</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        | Pi ((x, tA), tB) -&gt;</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>            check cG t tA;</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> eG, n = ctx2env cG <span class="kw">in</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> v = eval eG t <span class="kw">in</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> vB = eval ((x, v)::eG) tB <span class="kw">in</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>            quote n (ctx2tyenv cG eG) VStar vB</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>        | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;ill-typed: application subject not a function&quot;</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span></code></pre></div>
<p>Unfortunately, this approach merely trades one inefficiency for another.</p>
<p>Stop and consider for a moment that applications are often nested. This means what the subterm <code>s</code>
is likely to be yet another application. We end up repeatedly calling <code>ctx2env</code> and <code>ctx2tyenv</code> on
the same context <code>cG</code>, meaning we repeatedly evaluate the types in that context.</p>
<p>Moreover, in the event of nested applications, notice that we quote <code>vB</code> only to get back another
Pi-type on whose subterms we would then redundantly <code>eval</code> again!</p>
<h2 id="leaning-on-the-semantics">Leaning on the semantics</h2>
<p>Rather than repeatedly convert back and forth from syntax into semantics, we could instead work
more closely with the semantics. For instance, recall that we imposed a precondition on <code>check</code>,
that the given type would be in normal form. In that case, let’s not take the type as a syntactic
<code>tp</code>, but rather as a semantic <code>vtp</code>, which we designed to capture only beta-normal forms anyway.
Likewise, the context ought to only store types in normal form, too, so why not just use a <code>tp_env</code>
instead of a <code>ctx</code>? And finally, if <code>synth</code> should output a type in normal form, again let’s output
a <code>vtp</code> instead.</p>
<p>Crucially, the only one that remains as a raw, syntactic term is the term under consideration for
checking or synthesis. What’s more, that’s the only term we <strong>can’t</strong> evaluate first, as we don’t
yet know whether it’s well-typed!</p>
<p>Besides representing everything that ought to be in normal form as a value, we’ll also want to
avoiding using <code>ctx2env</code> to generate the ‘dummy’ environment we need when calling <code>eval</code> during
typechecking. To do so, the typechecker will also track a dummy environment. Whenever it goes under
a binder, we will extend not only the typing environment but also the dummy environment. To extend
the dummy environment, we need to generate a new variable whose level is the current length of the
dummy environment. To avoid computing this length, we’ll also track it as we go.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> check (d : lvl) (e : env) (eG : tp_env) (t : tm) (vA : vtp) : <span class="dt">unit</span> =</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> vA, t <span class="kw">with</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    | VStar, Top -&gt; ()</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    | VStar, Star -&gt; ()</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    | VStar, Pi ((x, tA), tB) -&gt;</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>        check d e eG tA VStar;</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> vA = eval e tA <span class="kw">in</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>        check (d+<span class="dv">1</span>) ((x, vvar d)::e) ((x, vA)::eG) tB VStar</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>    | VTop, Unit -&gt; ()</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>    | VPi ((_, vA), fB), Lam (x, t) -&gt;</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>        check (d+<span class="dv">1</span>) ((x, vvar d)::e) ((x, vA)::eG) t (fB (vvar d))</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>    | vA, s -&gt;</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> vA&#39; = synth d eG s <span class="kw">in</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> tA = quote d eG VStar vA <span class="kw">in</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> tA&#39; = quote d eG VStar vA&#39; <span class="kw">in</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="dt">not</span> (tm_eq tA tA&#39;) <span class="kw">then</span> <span class="dt">failwith</span> <span class="st">&quot;type mismatch&quot;</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> synth (d : lvl) (e : env) (eG : tp_env) (t : tm) : vtp =</span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">List</span>.nth eG i |&gt; <span class="dt">snd</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>    | App (s, t) -&gt;</span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> synth d e eG s <span class="kw">with</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a>        | VPi ((x, vA), fB) -&gt;</span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>            check d e eG t vA;</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> v = eval e t <span class="kw">in</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a>            fB v</span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>        | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;ill-typed: application subject not a function&quot;</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;cannot synthesize type of checkable term&quot;</span></span></code></pre></div>
<p>There are two things that remain a bit unpleasant about this implementation. In the last case of
<code>check</code>, we need to check that <code>vA</code> equals <code>vA'</code>, and we do so by quoting both and comparing as
terms. It’s a bit wasteful to <em>fully</em> quote both values if it turns out they aren’t equal though.
When they <em>are</em> equal, we still end up performing three traversals: once for each quote, and once
more for <code>tm_eq</code>.</p>
<p>We can do better by implementing an equality procedure directly on values. Essentially, the
procedure does the job of quoting (and hence eta-expanding) both values as long as they match,
stopping early as soon as it detects that they don’t.</p>
<p>Since we need to maintain typing information along the way (to support eta-expansion), the
implementation will follow the normal/neutral split into a pair of mutually recursion functions
<code>val_eq</code> and <code>neu_eq</code>, with <code>neu_eq</code> synthesizing a type.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> val_eq (d : lvl) (eG : tp_env) (v1 : value) (v2 : value) (vA : vtp) : <span class="dt">bool</span> =</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> vA, v1, v2 <span class="kw">with</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    | VStar, VTop, VTop -&gt; <span class="kw">true</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    | VStar, VStar, VStar -&gt; <span class="kw">true</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    | VTop, VUnit, VUnit -&gt; <span class="kw">true</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    | VStar, VPi ((x1, vA1), fB1), VPi ((x2, vA2), fB2) -&gt;</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> v = vvar d <span class="kw">in</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>        val_eq d eG vA1 vA2 VStar &amp;&amp; val_eq (d+<span class="dv">1</span>) ((x1, vA1)::eG) (fB1 v) (fB2 v) VStar</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    | VPi ((x, vA), fB), v1, v2 -&gt; <span class="co">(* handles eta-expansion *)</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> v = vvar d <span class="kw">in</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>        val_eq (d+<span class="dv">1</span>) ((x, vA)::eG) (apply v1 v) (apply v2 v) (fB v)</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>        <span class="co">(* using `apply` to either reduce an application of a lambda or to extend the stack of</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a><span class="co">           neutral terms *)</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>    | vA, VN n1, VN n2 -&gt;</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> neu_eq d eG n1 n2 <span class="kw">with</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">Some</span> _ -&gt; <span class="kw">true</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">None</span> -&gt; <span class="kw">false</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="kw">false</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a><span class="co">(* checking equality of neutral terms needs to compute a type as output, so we use `vtp option` as</span></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a><span class="co">an output type to represent &quot;yes they&#39;re equal and here&#39;s their type&quot; or &quot;no they&#39;re not equal&quot;. *)</span></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> neu_eq (d : lvl) (eG : tp_env) (n1 : neu) (n2 : neu) : vtp <span class="dt">option</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> n1, n2 <span class="kw">with</span></span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a>    | NVar l1, NVar l2 <span class="kw">when</span> l1 = l2 = <span class="dt">Some</span> (<span class="dt">List</span>.nth (lvl2ix d l1) eG)</span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a>    | NApp (n1, v1), NApp (n2, v2) -&gt;</span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> neu_eq d eG n1 n2 <span class="kw">with</span></span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">Some</span> (VPi ((x, vA), fB)) -&gt;</span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> val_eq d eG v1 v2 vA <span class="kw">then</span></span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Some</span> (fB v1)</span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span></span>
<span id="cb10-32"><a href="#cb10-32" aria-hidden="true" tabindex="-1"></a>                <span class="dt">None</span></span>
<span id="cb10-33"><a href="#cb10-33" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">Some</span> _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;impossible: inputs of neu_eq are ill-typed&quot;</span></span>
<span id="cb10-34"><a href="#cb10-34" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">None</span> -&gt; <span class="dt">None</span></span>
<span id="cb10-35"><a href="#cb10-35" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb10-36"><a href="#cb10-36" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">None</span></span></code></pre></div>
<p>Now we can rewrite <code>check</code> to use this procedure.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> check (d : lvl) (eG : tp_env) (t : tm) (vA : vtp) : <span class="dt">unit</span> =</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> vA, t <span class="kw">with</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* ... *)</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    | vA, s -&gt;</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> vA&#39; = synth d eG s <span class="kw">in</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="dt">not</span> (val_eq d eG vA vA&#39; VStar) <span class="kw">then</span> <span class="dt">failwith</span> <span class="st">&quot;type mismatch&quot;</span></span></code></pre></div>
<p>Much better.</p>
<p>Then there’s just one thing left to reflect on in the implementation.</p>
<h3 id="checking-and-evaluating-at-once">Checking and evaluating at once?</h3>
<p>In our implementation of <code>check</code> and <code>synth</code>, there are two places where we typecheck a subterm
right before we evaluate it, both involving Pi-types. This begs the question, could we not fuse the
typechecking and evaluation procedures together, to at least handle those cases?</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (<span class="kw">let</span><span class="er">*)</span> x f = Option.bind</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> eval_check (d : lvl) (eG : tp_env) (e : env) (t : tm) (vA : vtp) : value <span class="dt">option</span> =</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> vA, t <span class="kw">with</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    | VStar, Top -&gt; <span class="dt">Some</span> VTop</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    | VStar, Star -&gt; <span class="dt">Some</span> VStar</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    | VStar, Pi ((x, tA), tB) -&gt;</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span>* vA = eval_check d eG e tA VStar <span class="kw">in</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span>* _ = eval_check (d+<span class="dv">1</span>) ((x, vA)::eG) ((x, vvar d)::e) tB VStar <span class="kw">in</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Some</span> (VPi ((x, vA), <span class="kw">fun</span> v -&gt; eval (v::e) tB))</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>    | VTop, Unit -&gt; VUnit</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>    | VPi ((_, vA), fB), Lam (x, t) -&gt;</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span>* _ = eval_check (d+<span class="dv">1</span>) ((x, vA)::eG) ((x, vvar d)::e) t (fB (vvar d)) <span class="kw">in</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Some</span> (VLam (x, <span class="kw">fun</span> v -&gt; eval (v::e) t))</span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a>    | vA, s -&gt;</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span>* v, vA&#39; = eval_synth d eG e s <span class="kw">in</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> val_eq d eG vA vA&#39; VStar <span class="kw">then</span></span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Some</span> v</span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a>            <span class="dt">None</span></span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> eval_synth (d : lvl) (eG : tp_env) (e : env) (t : tm) : (value * vtp) <span class="dt">option</span> =</span>
<span id="cb12-22"><a href="#cb12-22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb12-23"><a href="#cb12-23" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">Some</span> (<span class="dt">List</span>.nth e i, <span class="dt">List</span>.nth eG i)</span>
<span id="cb12-24"><a href="#cb12-24" aria-hidden="true" tabindex="-1"></a>    | App (s, t) -&gt;</span>
<span id="cb12-25"><a href="#cb12-25" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> eval_synth d eG e s <span class="kw">with</span></span>
<span id="cb12-26"><a href="#cb12-26" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">Some</span> (v1, VPi ((x, vA), fB)) -&gt;</span>
<span id="cb12-27"><a href="#cb12-27" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span>* v2 = eval_check d eG e t vA <span class="kw">in</span></span>
<span id="cb12-28"><a href="#cb12-28" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Some</span> (apply v1 v2, fB v2)</span>
<span id="cb12-29"><a href="#cb12-29" aria-hidden="true" tabindex="-1"></a>        | _ -&gt; <span class="dt">None</span> <span class="co">(* application subject not a function *)</span></span>
<span id="cb12-30"><a href="#cb12-30" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb12-31"><a href="#cb12-31" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">None</span> <span class="co">(* trying to synthesize from a checkable term *)</span></span>
<span id="cb12-32"><a href="#cb12-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-33"><a href="#cb12-33" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> apply v1 v2 = <span class="kw">match</span> v1 <span class="kw">with</span></span>
<span id="cb12-34"><a href="#cb12-34" aria-hidden="true" tabindex="-1"></a>    | VN n -&gt; VN (NApp (n, v2))</span>
<span id="cb12-35"><a href="#cb12-35" aria-hidden="true" tabindex="-1"></a>    | VLam (_, f) -&gt; f v2</span>
<span id="cb12-36"><a href="#cb12-36" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;runtime type error: application subject not a function&quot;</span></span></code></pre></div>
<p>This is not an improvement. The point of typechecking is that it’s <em>static</em> – we don’t want to run
the program when we typecheck it. Running the program typically takes significantly longer than
merely typechecking it. In the presence of dependent types, we <em>unfortunately</em> have to run some
parts of the program, to do normalization, but that doesn’t mean we should go farther and insist on
running the entire program.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Of the surveyed implementations, the strategy that leans on the semantics avoids the back-and-forth
between syntax and semantics, while also limiting evaluation to only those subterms required as
dependencies in types.</p>
<p>Let’s recap that implementation in full, here.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ix = <span class="dt">int</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> tm =</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* terms *)</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    | Lam <span class="kw">of</span> name * tm</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    | Var <span class="kw">of</span> ix</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    | App <span class="kw">of</span> tm * tm</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>    | Unit</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* types *)</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>    | Pi <span class="kw">of</span> (name * tp) * tp</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>    | Top</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>    | Star</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> tp = tm <span class="co">(* to understand a term as a type *)</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> ctx = (name * tp) <span class="dt">list</span></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> value =</span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>    | VLam <span class="kw">of</span> name * (value -&gt; value)</span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>    | VUnit</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a>    | VPi <span class="kw">of</span> (name * vtp) * (value -&gt; vtp)</span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a>    | VTop</span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a>    | VStar</span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a>    | VN <span class="kw">of</span> neu <span class="co">(* neutral terms embed as values *)</span></span>
<span id="cb13-23"><a href="#cb13-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-24"><a href="#cb13-24" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> neu =</span>
<span id="cb13-25"><a href="#cb13-25" aria-hidden="true" tabindex="-1"></a>    | NVar <span class="kw">of</span> lvl</span>
<span id="cb13-26"><a href="#cb13-26" aria-hidden="true" tabindex="-1"></a>    | NApp <span class="kw">of</span> neu * value</span>
<span id="cb13-27"><a href="#cb13-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-28"><a href="#cb13-28" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> lvl = <span class="dt">int</span></span>
<span id="cb13-29"><a href="#cb13-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-30"><a href="#cb13-30" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> env = value <span class="dt">list</span></span>
<span id="cb13-31"><a href="#cb13-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-32"><a href="#cb13-32" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> eval (e : env) (t : tm) : value =</span>
<span id="cb13-33"><a href="#cb13-33" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb13-34"><a href="#cb13-34" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* types: *)</span></span>
<span id="cb13-35"><a href="#cb13-35" aria-hidden="true" tabindex="-1"></a>    | Top -&gt; VTop</span>
<span id="cb13-36"><a href="#cb13-36" aria-hidden="true" tabindex="-1"></a>    | Star -&gt; VStar</span>
<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a>    | Pi ((x, tA), tB) -&gt; VPi (eval e tA, (x, <span class="kw">fun</span> v -&gt; eval (v::e) tB))</span>
<span id="cb13-38"><a href="#cb13-38" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* terms: *)</span></span>
<span id="cb13-39"><a href="#cb13-39" aria-hidden="true" tabindex="-1"></a>    | Unit -&gt; VUnit</span>
<span id="cb13-40"><a href="#cb13-40" aria-hidden="true" tabindex="-1"></a>    | Lam (x, t) -&gt; VLam (x, <span class="kw">fun</span> v -&gt; eval (v::e) t)</span>
<span id="cb13-41"><a href="#cb13-41" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">List</span>.nth e i</span>
<span id="cb13-42"><a href="#cb13-42" aria-hidden="true" tabindex="-1"></a>    | App (t1, t2) -&gt; apply (eval e t1) (eval e t2)</span>
<span id="cb13-43"><a href="#cb13-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-44"><a href="#cb13-44" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> apply v1 v2 = <span class="kw">match</span> v1 <span class="kw">with</span></span>
<span id="cb13-45"><a href="#cb13-45" aria-hidden="true" tabindex="-1"></a>    | VN n -&gt; VN (NApp (n, v2))</span>
<span id="cb13-46"><a href="#cb13-46" aria-hidden="true" tabindex="-1"></a>    | VLam (_, f) -&gt; f v2</span>
<span id="cb13-47"><a href="#cb13-47" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;type error&quot;</span></span>
<span id="cb13-48"><a href="#cb13-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-49"><a href="#cb13-49" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> tp_env = env</span>
<span id="cb13-50"><a href="#cb13-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-51"><a href="#cb13-51" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> vvar l = VN (NVar l)</span>
<span id="cb13-52"><a href="#cb13-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-53"><a href="#cb13-53" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> val_eq (d : lvl) (eG : tp_env) (v1 : value) (v2 : value) (vA : vtp) : <span class="dt">bool</span> =</span>
<span id="cb13-54"><a href="#cb13-54" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> vA, v1, v2 <span class="kw">with</span></span>
<span id="cb13-55"><a href="#cb13-55" aria-hidden="true" tabindex="-1"></a>    | VStar, VTop, VTop -&gt; <span class="kw">true</span></span>
<span id="cb13-56"><a href="#cb13-56" aria-hidden="true" tabindex="-1"></a>    | VStar, VStar, VStar -&gt; <span class="kw">true</span></span>
<span id="cb13-57"><a href="#cb13-57" aria-hidden="true" tabindex="-1"></a>    | VTop, VUnit, VUnit -&gt; <span class="kw">true</span></span>
<span id="cb13-58"><a href="#cb13-58" aria-hidden="true" tabindex="-1"></a>    | VStar, VPi ((x1, vA1), fB1), VPi ((x2, vA2), fB2) -&gt;</span>
<span id="cb13-59"><a href="#cb13-59" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> v = vvar d <span class="kw">in</span></span>
<span id="cb13-60"><a href="#cb13-60" aria-hidden="true" tabindex="-1"></a>        val_eq d eG vA1 vA2 VStar &amp;&amp; val_eq (d+<span class="dv">1</span>) ((x1, vA1)::eG) (fB1 v) (fB2 v) VStar</span>
<span id="cb13-61"><a href="#cb13-61" aria-hidden="true" tabindex="-1"></a>    | VPi ((x, vA), fB), v1, v2 -&gt; <span class="co">(* handles eta-expansion *)</span></span>
<span id="cb13-62"><a href="#cb13-62" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> v = vvar d <span class="kw">in</span></span>
<span id="cb13-63"><a href="#cb13-63" aria-hidden="true" tabindex="-1"></a>        val_eq (d+<span class="dv">1</span>) ((x, vA)::eG) (apply v1 v) (apply v2 v) (fB v)</span>
<span id="cb13-64"><a href="#cb13-64" aria-hidden="true" tabindex="-1"></a>        <span class="co">(* using `apply` to either reduce an application of a lambda or to extend the stack of</span></span>
<span id="cb13-65"><a href="#cb13-65" aria-hidden="true" tabindex="-1"></a><span class="co">           neutral terms *)</span></span>
<span id="cb13-66"><a href="#cb13-66" aria-hidden="true" tabindex="-1"></a>    | vA, VN n1, VN n2 -&gt;</span>
<span id="cb13-67"><a href="#cb13-67" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> neu_eq d eG n1 n2 <span class="kw">with</span></span>
<span id="cb13-68"><a href="#cb13-68" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">Some</span> _ -&gt; <span class="kw">true</span></span>
<span id="cb13-69"><a href="#cb13-69" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">None</span> -&gt; <span class="kw">false</span></span>
<span id="cb13-70"><a href="#cb13-70" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb13-71"><a href="#cb13-71" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="kw">false</span></span>
<span id="cb13-72"><a href="#cb13-72" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-73"><a href="#cb13-73" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> neu_eq (d : lvl) (eG : tp_env) (n1 : neu) (n2 : neu) : vtp <span class="dt">option</span></span>
<span id="cb13-74"><a href="#cb13-74" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> n1, n2 <span class="kw">with</span></span>
<span id="cb13-75"><a href="#cb13-75" aria-hidden="true" tabindex="-1"></a>    | NVar l1, NVar l2 <span class="kw">when</span> l1 = l2 = <span class="dt">Some</span> (<span class="dt">List</span>.nth (lvl2ix d l1) eG)</span>
<span id="cb13-76"><a href="#cb13-76" aria-hidden="true" tabindex="-1"></a>    | NApp (n1, v1), NApp (n2, v2) -&gt;</span>
<span id="cb13-77"><a href="#cb13-77" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> neu_eq d eG n1 n2 <span class="kw">with</span></span>
<span id="cb13-78"><a href="#cb13-78" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">Some</span> (VPi ((x, vA), fB)) -&gt;</span>
<span id="cb13-79"><a href="#cb13-79" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> val_eq d eG v1 v2 vA <span class="kw">then</span></span>
<span id="cb13-80"><a href="#cb13-80" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Some</span> (fB v1)</span>
<span id="cb13-81"><a href="#cb13-81" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span></span>
<span id="cb13-82"><a href="#cb13-82" aria-hidden="true" tabindex="-1"></a>                <span class="dt">None</span></span>
<span id="cb13-83"><a href="#cb13-83" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">Some</span> _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;impossible: inputs of neu_eq are ill-typed&quot;</span></span>
<span id="cb13-84"><a href="#cb13-84" aria-hidden="true" tabindex="-1"></a>        | <span class="dt">None</span> -&gt; <span class="dt">None</span></span>
<span id="cb13-85"><a href="#cb13-85" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb13-86"><a href="#cb13-86" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">None</span></span>
<span id="cb13-87"><a href="#cb13-87" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-88"><a href="#cb13-88" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> check (d : lvl) (e : env) (eG : tp_env) (t : tm) (vA : vtp) : <span class="dt">unit</span> =</span>
<span id="cb13-89"><a href="#cb13-89" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> vA, t <span class="kw">with</span></span>
<span id="cb13-90"><a href="#cb13-90" aria-hidden="true" tabindex="-1"></a>    | VStar, Top -&gt; ()</span>
<span id="cb13-91"><a href="#cb13-91" aria-hidden="true" tabindex="-1"></a>    | VStar, Star -&gt; ()</span>
<span id="cb13-92"><a href="#cb13-92" aria-hidden="true" tabindex="-1"></a>    | VStar, Pi ((x, tA), tB) -&gt;</span>
<span id="cb13-93"><a href="#cb13-93" aria-hidden="true" tabindex="-1"></a>        check d e eG tA VStar;</span>
<span id="cb13-94"><a href="#cb13-94" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> vA = eval e tA <span class="kw">in</span></span>
<span id="cb13-95"><a href="#cb13-95" aria-hidden="true" tabindex="-1"></a>        check (d+<span class="dv">1</span>) ((x, vvar d)::e) ((x, vA)::eG) tB VStar</span>
<span id="cb13-96"><a href="#cb13-96" aria-hidden="true" tabindex="-1"></a>    | VTop, Unit -&gt; ()</span>
<span id="cb13-97"><a href="#cb13-97" aria-hidden="true" tabindex="-1"></a>    | VPi ((_, vA), fB), Lam (x, t) -&gt;</span>
<span id="cb13-98"><a href="#cb13-98" aria-hidden="true" tabindex="-1"></a>        check (d+<span class="dv">1</span>) ((x, vvar d)::e) ((x, vA)::eG) t (fB (vvar d))</span>
<span id="cb13-99"><a href="#cb13-99" aria-hidden="true" tabindex="-1"></a>    | vA, s -&gt;</span>
<span id="cb13-100"><a href="#cb13-100" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> vA&#39; = synth d e eG s <span class="kw">in</span></span>
<span id="cb13-101"><a href="#cb13-101" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="dt">not</span> (val_eq d eG vA vA&#39; VStar) <span class="kw">then</span> <span class="dt">failwith</span> <span class="st">&quot;type mismatch&quot;</span></span>
<span id="cb13-102"><a href="#cb13-102" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-103"><a href="#cb13-103" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> synth (d : lvl) (e : env) (eG : tp_env) (t : tm) : vtp =</span>
<span id="cb13-104"><a href="#cb13-104" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb13-105"><a href="#cb13-105" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">List</span>.nth eG i |&gt; <span class="dt">snd</span></span>
<span id="cb13-106"><a href="#cb13-106" aria-hidden="true" tabindex="-1"></a>    | App (s, t) -&gt;</span>
<span id="cb13-107"><a href="#cb13-107" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> synth d eG s <span class="kw">with</span></span>
<span id="cb13-108"><a href="#cb13-108" aria-hidden="true" tabindex="-1"></a>        | VPi ((x, vA), fB) -&gt;</span>
<span id="cb13-109"><a href="#cb13-109" aria-hidden="true" tabindex="-1"></a>            check d e eG t vA;</span>
<span id="cb13-110"><a href="#cb13-110" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> v = eval e t <span class="kw">in</span></span>
<span id="cb13-111"><a href="#cb13-111" aria-hidden="true" tabindex="-1"></a>            fB v</span>
<span id="cb13-112"><a href="#cb13-112" aria-hidden="true" tabindex="-1"></a>        | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;ill-typed: application subject not a function&quot;</span></span>
<span id="cb13-113"><a href="#cb13-113" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb13-114"><a href="#cb13-114" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;cannot synthesize type of checkable term&quot;</span></span></code></pre></div>
<p>To actually use this implementation, consider that a user will supply a term together with its
type, both represented as syntax and assumed to be closed.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> check_user (t : tm) (tA : tp) : <span class="dt">unit</span> =</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>    check <span class="dv">0</span> [] [] tA VStar; <span class="co">(* check that the type is a valid type *)</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> vA = eval [] tA <span class="kw">in</span> <span class="co">(* evaluate it, to then guide checking of the user&#39;s program *)</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    check <span class="dv">0</span> [] [] t vA <span class="co">(* check the user&#39;s program *)</span></span></code></pre></div>
<p>Depending on the situation, after evaluation, we might simply evaluate the user’s program, or
compile it.</p>
<p>This gives, in 115 lines of code, a fairly straightforward implementation of a dependently-typed
lambda calculus. This implementation omits <code>quote</code>. After introducing equality directly on values,
it became unnecessary to convert back into syntax to complete the implementation of the type
checker. In a practical implementation, with real error messages, we would need it: in the case
that type checking switches to synthesis, for instance, we check equality of values, and would like
to tell the user what the expected and actual types are!</p>
<p>In the next post in this series, I’ll extend the calculus with some built-in inductive types –
natural numbers and equality – and encode a proof by induction that addition is associative.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Implementing dependent types: how hard could it be? (Part 1)</title>
    <link href="https://jerrington.me/posts/2025-05-23-depty-impl.html" />
    <id>https://jerrington.me/posts/2025-05-23-depty-impl.html</id>
    <published>2025-05-23T00:00:00Z</published>
    <updated>2025-05-23T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on May 23, 2025
    
</div>

<p>Short answer: hard, but not as hard as I thought.</p>
<p>Type systems in which the types (of functions, typically) may <em>depend</em> on terms
are called <em>dependently-typed.</em> These systems exist on a spectrum, where restricted forms of
dependent types exist in common functional programming languages such as OCaml, Haskell, and even
TypeScript; the most complex forms of dependent types appear in proof assistants like Agda and Coq.</p>
<p>Dependent types complicate the typechecking process. Normally, a typechecker verifies, for
instance, that the type of the argument in a function application is compatible with the type of
the parameter of the function. In a simply-typed language, it suffices to check that the types are
equal. In the dependently-typed setting, types may contain terms requiring evaluation, so the
typechecker must <em>normalize</em> types before proceeding to check equality. For example, the
typechecker must decide whether <code>3 + 5</code> (a term requiring evaluation) equals <code>8</code> in the
course of deciding whether a term of type <code>Vec (3 + 5) A</code> can be passed to a function expecting an
input of type <code>Vec 8 A</code>.</p>
<p>Let me be clear: <em>proving</em> that every well-typed term in a dependently-typed language can be
normalized – this is called the normalization property – is very challenging. But that is not the
goal of this post.</p>
<p>In this series of posts, I want to demonstrate how we can <em>implement</em> a typechecker for a small,
dependently-typed lambda-calculus by relying on an elegant normalization technique called
<em>Normalization by Evaluation.</em> normalization procedure. The plan for the series is the following.</p>
<ul>
<li>Part 1: core syntax, evaluation, normal vs neutral terms, normalization.</li>
<li>Part 2: bidirectional typechecking, substitutions, semantic equality.</li>
<li>Part 3: scaling up the language: induction on natural numbers, identity type.</li>
</ul>
<h2 id="the-core-calculus">The core calculus</h2>
<p>If we allow terms to compute types and types to refer to terms, then the syntactic separation
between these objects loses its relevance. Instead, let’s define a unified syntax that captures
both, but nonetheless use the letter <code>t</code> to refer to terms <em>understood as terms</em> but the letters
<code>A</code> and <code>B</code> to refer to terms <em>understood as types.</em></p>
<pre><code>Terms t, A, B ::= x | λx. t | t1 t2 | () | (x:A) -&gt; B | ⊤ | ★</code></pre>
<p>This syntax contains variables, lambda abstractions, applications, a constant <code>()</code> (unit), the
dependent function type <code>(x:A) -&gt; B</code>, the unit type <code>⊤</code>, and the type of types <code>★</code>. (To simplify,
we’ll use the rule <code>★ : ★</code>.)</p>
<p>With this syntax, we can write things we couldn’t in the simply-typed lambda calculus. For example,
consider the type <code>(x:⊤) -&gt; (λx.⊤) x</code>. From the point of view of the simply-typed lambda calculus,
this type is very unusual: it contains a reducible expression (redex), namely the right-hand
side of the arrow can be simplified to just <code>⊤</code> by beta-reduction.</p>
<p>This syntax also allows for quantification over types, allowing us to write polymorphic functions,
too. For example, here’s the type of a (simply-typed) composition operator.</p>
<pre><code>(A:★) -&gt; (B:★) -&gt; (C:★) -&gt; (f : B -&gt; C) -&gt; (g : A -&gt; B) -&gt; (x:A) -&gt; C</code></pre>
<p>We encode the syntax of the core calculus as a recursive type.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> ix = <span class="dt">int</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> tm =</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* terms *)</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    | Lam <span class="kw">of</span> name * tm</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    | Var <span class="kw">of</span> ix</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    | App <span class="kw">of</span> tm * tm</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    | Unit</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* types *)</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    | Pi <span class="kw">of</span> (name * tp) * tp</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    | Top</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    | Star</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> tp = tm <span class="co">(* to understand a term as a type *)</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> ctx = (name * tp) <span class="dt">list</span></span></code></pre></div>
<p>This syntax uses a nameless (de Bruijn) representation for variables in order to simplify the
implementation of capture-avoiding substitution, but I do store names of variables in binders and
contexts as a compromise to enable writing a pretty-printer that shows names.</p>
<h2 id="normalization-by-evaluation">Normalization by Evaluation</h2>
<p>A term is in normal form when it cannot be further reduced. Suppose <code>t</code> and <code>A</code> are in normal form,
and that <code>A</code> contains a free variable <code>x</code>. Will the substitution <code>[t/x]A</code> be in normal form?</p>
<p>Not necessarily! That’s the central challenge in implementing our typechecker, which we will
surmount by implementing a normalization procedure.</p>
<aside>
<p>Crucially, we have a problem when <code>t</code> is built from an introduction form and the target variable of
the substitution is the subject of an elimination. The substitution then introduces a beta-redex.</p>
</aside>
<p>Normalization by Evaluation is a semantic approach to normalization. It is made up of two related
procedures.</p>
<ol type="1">
<li><code>eval</code> is a bog-standard evaluation procedure, which interprets a lambda-term into a semantic
space of values. This procedure is responsible for finding the beta-normal form of a lambda-term
by eliminating all redexes from the term.</li>
<li><code>quote</code> is its inverse, which reifies an element from the semantics (a value) back into a
lambda-term. This procedure is responsible for eta-expanding terms at function types, enabling
us to consider <code>f</code> and <code>λx. f x</code> as judgmentally equal at the type <code>A -&gt; B</code>.</li>
</ol>
<p>The game plan to implement this pair of procedures is first to define the semantic space, i.e. the
set values; then to implement <code>eval</code>; and finally to implement <code>quote</code>.</p>
<h3 id="values">Values</h3>
<p>The value of a term is its semantics. Since we’re working in OCaml, we can give the semantics of a
lambda-term at function type as an OCaml function. In other words, we design our evaluation
procedure so that if <code>t : A -&gt; B</code>, then <code>eval(t)</code> gives us an OCaml function from values of type
<code>A</code> to values of type <code>B</code>. This is a good idea, operationally speaking, because we get to wait
until the argument to the function is known (and evaluated) before proceeding to evaluate the
function body. The same line of reasoning leads to interpreting a Pi-type as an OCaml function on
types.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> value =</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    | VLam <span class="kw">of</span> name * (value -&gt; value)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    | VUnit</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    | VPi <span class="kw">of</span> (name * vtp) * (value -&gt; vtp)</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    | VTop</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    | VStar</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> vtp = value</span></code></pre></div>
<p>This syntax of values is good enough for closed terms, having no free variables, but it is
insufficient for open terms. Concretely, we will run into a problem when trying to implement
<code>quote</code> later on: how will we reconstruct a lambda-term from an OCaml function <code>value -&gt; value</code>?
We want to quote the body of the abstraction – that is the output of the function <code>value -&gt; value</code>
– but to access the body, we must apply this OCaml function to some value. What value can we use?</p>
<p>The resolution to this quandry lies in generalizing the syntax of values to explicitly account for
open terms. We might think to add merely a constructor for variables, but this isn’t enough, as
e.g. <code>x (λx. y)</code> is an application that’s in normal form.</p>
<p>Rather than merely add variables, we add a separate syntax of so-called <em>neutral terms.</em> These are
variables and elimination forms applied to neutral terms. Conceptually, a neutral term is a stack
of elimination forms that are ultimately blocked on a variable. In contrast, the syntax of values
I gave above corresponds to the introduction forms of the lambda-calculus.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> value =</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    | VLam <span class="kw">of</span> name * (value -&gt; value)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    | VUnit</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    | VPi <span class="kw">of</span> (name * vtp) * (value -&gt; vtp)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    | VTop</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    | VStar</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    | VN <span class="kw">of</span> neu <span class="co">(* neutral terms embed as values *)</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> neu =</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    | NVar <span class="kw">of</span> lvl</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    | NApp <span class="kw">of</span> neu * value</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> vtp = value</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> lvl = <span class="dt">int</span></span></code></pre></div>
<p>Notice that the representation I use for variables here mentions <code>lvl</code> – these are de Bruijn
levels, the dual of de Bruijn indices. When variables use de Bruijn levels, weakening such terms
becomes free, whereas the use of de Bruijn indices would require costly explicit shifts. This will
end up simplifying the implementation of <code>eval</code>.</p>
<p>Finally, this combined syntax of values and neutral terms is specifically designed to represent
only beta-normal forms. A value is a stack of introduction forms that might at some point “switch”
to a neutral term, which is then a stack of elimination forms ending on a variable. Crucially
impossible is to write an elimination form whose subject is an introduction form, i.e. a
non-beta-normal term.</p>
<h3 id="eval"><code>eval</code></h3>
<p>Recall from kindergarten how to evaluate lambda-terms, and use your imagination to extend the
procedure to types. We’ll use an environment-based approach to efficiently handle substitutions in
a lazy fashion. In the presence of neutral terms, whenever we evaluate an elimination form, we need
to explicitly check whether the subject of the elimination is normal or neutral to proceed
accordingly.</p>
<ul>
<li><strong>Elimination subject is normal.</strong> A reduction is therefore possible, so we must perform it.</li>
<li><strong>Elimination subject is neutral.</strong> Reduction is ultimately blocked on a variable, so we extend
the stack of blocked eliminations.</li>
</ul>
<p>The helper function <code>apply</code>, which interprets a function application, performs this check.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> env = value <span class="dt">list</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> eval (e : env) (t : tm) : value =</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> t <span class="kw">with</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* types: *)</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    | Top -&gt; VTop</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    | Star -&gt; VStar</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    | Pi ((x, tA), tB) -&gt; VPi ((x, eval e tA), <span class="kw">fun</span> v -&gt; eval (v::e) tB)</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* terms: *)</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>    | Unit -&gt; VUnit</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>    | Lam (x, t) -&gt; VLam (x, <span class="kw">fun</span> v -&gt; eval (v::e) t)</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>    | Var i -&gt; <span class="dt">List</span>.nth e i</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>    | App (t1, t2) -&gt; apply (eval e t1) (eval e t2)</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> apply v1 v2 = <span class="kw">match</span> v1 <span class="kw">with</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>    | VN n -&gt; VN (NApp (n, v2))</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>    | VLam (_, f) -&gt; f v2</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;type error&quot;</span></span></code></pre></div>
<aside>
<p>Notice the anonymous function used in both the <code>Pi</code> and <code>Lam</code> cases is the same. We could easily
rewrite <code>eval</code> (and <code>value</code>) in a
<a href="/posts/2023-02-12-defunctionalizing-continuations">defunctionalized</a> form – that is, we could use
a first-order representation of closures instead of using OCaml’s closures – leading to a strategy
suitable for efficient implementation in a lower-level language.</p>
</aside>
<h3 id="quote"><code>quote</code></h3>
<p>Equipped with <code>eval</code> to perform reductions, interpreting a lambda-term into an OCaml semantics,
we’re now ready to implement its dual, to finally arrive at a normalization procedure by composing
the two. This dual procedure, called <code>quote</code>, transforms a semantic value back into syntax.</p>
<p>What’s conceptually tricky about <code>quote</code> is how we handle functions. Recall that <code>Lam (x, t)</code>
evaluates to the (metalanguage) closure <code>fun v -&gt; eval (v::e) t</code> where the (meta) free variable <code>e</code>
is an environment providing values for the (object) free variables present in <code>t</code>. To quote this,
we must first apply the closure to a value. Thankfully, we have neutral terms at our disposal: we
generate a variable, corresponding to the bound variable of the abstraction, to use as an argument.</p>
<p>Since neutral variables use de Bruijn levels, the <code>quote</code> procedure tracks a current depth,
incremented by one whenever it traverses a binder.</p>
<p>Furthermore, <code>quote</code> is responsible for finding an eta-normal form, by performing eta-expansion of
neutral terms at function types. This requires typing information, which quote will ultimately
receive from the typechecker in the form of a semantic type. Then, <code>quote</code> must perform type
reconstruction to maintain typing information at every step: <code>quote</code> traverses the given value
together with its (semantic) type.</p>
<p>To know the type of a variable when quoting encounters it, we equip the process with a map from
variables to semantic types. This mapping is called a <em>typing environment,</em> in contrast with an
(ordinary) context that maps variables to <em>syntactic</em> types and an (ordinary) environment that maps
variables to values (semantic terms). Since we conflate types and terms in our setup, a typing
environment is really nothing more than an ordinary environment.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> tp_env = env</span></code></pre></div>
<p>Since the syntax of values is broken down into normal values and neutral values, we need a separate
<code>quote_neu</code> to quote neutral terms. When working with neutral terms, the flow of typing information
is reversed: rather than take as <em>input</em> a type to be broken down alongside the value to quote,
<code>quote_neu</code> instead produces as <em>output</em> the type of the given neutral value. Recall that a neutral
term is a stack of elimination forms ultimately blocked on a variable; that variable’s type will
have been recorded in the context previously when quoting an abstraction, and the stacked
elimination forms will break down that type.</p>
<aside>
<p>The idea of reversing the flow of typing information is very powerful. I’ll expand on it
considerably when we implement the typechecker for this language in Part 2 of this series.</p>
</aside>
<div class="sourceCode" id="cb8"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> vvar l = VN (NVar l)</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> lvl2ix d l = d - l - <span class="dv">1</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> quote (d : lvl) (e : tp_env) (vA : vtp) (v : value) : tm =</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">match</span> vA, v <span class="kw">with</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* types: *)</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    | VStar, VTop -&gt; Top</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    | VStar, VStar -&gt; Star</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    | VStar, VPi ((x, vA), fB)-&gt;</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>        Pi ((x, quote d e VStar vA), quote (d+<span class="dv">1</span>) ((x, vA)::e) VStar (fB (vvar d)))</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* terms: *)</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>    | VTop, VUnit -&gt; Unit</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>    | VPi ((_, vA), fB), v -&gt;</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>        Lam (x, quote (d+<span class="dv">1</span>) ((x, vA)::e) (fB (vvar d)) (apply v (vvar d))</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    | vA, VN n -&gt; quote_neu d e n |&gt; <span class="dt">fst</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>    | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;quote: ill-typed&quot;</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> quote_neu (d : lvl) (e : tp_env) : neu -&gt; tm * vtp = <span class="kw">function</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>    | NVar l -&gt;</span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> i = lvl2ix d l <span class="kw">in</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> vA = ix_lookup i e <span class="kw">in</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>        (Var i, vA)</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>    | NApp (n, v) -&gt;</span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> t, vAB = quote_neu d e n <span class="kw">in</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>        <span class="kw">begin</span> <span class="kw">match</span> vAB <span class="kw">with</span></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>        | VPi ((x, vA), fB) -&gt;</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a>            (App (t, quote d e vA v), fB v)</span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a>        | _ -&gt; <span class="dt">failwith</span> <span class="st">&quot;quote_neu: ill-typed application subject&quot;</span></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span></code></pre></div>
<p>On a well-typed value, quoting always succeeds. This justifies two choices made in this
implementation of <code>quote</code> and <code>quote_neu</code>.</p>
<ol type="1">
<li>In ill-typed cases, we simply use <code>failwith</code>.</li>
<li>In the last case of <code>quote</code>, where we call <code>quote_neu</code>, the expected type of <code>VN n</code> (i.e. the
input <code>vA</code> of <code>quote</code>) will necessarily equal its actual type (the type synthesized by
<code>quote_neu</code>). We simply throw out the synthesized type.</li>
</ol>
<h3 id="normalization">Normalization</h3>
<p>A roundtrip through eval and quote brings a term into normal form.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> norm (t : tm) (tA : tp) : tm =</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    quote <span class="dv">0</span> [] (eval [] tA) (eval [] t)</span></code></pre></div>
<p>To enable normalization of open terms – we will encounter open terms during typechecking – it
suffices to slightly generalize <code>norm</code>. I’ll delay the discussion of that generalization until we
get to implementing the typechecker, in Part 2 of the series.</p>
<h2 id="next-steps">Next steps</h2>
<p>In this post, we built a normalization procedure for a small, dependently-typed calculus by
following the Normalization by Evaluation strategy. That strategy consists broadly in the following
steps.</p>
<ol type="1">
<li>Define a semantics into which the language’s syntax is to be interpreted. In doing so, separate
the introduction forms (normal terms) from the elimination forms (neutral terms), giving rise to
a syntactic characterization of beta-normal forms.</li>
<li>Implement an evaluation procedure <code>eval</code> that interprets the syntax into the semantics. This
eliminates all beta-redexes from a given term.</li>
<li>Implement the evaluation procedure’s inverse, called <code>quote</code>. This procedure converts a semantic
term back into a syntactic term. This is a type-directed procedure. Typing information is
crucially used to enable eta-expansion. This allows our system to identify as definitionally
equal the terms <code>f</code> and <code>λx. f x</code>.</li>
<li>A roundtrip through <code>eval</code> and <code>quote</code> brings a term into normal form. This ultimately gives us
a way to compare types which may contain terms requiring evaluation, as is common in a
dependently-typed system.</li>
</ol>
<p>Equipped with the normalization procedure implemented in this post, we’re ready to code up the
typechecker for this small language. The central challenge in implementing the typechecker, as
usual, will be the handling of variables and substitutions. I’ll approach that challenge in a few
different ways in the next post.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>An inductive model of food</title>
    <link href="https://jerrington.me/posts/2025-02-20-induction-on-food.html" />
    <id>https://jerrington.me/posts/2025-02-20-induction-on-food.html</id>
    <published>2025-02-20T00:00:00Z</published>
    <updated>2025-02-20T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on February 20, 2025
    
</div>

<p>At long last I combine my two passions to form an unlikely duo:
mathematical rigour and bodybuilding.</p>
<p>For me, the biggest challenge in bodybuilding has always been to eat enough. The apps out there for
tracking macros and meal planning always left me dissastisfied, so I even made my own called
macro-traco. But in macro-traco, I made the same mistake that major apps like MyFitnessPal make: my
model of food considered as distinct a number of things that are, at their core, not different at
all. Those are foods, recipes, meals, meal plans/journals. Addressing that mistake is
what led me to implement <a href="https://nutcalc.jerrington.me">Nutcalc</a> in a very natural way.</p>
<h2 id="getting-to-the-bottom-of-food">Getting to the bottom of food</h2>
<p>What is a meal plan? It’s a schedule of meals to eat in a day. Really it’s the same as a meal
<em>journal,</em> but with a forward-thinking perspective. So a meal plan (or journal) <em>is composed
of</em> meals.</p>
<p>What is a meal? (I promise this isn’t a silly question.) Take the bodybuilder classic: chicken,
broccoli and rice. In this case, the meal <em>is composed of</em> three foods. Take a less simple meal:
pasta with bolognese sauce. Whereas pasta is just a food, bolognese sauce is a recipe you make
yourself, unless of course you buy it in a jar.</p>
<p>Then, a <em>recipe</em> is something that doesn’t have a nutrition facts label, that you make yourself by
combining various foods via a mysterious process known as “cooking.”</p>
<p>Finally, what is a food? A food, practically speaking, has a “nutrition facts” label on it, listing
the nutrients of the food.</p>
<p>At last we reach the bottom of this model: nutrients sit indivisible, at the bottom of this
hierarchy.</p>
<p>To recap, this exploration reveals the following levels, from largest to smallest: a meal
plan/journal is composed of meals; a meal is composed of recipes; a recipe is composed of foods;
and foods are composed of nutrients.</p>
<h2 id="modelling-the-hierarchy">Modelling the hierarchy</h2>
<p>A rigid model of this setup, as used in apps like MyFitnessPal or macro-traco could define each
layer separately to consist of a list of items from the layer below. Such a model is inflexible –
adding new layers requires substantial work – and even its initial setup is painful. (<em>Five</em>
database tables?) And moreover, at a basic level, a straightforward such model would require
that meals consist <em>only</em> of recipes, making it annoying to model meals like “chicken broccoli and
rice” that are simply composed naturally of foods, living two (instead of one) layers away in the
hierarchy.</p>
<p>Instead of choosing a particular number of layers, let’s define <em>all infinitely many</em> layers by
induction. Here is an inductive definition of Food. (I’ll use capital-F Food to refer to items
generated by this inductive process at any layer as opposed to lowercase-F food for those items
described above as having nutrition facts labels, living at layer 1 of the model.)</p>
<ul>
<li><strong>Base case.</strong> Each Nutrient is a Food.</li>
<li><strong>Step case.</strong> If <span class="math inline">\(F_1,\ldots,F_n\)</span> are each a Food,
then the Compound <span class="math inline">\(\langle F_1, \ldots, F_n \rangle\)</span> is a Food.</li>
</ul>
<p>Mathematically speaking, a Food is an <span class="math inline">\(n\)</span>-ary tree whose leaves are labelled according to what
nutrient is represented there.</p>
<p>In this inductive model, nutrition facts is defined by a totally straightfoward recursion on Food,
which one normally learns to implement in kindergarten.</p>
<ul>
<li>If the Food is a Nutrient, then it <em>is</em> its nutrition facts.</li>
<li>If the Food is a Compound <span class="math inline">\(\langle F_1, \ldots, F_n \rangle\)</span>, then its nutrition facts is simply
the sum of the nutrition facts of each <span class="math inline">\(F_i\)</span>.</li>
</ul>
<h2 id="how-much-chicken">How much chicken?</h2>
<p>I’ve thus far omitted a crucial aspect of the model: what are the <em>quantities</em> of the Foods that go
into forming a Compound? Recall that Compounds are things like meals, which we would naturally
express as “two cups of cooked white rice, one large chicken breast, and 200 grams of broccoli.”</p>
<p>In that natural language description, the foods are “cooked white rice”, “chicken breast”, and
“broccoli”, but their respective <em>quantities</em> are “two cups”, “one large”, and “200 grams”.
Quantities are composed of a number together with a <em>unit.</em> The units here are “cups”,
“large,” and “grams”.</p>
<p>In light of this, I define a Quantified Food as a Quantity together with a Food. A Quantity is just
a number and a unit. The unit is specific to the associated Food, so a “cup” of “cooked white rice”
is distinct from a “cup” of “dry steel-cut oats.”</p>
<p>Now let’s revise the step case of the definition of Food.</p>
<ul>
<li>If <span class="math inline">\(Q_1, \ldots, Q_n\)</span> are each a Quantified Food, then <span class="math inline">\(\langle Q_1, \ldots, Q_n \rangle\)</span> is a
Food.</li>
</ul>
<p>Mathematically speaking, we still have an <span class="math inline">\(n\)</span>-ary tree, but the <em>edges</em> in that tree are now
labelled with Quantities.</p>
<p>The recursive definition of nutrition facts changes slightly: it suffices to multiply the nutrition
facts of each Food in a Compound by its Quantity before summing.</p>
<h2 id="in-practice">In practice</h2>
<p><a href="https://nutcalc.jerrington.me">Nutcalc</a> implements this inductive model of food. It is a
domain-specific programming language for defining Foods and performing computations on them.</p>
<p>A Nutcalc program consists of a series of Food definitions.</p>
<pre class="nutcalc"><code>1 cup &#39;cooked white rice&#39; weighs 158 g:
- 0.4 g fat + 4.3 g protein + 45 g carbs
- 1.9 mg iron

1 large &#39;chicken breast&#39; weighs 120 g:
- 4.3 g fat + 37 g protein
- 89 mg sodium + 102 mg cholesterol + 1.2 mg iron + 307 mg potassium

100 g broccoli:
- 0.4 g fat + 7 g carbs + 2.8 g protein
- 33 mg sodium + 316 mg potassium</code></pre>
<p>The effect of executing these statements in the Nutcalc interpreter is to define the Foods ‘cooked
white rice’ and ‘chicken breast’ together with the respective units ‘cup’ and ‘large’ whose
equivalent weights are given. For broccoli, since the definition is already for a particular
weight, there’s no need for a ‘weighs’ clause.</p>
<p>Since Nutcalc uses the inductive model of food, we use the same syntax to define meals. For meals,
the most natural unit is usually ‘serving’, but that’s long to type so how about <code>x</code>?</p>
<pre class="nutcalc"><code>1 x &#39;chicken broccoli rice&#39;:
- 1 large &#39;chicken breast&#39; + 2 cup &#39;cooked white rice&#39; + 200 g broccoli</code></pre>
<p>When a ‘weighs’ clause is omitted but the definition defines a new unit (here <code>x</code>), the weight of
the new unit is inferred as the sum of the weights of the constituent Foods.
For meals, not only is that assumption about weight usually correct, but we often don’t care
anyway about the weights of Foods at the higher levels in the model.</p>
<p>Again, we use the same syntax to define a meal plan:</p>
<pre class="nutcalc"><code>1 x Monday:
- 1 x &#39;oatmeal breakfast&#39;
- 1 x &#39;eggs sausage bacon toast lunch&#39;
- 1 x &#39;chicken broccoli rice&#39;
- 1 x &#39;protein shake&#39;</code></pre>
<p>Of course, the same syntax is used to define a food journal:</p>
<pre class="nutcalc"><code>1 x &#39;2025-02-20&#39;:
- 0.5 cup &#39;dry steel-cut oats&#39; + 50 g walnuts + 2 cup &#39;3.25% milk&#39;
- 4 x &#39;breakfast sausage&#39; + 4 large egg + 2 slice toast + 2 tsp butter
- 1 medium &#39;chicken break&#39; + 1 medium &#39;chicken leg&#39; + 2.5 cup &#39;cooked white rice&#39; + 200 g broccoli</code></pre>
<p>After loading a file with our definitions, we can compute aggregate nutrition facts easily:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> nutcalc <span class="at">-i</span> journal.nut</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ex">nutcalc</span><span class="op">&gt;</span> facts 1 x <span class="st">&#39;oatmeal breakfast&#39;</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ex">energy:</span> 1122.83 kcal</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="ex">protein:</span> 44.30 g</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ex">fat:</span> 46.57 g</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="ex">carbs:</span> 131.62 g</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ex">water:</span> 150.60 g</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="ex">calcium:</span> 602.41 mg</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ex">iron:</span> 4.35 mg</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a><span class="ex">potassium:</span> 930.49 mg</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a><span class="ex">sodium:</span> 84.34 mg</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a><span class="ex">zinc:</span> 2.71 mg</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a><span class="ex">cholesterol:</span> 30.12 mg</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a><span class="ex">nutcalc</span><span class="op">&gt;</span></span></code></pre></div>
<p>In fact, <code>facts</code> accepts an <em>expression</em> on the right, which can be a lone Quantified Food or a sum
thereof, e.g. <code>2 cup 'cooked white rice' + 200 g broccoli</code>.</p>
<h2 id="a-programming-language">A programming language?</h2>
<p>Some might laugh at the idea of calling Nutcalc a “programming language.” It has no loops, no
conditions, no mutable variables, no functions, no recursion. It is certainly not Turing-complete.</p>
<p>In my view, Nutcalc is a programming language because it has a syntax and a semantics. Both are
very simple, but I see that as a strength of the language, not a weakness.</p>
<p>Overall, whether Nutcalc is or isn’t a programming language is incidental. It’s useful.
Anyway, the main contribution is the inductive model of food, giving a unified view of foods,
meals, and so on.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Three detailed solutions to Leetcode #10: regular expression matching</title>
    <link href="https://jerrington.me/posts/2024-09-27-leetcode-10.html" />
    <id>https://jerrington.me/posts/2024-09-27-leetcode-10.html</id>
    <published>2024-09-27T00:00:00Z</published>
    <updated>2024-09-27T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on September 27, 2024
    
</div>

<p>As I prepare for technical interviews, I’ve been grinding Leetcode to practice my data structures
and algorithms. (And if you’re looking to hire in 2025, <a href="/info.html">hit me up</a>.)
I want to share detailed explanations of three different, fairly short solutions to
<a href="https://leetcode.com/problems/regular-expression-matching">Problem 10</a>, “regular expression
matching.” I especially find it interesting when a problem admits multiple, workable solutions.
Part of the beauty of computer science and software engineering is exactly that there are so many
different, interesting ways to solve problems.</p>
<h2 id="the-problem-not-really-regex">The problem: not really regex!</h2>
<p>We’re asked to define a function <code>match_pattern(s: str, p: str) -&gt; bool</code> that determines whether
the given string <code>s</code> matches the given regular expression <code>p</code>, subject to some constraints.</p>
<ul>
<li>the lengths of both <code>s</code> and <code>p</code> are between 1 and 20 (inclusive)</li>
<li><code>s</code> contains only lowercase English letters</li>
<li><code>p</code> contains only lowercase English letters, plus <code>.</code> and <code>*</code>.</li>
</ul>
<p>The <code>.</code> pattern matches any character, and the <code>*</code> is a <em>modifier</em> meaning to match <em>zero</em> or more
times the preceding character. There is an additional restriction that the input <code>p</code> be
“well-formed,” meaning that there isn’t a <code>*</code> as the very first character, nor that there are two
<code>*</code>s in a row.</p>
<p>Moreover, for our <code>match_pattern</code> to output <code>True</code>, the pattern must cover the <em>entire</em> input
string.</p>
<p>This might sound different from the regex you know and love:</p>
<ul>
<li>There are no parentheses, so repetitions with the star are only for a single character.</li>
<li>There are no alternations, so no patterns like <code>a|b</code>.</li>
</ul>
<p>This vastly simplifies the problem down from full regex matching!</p>
<p>In the absense of any <code>*</code>, this is just a simple string-matching problem. We could just traverse
<code>s</code> and <code>p</code> simultaneously, checking along the way that each character of <code>p</code> matches the
corresponding character of <code>s</code>, letting any <code>.</code> in <code>p</code> match any character in <code>s</code>.</p>
<p>In other words, when e.g. <code>s = "abc"</code> and <code>p = "a.c"</code>, we can walk both strings together and
compare character by character. When comparing <code>'b'</code> with <code>'.'</code>, we say yes. We would arrive at the
end of both inputs at the same time, and along the way said yes everywhere, so we decide that this
string matches this pattern.</p>
<p>To illustrate the challenge involved in handling the <code>*</code>, let’s walk through an example in detail.
Say <code>s = "aab"</code> and <code>p = "a*b"</code>. Set up two pointers: let <code>i</code> be an index into <code>s</code> and <code>j</code> be an
index into <code>p</code>, both starting at zero.</p>
<ul>
<li>We see a star at index <code>j+1</code>, so we have to decide:
<ul>
<li>do we <em>skip</em> the star, setting <code>j = j+2</code> but leaving <code>i</code> the same? Or,</li>
<li>do we <em>use</em> the star, setting <code>i = i+1</code>, but leaving <code>j</code> the same?</li>
</ul></li>
</ul>
<p>That decision is the crux of the challenge: we can’t know for sure which choice to make.</p>
<h2 id="using-brute-force-backtracking-search">Using brute force: backtracking search</h2>
<p>The idea is this: we don’t know which choice to make, so try both ways!</p>
<p>A backtracking search will, in the worst case, explore the entire decision tree of the problem,
which we can visualize like this. Rather than show the indices, I’ll show <code>s</code> and <code>p</code> changing as
we move through them. States in red are those where we return false, and the green state is where
we return <code>True</code> as we successfully matched the string with the pattern.</p>
<p><img class="figure" src="/figures/2024-09-13-regex-dt.svg"></p>
<ul>
<li>The leftmost state does not have a “use star” branch: to use the star, the head of <code>s</code> (i.e.
<code>'b'</code>) must match the head of <code>p</code> (i.e. <code>'a'</code>).</li>
<li>When the current state’s pattern’s head doesn’t have a star, the tree doesn’t branch.</li>
</ul>
<p>We can code this backtracking search as a recursive algorithm.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> match_pattern(s, p):</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> s <span class="op">==</span> <span class="st">&#39;&#39;</span> <span class="kw">and</span> p <span class="op">==</span> <span class="st">&#39;&#39;</span>: <span class="cf">return</span> <span class="va">True</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> p <span class="op">==</span> <span class="st">&#39;&#39;</span>: <span class="cf">return</span> <span class="va">False</span> <span class="co"># pattern empty, but more string left</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span>(p) <span class="op">&gt;=</span> <span class="dv">2</span> <span class="kw">and</span> p[<span class="dv">1</span>] <span class="op">==</span> <span class="st">&#39;*&#39;</span>:</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>        <span class="co"># right branch: skip star</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> match_pattern(s, p[<span class="dv">2</span>:]): <span class="cf">return</span> <span class="va">True</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>        <span class="co"># but if that fails, then we have to use the star</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> (</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>            <span class="bu">len</span>(s) <span class="co"># for that, we need at least one char in s</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_char(s[<span class="dv">0</span>], p[<span class="dv">0</span>]) <span class="co"># it must match the head of p</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_pattern(s[<span class="dv">1</span>:], p) <span class="co"># and p has to match the rest of s</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>        )</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>: <span class="co"># we&#39;re not handling a star, so we need:</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> (</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>            <span class="bu">len</span>(s) <span class="co"># there to be at least one character in s</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_char(s[<span class="dv">0</span>], p[<span class="dv">0</span>]) <span class="co"># that it match the head of p</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_pattern(s[<span class="dv">1</span>:], p[<span class="dv">1</span>:])</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>            <span class="co"># that the rest of the string match the rest of the pattern</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>        )</span></code></pre></div>
<aside>
The use of string slicing in this solution is (probably) inefficient as it might copy the string.
We could improve on this solution by using indices instead of repeatedly slicing the strings.
</aside>
<p>The <code>match_char</code> function is simply an equality check on characters that accounts for the pattern
character <code>'.'</code> being equal to any string character.</p>
<p>To assess the time complexity of this solution, let’s consider an input with lots of stars:
<code>match_pattern("aaaaab", "a*a*a*a*c")</code></p>
<p>Of course, the output should be <code>False</code> due to the last characters being mismatched, but to
discover this, the backtracking search has to explore the entire tree. So how big does the tree
become for this input?</p>
<p>When there’s a star, we make two recursive calls, each on an input that’s smaller only by one.
Overall, we get an <em>exponential</em> time complexity.</p>
<p>However, you might notice that a sequence of <code>a*a*...</code> is equivalent to just a single <code>a*</code>.
Therefore, we can ‘optimize’ the regular expression before interpreting it. By doing this and
prioritizing the ‘use star’ branch of the backtracking search we get a greedy formulation of the
search that avoids exponential blowup in most cases. This formulation is performant enough to pass
the time requirements on Leetcode.</p>
<h2 id="avoid-repeating-work-dynamic-programming">Avoid repeating work: dynamic programming</h2>
<p>The subproblems to solve in the recursive algorithm above are <em>overlapping.</em></p>
<p>To see why, let’s draw out some of the recursive calls for <code>match_pattern("aaab", "a*a*a*c")</code></p>
<p><img class="figure" src="/figures/2024-09-13-repeated-work.svg"></p>
<p>See? There are two different paths that lead us to solving the subproblem
<code>match_pattern("aab", "a*a*c")</code>:</p>
<ol type="1">
<li>Left (‘use star’) then right (‘skip star’)</li>
<li>Right (‘skip star’) then left (‘use star’)</li>
</ol>
<p>The essence of dynamic programming is to solve each unique subproblem exactly once, and there are
two broad approaches to accomplishing that.</p>
<h3 id="strategy-1-top-down-with-memoization">Strategy 1: top-down with memoization</h3>
<p>This technique is quite simple: take the recursive algorithm and attach a cache of solutions to it.
This cache will be a hashtable, initially empty. Each key will be a tuple of inputs to
<code>match_pattern</code>. At the very beginning of <code>match_pattern</code>, we consult the cache to see if we’ve
already solved the problem, returning the cached result in that case. Else, we actually do the
computation, and store its result in the cache before returning.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> match_pattern_dp(s, p, cache):</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> s <span class="op">==</span> <span class="st">&#39;&#39;</span> <span class="kw">and</span> p <span class="op">==</span> <span class="st">&#39;&#39;</span>: <span class="cf">return</span> <span class="va">True</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> p <span class="op">==</span> <span class="st">&#39;&#39;</span>: <span class="cf">return</span> <span class="va">False</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="co"># answer already known:</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (s, p) <span class="kw">in</span> cache: <span class="cf">return</span> cache[(s, p)]</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span>(p) <span class="op">&gt;=</span> <span class="dv">2</span> <span class="kw">and</span> p[<span class="dv">1</span>] <span class="op">==</span> <span class="st">&#39;*&#39;</span>:</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>        outcome <span class="op">=</span> (</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>            <span class="co"># skip star:</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>            match_pattern_dp(s, p[<span class="dv">2</span>:], cache)</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>            <span class="co"># or use star:</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">or</span> <span class="bu">len</span>(s)</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_char(s[<span class="dv">0</span>], p[<span class="dv">0</span>])</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_pattern_dp(s[<span class="dv">1</span>:], p, cache)</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>        )</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>        outcome <span class="op">=</span> (</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>            <span class="bu">len</span>(s)</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_char(s[<span class="dv">0</span>], p[<span class="dv">0</span>])</span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>            <span class="kw">and</span> match_pattern_dp(s[<span class="dv">1</span>:], p[<span class="dv">1</span>:], cache)</span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>        )</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a>    cache[(s, p)] <span class="op">=</span> outcome</span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> outcome</span></code></pre></div>
<p>With the cache in place, whenever we run into a subproblem we’ve seen before, we can just look up
its answer.</p>
<p>Just by looking this program, however, it’s not so obvious what the time complexity is. Instead,
it’s more illuminating to look at the tree again:</p>
<p><img class="figure" src="/figures/2024-09-13-repeated-work.svg"></p>
<p>With the addition of the cache, it doesn’t matter anymore by what path we arrive at a particular
subproblem. We can visualize this by fusing the duplicated middle nodes.</p>
<p><img class="figure" src="/figures/2024-09-13-no-repeated-work.svg"></p>
<p>Imagining that we continue fusing duplicated middle nodes all the way, the structure that this
top-down memoizing algorithm ends up exploring takes the shape of a <em>rectangle.</em></p>
<p><img class="figure" src="/figures/2024-09-13-no-repeated-work-all-the-way.svg"></p>
<p>To determine the time complexity of our algorithm, it suffices to count the nodes in the rectangle.
One side’s length is bounded by the length of <code>s</code> – let’s call that <span class="math inline">\(n\)</span> – and the other side’s
length is bounded by the length of <code>p</code> – let’s call that <span class="math inline">\(m\)</span>. We get an <span class="math inline">\(O(n\times m)\)</span> complexity
overall then.</p>
<p>Equipped with this better understanding of this problem’s underlying structure, we can exploit this
structure to design an even better implementation.</p>
<h3 id="strategy-2-bottom-up-table-construction">Strategy 2: bottom-up table construction</h3>
<p>Function calls are slow. Rather than express the exploration of the problem’s rectangular state
space as a recursive function + a hashtable, we can instead <em>directly</em> build the rectangle as a
matrix, using nested loops. CPUs hate function calls, but <em>love</em> loops.
Of course, this won’t improve the asymptotic complexity of the algorithm – it will still be <span class="math inline">\(O(n \times m)\)</span> – but the constant factors, which matter in Real Life, will be better.</p>
<p>The game plan is to write a function that will construct a 2D array <code>T</code>, such that <code>T[i][j]</code> holds
the answer to the problem “does the pattern formed by taking the last <code>i</code> characters of <code>p</code> match
the string obtained by taking the last <code>j</code> characters of <code>s</code>.”</p>
<p>Sheesh. That’s a complicated definition. I picked it because it really is a bottom-up version of
what we did in the previous section.</p>
<ul>
<li>The base case of the recursive algorithm ends up in <code>T[0][0] = True</code> – the empty pattern matches
the empty string.</li>
<li>But wait, there’s more base case: an empty pattern can never match a nonempty string;
that’s the rest of the first row of <code>T</code>.
We’ll set <code>T[0][j] = False</code> for all <code>j&gt;0</code> up to and including <code>len(s)</code>.</li>
<li>Then, we build <code>T</code> row by row until we’ve filled in <code>T[len(p)][len(s)]</code>, which holds the answer
to the full problem.
<ul>
<li><code>T[i][0]</code> (for <code>i&gt;0</code>) asks “does the pattern formed from the last <code>i</code> characters of <code>p</code> match
the empty string?”
<ul>
<li>This is possible only when that pattern’s head is starred, and when <code>T[i-1][0]</code> is <code>True</code></li>
</ul></li>
<li>the value of <code>T[i][j]</code> (for <code>i&gt;0</code> and <code>j&gt;0</code>) depends crucially on <code>p[-i]</code>
<ul>
<li>If it’s unstarred, then take the AND of <code>T[i-1][j-1]</code> – does the rest of the pattern
match the rest of the string? – and whether <code>p[-i]</code> matches <code>s[-j]</code>.</li>
<li>If it’s starred, then take the OR of the skip star and use star calculations.</li>
<li>Skip star is easy: it’s precisely <code>T[i-1][j]</code></li>
<li>Use star on the other hand, has us check that <code>p[-i]</code> match <code>s[-j]</code> and AND that with
<code>T[i][j-1]</code>.</li>
</ul></li>
</ul></li>
</ul>
<p>To simplify the implementation slightly, we’ll preprocess the input pattern <code>p</code> to ‘tokenize’ it.
This process will turn a pattern like <code>ba*a*bb*c</code> into <code>['b', 'a*', 'a*', 'b', 'b*', 'c']</code>. This
avoids an uncomfortable situation where we take e.g. the last two characters of that pattern,
giving the illegal pattern <code>*c</code>.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> preprocess(p):</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    out <span class="op">=</span> []</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    i <span class="op">=</span> <span class="dv">0</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> i <span class="op">&lt;</span> <span class="bu">len</span>(p):</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> i<span class="op">+</span><span class="dv">1</span> <span class="op">&lt;</span> <span class="bu">len</span>(p) <span class="kw">and</span> p[i<span class="op">+</span><span class="dv">1</span>] <span class="op">==</span> <span class="st">&#39;*&#39;</span>:</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>            out.append(p[i:i<span class="op">+</span><span class="dv">2</span>])</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>            i <span class="op">+=</span> <span class="dv">2</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">else</span>:</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>            out.append(p[i])</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>            i <span class="op">+=</span> <span class="dv">1</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> out</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> match_pattern_tabular(s, p):</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    p <span class="op">=</span> preprocess(p)</span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>    T <span class="op">=</span> [[<span class="va">True</span>] <span class="op">+</span> [<span class="va">False</span>] <span class="op">*</span> <span class="bu">len</span>(s)]</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> i <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">1</span>, <span class="bu">len</span>(p) <span class="op">+</span> <span class="dv">1</span>):</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>        p_c <span class="op">=</span> p[<span class="op">-</span>i]</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>        T[i][<span class="dv">0</span>] <span class="op">=</span> p_c.endswith(<span class="st">&#39;*&#39;</span>) <span class="kw">and</span> T[i<span class="op">-</span><span class="dv">1</span>][<span class="dv">0</span>]</span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> j <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">1</span>, <span class="bu">len</span>(s) <span class="op">+</span> <span class="dv">1</span>):</span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>            c <span class="op">=</span> s[<span class="op">-</span>j]</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>            T[i][j] <span class="op">=</span> (</span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>                match_char(p_c, c) <span class="kw">and</span> T[i<span class="op">-</span><span class="dv">1</span>][j<span class="op">-</span><span class="dv">1</span>]</span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> <span class="kw">not</span> p_c.endswith(<span class="st">&#39;*&#39;</span>) <span class="cf">else</span> (</span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>                    <span class="co"># use star</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>                    match_char(p_c[<span class="dv">0</span>], c) <span class="kw">and</span> T[i][j<span class="op">-</span><span class="dv">1</span>]</span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a>                    <span class="co"># skip star</span></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">or</span> T[i<span class="op">-</span><span class="dv">1</span>][j]</span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>                )</span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a>            )</span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> T[<span class="bu">len</span>(p)][<span class="bu">len</span>(s)]</span></code></pre></div>
<p>The nested loops in this approach make obvious the <span class="math inline">\(O(n \times m)\)</span> time complexity.</p>
<p>We could further improve the memory usage of this approach by observing that only the previous row
is needed to compute the next row. I leave that as an exercise to the reader.</p>
<h2 id="the-general-solution-interpret-an-nfa">The general solution: interpret an NFA</h2>
<p>I was first intrigued by this Leetcode problem because it had me remember my theory of computation
class. We spent quite some time in that course talking about different kinds of automata, which are
(idealized) models of computation. I learned in that course that regular expressions correspond to
nondeterministic finite automata (NFAs), and that a regex can be converted into an NFA according to
an algorithm called <a href="https://en.wikipedia.org/wiki/Thompson%27s_construction">Thompson’s
construction</a>. Yes, that’s Ken Thompson,
co-creator of Unix!</p>
<h3 id="but-whats-an-nfa">But what’s an NFA?</h3>
<p>Let’s start with an example. Here’s an NFA that corresponds to the regex <code>a*b*c</code>:</p>
<p><img class="figure" src="/figures/2024-09-13-nfa-regex.svg"></p>
<p>This diagram is a representation of an abstract machine into which we input a string, that
either accepts or rejects the string.</p>
<p>Fundamentally, an NFA is a <em>state machine.</em> The circles in the diagram are the different states the
machine can be in. The letters inside the states are just some arbitrary names for those states.
The arrows are the <em>transitions</em> of the machine, and the label of an arrow indicates what letter we
need to see at the head of the string to advance to the corresponding state on the rest of the
string. However, the label <span class="math inline">\(\epsilon\)</span> is special: this is a transition that we can make “for free”
without needing to consume the head letter from the string.</p>
<p>The machine <em>accepts</em> a given string if after processing the whole string, the machine is in an
<em>accepting</em> state, indicated by the double circle. The machine rejects the string under two
situations.</p>
<ol type="1">
<li>The machine’s current state cannot accept the head letter of the string.</li>
<li>The string becomes empty while the machine is not in an accepting state.</li>
</ol>
<p>An NFA is <em>nondeterministic.</em> What that means is that the transition to take to move to the next
state isn’t (always) uniquely determined. For example, in the first state on the left (or the
second one), we could follow the <span class="math inline">\(a\)</span> (or <span class="math inline">\(b\)</span>) transition or the <span class="math inline">\(\epsilon\)</span> transition whenever the
head of the string is an <code>a</code> (or <code>b</code>, respectively). More generally, NFAs might have multiple
transitions with the same label.</p>
<p>This somewhat complicates the idea of “accepting” a string. How does the NFA “know” which choice to
make, when more than one transition is possible? It doesn’t know! This is a mathematical object,
after all. In reality, the acceptance criterion for an NFA is more precisely that there <em>exist</em> a
sequence of transitions that consumes the entire input string and ends on an accepting state.</p>
<p>But let’s not get ahead of ourselves. Before we see how to discover whether such a sequence of
transitions exists, we need to decide how to represent an NFA in code, and how to translate a regex
into an NFA.</p>
<h3 id="constructing-an-nfa-from-a-regex">Constructing an NFA from a regex</h3>
<p>Fortunately, the regex in this problem are not really regex! Therefore, we don’t need to implement
the entire Thompson construction. Just a part of it will do.</p>
<p>First, let’s choose a way of representing an NFA. We’ll identify the states of the NFA with
numbers, and use an array to represent the NFA itself. Indexing into that array at <span class="math inline">\(i\)</span> will give us
a description of the transitions that are possible in state <span class="math inline">\(i\)</span>. We’ll describe a set of
transitions as a list of key-value pairs, with the key being the letter we need to see and the
value being the state index to move to in that case. To represent <span class="math inline">\(\epsilon\)</span>-moves, we’ll use the
empty string.</p>
<p>We can represent the NFA from before, for the regex <code>a*b*c</code>, as the following.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>abc <span class="op">=</span> [</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    [(<span class="st">&#39;a&#39;</span>, <span class="dv">0</span>), (<span class="st">&#39;&#39;</span>, <span class="dv">1</span>)],</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    [(<span class="st">&#39;b&#39;</span>, <span class="dv">1</span>), (<span class="st">&#39;&#39;</span>, <span class="dv">2</span>)],</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    [(<span class="st">&#39;c&#39;</span>, <span class="dv">3</span>)],</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    [],</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>]</span></code></pre></div>
<p>Due to the simplified nature of the regex in this problem, we’ll always have a unique accepting
state, and it will always be the last state in the list.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> regex_to_nfa(p):</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    nfa <span class="op">=</span> []</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    i <span class="op">=</span> <span class="dv">0</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> i <span class="op">&lt;</span> <span class="bu">len</span>(p):</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        new_state_index <span class="op">=</span> <span class="bu">len</span>(nfa)</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> i <span class="op">+</span> <span class="dv">1</span> <span class="op">&lt;</span> <span class="bu">len</span>(p) <span class="kw">and</span> p[i<span class="op">+</span><span class="dv">1</span>] <span class="op">==</span> <span class="st">&#39;*&#39;</span>:</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>            new_state <span class="op">=</span> [ (<span class="st">&#39;&#39;</span>, new_state_index <span class="op">+</span> <span class="dv">1</span>), (p[i], new_state_index) ]</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>            i <span class="op">+=</span> <span class="dv">2</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">else</span>:</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>            new_state <span class="op">=</span> [ (p[i], new_state_index <span class="op">+</span> <span class="dv">1</span>) ]</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>            i <span class="op">+=</span> <span class="dv">1</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>        nfa.append(new_state)</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>    nfa.append([]) <span class="co"># the accepting state</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> nfa</span></code></pre></div>
<p>Equipped with a Python model of NFAs and a procedure for constructing an NFA from a regex, we’re
ready to tackle the nondeterminism of the NFA to discover how to actually <em>run</em> one of these
machines.</p>
<h3 id="running-an-nfa">Running an NFA</h3>
<p>The computers that we use are deterministic, so to run an NFA, we have to simulate its
nondeterminism. One way to do this is to keep track of a <em>set</em> of states that the NFA is in
simultaneously. To see how this works, let’s walk through running the NFA of the regex <code>a*b*c</code> on
the string <code>aac</code>.</p>
<ul>
<li>The initial set of states is <span class="math inline">\(\{A, B, C\}\)</span>, i.e. the state marked by “start” plus all the states
reachable from there by using only <span class="math inline">\(\epsilon\)</span>-moves.</li>
<li>For each state that the NFA is in, we check whether that state can consume the head letter <code>a</code>,
and form the set of all the states that result from following that transition + all the states
then reachable by using only <span class="math inline">\(\epsilon\)</span>-moves. The states <span class="math inline">\(B\)</span> and <span class="math inline">\(C\)</span> can’t accept <code>a</code>, so they
“die”. The state <span class="math inline">\(A\)</span>, however, <em>can</em> consume <code>a</code>, leading back to state <span class="math inline">\(A\)</span> + the states <span class="math inline">\(B\)</span> and
<span class="math inline">\(C\)</span> which are reachable from <span class="math inline">\(A\)</span> by using <span class="math inline">\(\epsilon\)</span>-moves. Therefore we get back the same set of
states, <span class="math inline">\(\{A, B, C\}\)</span>, only now the string that’s left to process is <code>ac</code>.</li>
<li>The same thing happens again, leading to the next set of states being <span class="math inline">\(\{A, B, C\}\)</span> and the
remaining string to process being just <code>c</code>.</li>
<li>States <span class="math inline">\(A\)</span> and <span class="math inline">\(B\)</span> can’t consume <code>c</code>, so they die, but state <span class="math inline">\(C\)</span> can consume <code>c</code>, leading to
state <span class="math inline">\(D\)</span>.</li>
<li>The input string runs out, and the final set of states is just <span class="math inline">\(\{D\}\)</span>.</li>
<li>Among that set of states is an accepting state, so overall the string is accepted.</li>
</ul>
<p>You also might have noticed from the description above that “all the states reachable from
there by using only <span class="math inline">\(\epsilon\)</span>-moves” shows up a few times. This concept has a fancy math-name:
it’s called the <em><span class="math inline">\(\epsilon\)</span>-closure</em> of a state. It’s easily expressed as a depth-first
search through the NFA, following only <span class="math inline">\(\epsilon\)</span>-moves. The NFAs in our setting never have
<span class="math inline">\(\epsilon\)</span>-moves that jump “backwards”, so we don’t need to worry about marking nodes as visited.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> epsilon_closure(nfa, i):</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    closure <span class="op">=</span> <span class="bu">set</span>([i]) <span class="co"># the state itself is part of the closure</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> (letter, j) <span class="kw">in</span> nfa[i]:</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> letter <span class="op">==</span> <span class="st">&#39;&#39;</span>:</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>            closure.update(epsilon_closure(nfa, j))</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> closure</span></code></pre></div>
<p>Finally, we’re ready to simulate an NFA.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> run_nfa(nfa, s):</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    active_states <span class="op">=</span> epsilon_closure(nfa, <span class="dv">0</span>)</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> c <span class="kw">in</span> s:</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>        <span class="co"># each iteration of the outermost loop</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>        <span class="co"># calculates a new set of active states.</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>        next_active_states <span class="op">=</span> <span class="bu">set</span>()</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> i <span class="kw">in</span> active_states:</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>            <span class="cf">for</span> (letter, j) <span class="kw">in</span> nfa[i]:</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> match_char(c, letter):</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>                    next_active_states.update(epsilon_closure(nfa, j))</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>        active_states <span class="op">=</span> next_active_states</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>    <span class="co"># accept or reject the string according to whether</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>    <span class="co"># the accepting state is among the active states, now that</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>    <span class="co"># the entire string has been traversed.</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="bu">len</span>(nfa)<span class="op">-</span><span class="dv">1</span> <span class="kw">in</span> active_states</span></code></pre></div>
<p>Now let’s evaluate the time complexity of <code>run_nfa</code>. The two outermost loops require that it be at
least <span class="math inline">\(O(n \times m)\)</span>, but it might be worse than that. We need to account for the call to
<code>epsilon_closure</code> that happens in the innermost loop!</p>
<p>Recall that calculating an <span class="math inline">\(\epsilon\)</span>-closure requires making a depth-first search through the NFA.
In a general graph, a depth-first search has a time complexity of <span class="math inline">\(O(V + E)\)</span>; in our setting the
vertices are the states of the NFA and the edges are the transitions. The number of transitions per
state is bounded by a constant, namely <span class="math inline">\(2\)</span> – just look at <code>regex_to_nfa</code>. Therefore, to calculate
the <span class="math inline">\(\epsilon\)</span>-closure of one state takes <span class="math inline">\(O(m)\)</span> time.</p>
<p>It suffices at this point to determine how many <span class="math inline">\(\epsilon\)</span>-closures we need to calculate. Notice
that the call to <code>epsilon_closure</code> is guarded by the condition <code>if match_char(c, letter)</code>. This
condition can be true at most once per entire loop! That’s because there are at most <span class="math inline">\(2\)</span>
transitions per state in our NFAs, and at most <span class="math inline">\(1\)</span> that’s not an <span class="math inline">\(\epsilon\)</span>-move.</p>
<p>Therefore, thanks again to the restricted nature of the regex in this problem, the simulation of
the NFAs that result from these regex still takes <span class="math inline">\(O(n \times m)\)</span> time.</p>
<p>In a general NFA, where the number of transitions per state labelled with a given letter is bounded
by the total number of states in the NFA (instead of a constant), the time complexity would be
worse.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Leetcode problem 10 is a fascinating one because it admits three different, workable solutions. The
backtracking, exponential-time algorithm is performant enough to pass the automated checker so long
as we make a simple optimization of collapsing <code>a*a*...</code> down to <code>a*</code>. The two dynamic programming
solutions admit a much better time complexity of <span class="math inline">\(O(n\times m)\)</span>.</p>
<ol type="1">
<li>The top-down implementation uses a hashtable to store previously seen solutions of subproblems.</li>
<li>The bottom-up implementation directly exploits the resulting rectangular shape of the problem’s
state space.</li>
</ol>
<p>Finally, the most theoretically rigorous and (in principle) general solution to the problem comes
from the study of the theory of computation: we translate the regular expression into a
nondeterministic finite automaton and interpret it by tracking a set of active states to simulate
the nondeterminism. Of course, thanks to the simplified nature of the regex in the problem, we were
able to cut some corners to simplify the implementation as well.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Implementing generators with continuation-passing style, streams, and defunctionalization</title>
    <link href="https://jerrington.me/posts/2023-04-02-generators-cps-streams-d17n.html" />
    <id>https://jerrington.me/posts/2023-04-02-generators-cps-streams-d17n.html</id>
    <published>2023-04-02T00:00:00Z</published>
    <updated>2023-04-02T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on April  2, 2023
    
</div>

<p>Some languages define a variant of <code>return</code> called <code>yield</code>. When a function returns normally, it’s
finished, but when a function yields, the execution context of the function is saved, enabling us
to re-enter the function to resume its execution. Such resumable functions are especially
convenient for defining lazily generated sequences. Such functions that generate sequences are
called <em>generators.</em></p>
<p>This article will first describe native generators in Python before translating the idea into OCaml
using mutable variables and continuation-passing style (CPS). Then, we will see how to eliminate
the mutable variable and how to eliminate the higher-order functions that arise from CPS, leading
to an implementation that we translate into C.</p>
<h2 id="native-generators-in-python">Native generators in Python</h2>
<p>For example, consider this recursive algorithm in Python that enumerates all truth assignments on
<code>n</code> variables. Each truth assignment is represented as a list of booleans of length <code>n</code>. The
sequence that arises from this enumeration has length <code>2^n</code> since there are two possible choices
for the value of each of the <code>n</code> variables.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> enumerate_assignments(n):</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    a <span class="op">=</span> [<span class="va">True</span>] <span class="op">*</span> n</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> go(i):</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> i <span class="op">==</span> <span class="dv">0</span>:</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>            <span class="cf">yield</span> a</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">else</span>:</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>            a[n <span class="op">-</span> i] <span class="op">=</span> <span class="va">True</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>            <span class="cf">yield</span> <span class="cf">from</span> go(i <span class="op">-</span> <span class="dv">1</span>)</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>            a[n <span class="op">-</span> i] <span class="op">=</span> <span class="va">False</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>            <span class="cf">yield</span> <span class="cf">from</span> go(i <span class="op">-</span> <span class="dv">1</span>)</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> go(n)</span></code></pre></div>
<p>In the base case when <code>i == 0</code>, the variable <code>a</code> contains a truth assignment with some <code>True</code>s and
some <code>False</code>s put in it by the stack of recursive calls that leads to the base case. We <code>yield</code>
that truth assignment, suspending execution of the function. The function, upon being re-entered,
proceeds from that <code>yield</code>, in this case returning back to its caller. The caller might be the
recursive call <code>yield from go(i - 1)</code>, after which <code>a[n - i]</code> is set to <code>False</code> and another
recursive call is made.</p>
<p>Therefore, calling this function does not generate the whole sequence at once. In fact, nothing
happens just yet if we call <code>enumerate_assignments(5)</code> except to ‘prime’ the generator to run. The
call returns a so-called <em>iterator,</em> which stores the state of the execution. Then, calling the
function <code>next()</code> on the iterator will resume execution of the function up to the next <code>yield</code>.
Also, <code>next()</code> returns to us the yielded value. Repeatedly calling <code>next()</code> until the generator
exits is exactly what a Python <code>for</code>-loop does, so we can print all the truth assignments on five
variables like this:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> a <span class="kw">in</span> enumerate_assignments(<span class="dv">5</span>):</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">print</span>(a)</span></code></pre></div>
<p>What if the language we’re working in doesn’t have <code>yield</code> though? How can we implement something
like this in, say, OCaml? In doing so, we will explore what happens under the hood of generators.</p>
<h2 id="evaluation-contexts-and-continuations">Evaluation contexts and continuations</h2>
<p>Before diving into the implementation of generators in OCaml using continuations, some background
on continuations is required.
I’ve already written an article on continuations in general <a href="/posts/2022-10-22-higher-order-continuations">here</a>, but
I’ll give a somewhat different take on the core idea in this section.</p>
<p>To motivate the discussion of continuations in this section, let’s look ahead at what we will want
to accomplish in the <em>next</em> section: we will implement a generator as a stateful function <code>next</code>.
Each time we call this function – <code>next ()</code> – it returns the next item in the sequence.
The key idea in implementing this function is that just before returning an item in the sequence,
we store the current <em>evaluation context</em> in a reference. Then, when the user of our generator
calls <code>next ()</code> again, we restore the saved evaluation context. Evaluation then proceeds from that
saved point up to the next item in the sequence.</p>
<p>I said ‘evaluation context’ several times in the last paragraph (and in the title of this section)
so it’s about time I define what that is and how it’s related to continuations.</p>
<p>When a program is “in a call to a function”, for instance, there’s somewhere that call will return
to. That location corresponds to how the return value of the function is used. Or, said
differently, that location is the <em>evaluation context.</em></p>
<p>For example, let’s imagine we have a function <code>f : unit -&gt; int</code>.
Maybe somewhere in our program there is <code>let x = f () in E</code>.
The evaluation context of that call to <code>f</code> – the way the result of <code>f</code> is used – is that it is
associated to the variable <code>x</code> in evaluating <code>E</code>.
We can write this evaluation context as <code>let x = _ in E</code> as this shows where the return value of
the call will be used. Notice that <code>let x = _ in E</code> is <em>not a program!</em> Rather, it’s a program
<em>with a hole in it.</em></p>
<p>Or as another example, perhaps the program contains <code>f () + 5</code>.
The evaluation context inside the call to <code>f</code> is that the result of the call will be added with
five.
We can write that again with this ‘hole’ syntax: <code>_ + 5</code>.</p>
<p>Of course, evaluation can reach quite deep into a subexpression.
Consider this evaluation context <code>let x = if _ &gt; 17 then E1 else E2 in E3</code>.</p>
<p>The relevant insight about evaluation contexts, which are a concept <em>outside</em> our programming
language, is that we can <em>represent</em> them <em>in</em> our programming language: we represent an evaluation
context as a function. Let’s see how this applies to the examples seen so far.</p>
<ul>
<li><code>let x = _ in E</code> is represented by <code>fun r -&gt; let x = r in E</code></li>
<li>The second example <code>_ + 5</code> is represented by <code>fun r -&gt; r + 5</code></li>
<li>The last example <code>let x = if _ &gt; 5 then E1 else E2 in E3</code>
is represented by <code>fun r -&gt; let x = if r &gt; 5 then E1 else E2 in E3</code></li>
</ul>
<p>This functional representation of an evaluation context is called a <em>continuation</em>.</p>
<p>Now that we have a way of representing evaluation contexts as continuations, we can write OCaml
programs that manipulate continuations. Since continuations are functions, we cannot inspect them:
we can only construct them and call them. Calling a continuation <code>k</code> with an argument <code>a</code>
represents filling the hole in the evaluation context represented by <code>k</code> with the value <code>a</code> and
proceeding to evaluate the resulting expression.</p>
<p>For example, if <code>k</code> is the continuation <code>fun r -&gt; let x = if r &gt; 5 then E1 else E2 in E3</code> and we
apply this to <code>3</code>, then evaluation <em>continues</em> from the point where the value of the hole <code>_</code> was
required in the represented evaluation context, namely in computing <code>_ &gt; 5</code>. The value of <code>3 &gt; 5</code>
is needed in the context <code>if _ then E1 else E2</code>, and the value of that if-then-else expression is
needed in the context <code>let x = _ in E3</code>. From this apparent nestedness of evaluation contexts, we
can observe that the contexts form a <em>stack.</em> This observation will be expanded on considerably in
the last section of this article when we translate these ideas into C.</p>
<pre><code>    (fun r -&gt; let x = if r &gt; 5 then E1 else E2 in E3) 3
==&gt; let x = if 3 &gt; 5 then E1 else E2 in E3    -- substitute 3 for r
==&gt; let x = if true then E1 else E2 in E3     -- compute &#39;&gt;&#39;
==&gt; let x = E1 in E3                          -- select then-branch
==&gt; ...</code></pre>
<p>Great, evaluation contexts can be represented as functions called continuations and our programs
can use continuations by calling them. Calling a continuation corresponds to filling the hole in
the represented evaluation context and continuing the evaluation from there.</p>
<p>The big idea of <em>continuation-passing style</em> (CPS) is to equip the functions we write with an
extra parameter. You guessed it, that extra parameter is the continuation of the function. So
instead of having a function <code>f : A -&gt; int</code> that we use like <code>f a + 5</code>, we instead write <code>f a (fun r -&gt; r + 5)</code>. The upshot is that in the implementation of <code>f</code>, we will have access to (a
representation of) the evaluation context in which the call to <code>f</code> takes place!</p>
<p>In traditional CPS, functions no longer ‘return normally’. Instead, they return by calling the
continuation with the value they want to return. In our current setting of implementing generators,
this isn’t quite what we want. We would like our functions to return normally – this is how the
generator will emit a value – but we nonetheless want access to the evaluation context so that we
can store it in a reference just before returning. This will enable us to resume the function from
the point where it emitted a value. In the next section, we’ll see how we can transform the Python
code from the beginning of the article into OCaml using this form of CPS.</p>
<h2 id="implementing-generators-using-state-and-cps">Implementing generators using state and CPS</h2>
<p>In this section, we mimic Python’s approach to generators: generators in Python are stateful
objects, so our implementation in this section will use a reference to store an evaluation context.</p>
<p>To come up with our OCaml implementation, let’s first translate the Python program from the first
section into pseudo-OCaml with <code>yield</code> &amp; <code>yield from</code>. Rather than use a mutable array to construct
the truth assignment, we’ll build it up one value at a time in a parameter.</p>
<aside>
<p>Since the function we will eventually write is tail-recursive, the list pointer in this parameter
will actually be mutated. Although this isn’t the same as using a genuinely mutable array, there
will be some mutation in the resulting program.</p>
</aside>
<div class="sourceCode" id="cb4"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> go n a =</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>            yield a</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span> <span class="kw">begin</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>            yield from go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a);</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>            yield from go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a)</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    go n []</span></code></pre></div>
<p>Let’s concentrate specifically on the inner function <code>go</code>. We will need to find a way to represent
<code>yield</code> and <code>yield from</code> in genuine OCaml. First, let’s deal with <code>yield</code>.</p>
<p>Operationally, <code>yield</code> saves the current evaluation context and emits the given value.
We choose to represent ‘emitting a value’ as simply returning. To gain access to the current
evaluation context so that we can save it, we rewrite <code>go</code> in CPS. We also introduce a <code>ref</code> to
store the evaluation context.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> state = <span class="dt">ref</span> <span class="co">(* what to put here initially ? *)</span> <span class="kw">in</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>        (state := next; a)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> <span class="kw">begin</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>        yield from go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a);</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>        yield from go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a)</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">end</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="kw">in</span> ...</span></code></pre></div>
<p>Next, let’s address <code>yield from</code>. This keyword causes the current generator to invoke a
‘sub-generator’ and to yield all of its values.</p>
<aside>
<p>In Python, we have the following interpretation of <code>yield from E</code>:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> x <span class="kw">in</span> E:</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">yield</span> x</span></code></pre></div>
</aside>
<p>Since we choose to represent yielding a value as simply returning it, we implement <code>yield from go ...</code>
as simply calling <code>go</code>. In doing so however, we must pass <code>go</code> a continuation. We can determine
what continuation to pass by looking at the evaluation context of <code>yield from go (n-1) (true :: a)</code>:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>_; yield from go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a)</span></code></pre></div>
<p>We represent this evaluation context as a function: <code>fun x -&gt; x; yield from go (n-1) (false :: a)</code>.
Since <code>yield from</code> does not compute anything – it performs an <em>effect</em> – we observe that
<code>x : unit</code>. A value of type <code>unit</code> does not convey any information, so we simplify to <code>fun () -&gt; yield from go (n-1) (false :: a)</code>.</p>
<p>Next we must translate the inner <code>yield from go ...</code> which appears inside the continuation. Again,
we translate this simply to a call to <code>go</code>, but in doing so we must decide what continuation to
pass in this call. We ask ourselves what evaluation context this call takes place in: what
happens next, after <code>yield from go (n-1) (false :: a)</code> finishes generating its sequence of values?
The answer is that <code>go</code> returns to its caller. In other words, the evaluation context of <code>yield from go (n-1) (false :: a)</code> is the evaluation context of <code>go</code> itself, which was passed to <code>go</code> in
the continuation <code>next</code>. Therefore, the continuation we pass to this second call to <code>go</code> is simply
<code>next</code>.</p>
<p>Let’s take stock of the translation so far:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> state = <span class="dt">ref</span> <span class="co">(* ? *)</span> <span class="kw">in</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>        (state := next; a)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="kw">in</span> ...</span></code></pre></div>
<p>Let’s zoom out, look at <code>enumerate_assignments</code> again, and see how we can fit it together with
our adjusted <code>go</code>.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> state = <span class="dt">ref</span> <span class="co">(* ? *)</span> <span class="kw">in</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>            (state := next; a)</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>            go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>    go n [] <span class="co">(* ? *)</span></span></code></pre></div>
<p>Calling <code>go</code> right away at the end of <code>enumerate_assignments</code> can’t be correct anymore. This
will return the first item of the sequence, and then we’ll have no way to call the stored
continuation to get the next one!</p>
<p>Instead, we need to adjust the return type of <code>enumerate_assignments</code>. Let’s look back to the
pseudocode using <code>yield</code> and <code>yield from</code> to inform how.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> go n a =</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>            yield a</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span> <span class="kw">begin</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>            yield from go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a);</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>            yield from go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a)</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">end</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>    go n []</span></code></pre></div>
<p>First of all, what is <em>this</em> <code>enumerate_assignments</code> supposed to return? What is the return type of
<code>go</code> in this pseudocode? If we think back to the original Python implementation, it was returning
an <em>iterator</em>. This is some kind of object that holds the suspended execution state. We call the
function <code>next()</code> on this iterator to resume execution up to the next <code>yield</code>.</p>
<p>We can imagine in our OCaml pseudocode that <code>go</code> returns something of type <code>bool list gen</code> and
therefore that <code>enumerate_assignments n : bool list gen</code>. We can further imagine that there’s a
function <code>next : 'a gen -&gt; 'a option</code> which pumps the generator for one more item. This
hypothetical <code>next</code> returns an <code>option</code> because the sequence can end and we need a way to
signal this.</p>
<p>Now we need to turn the fantasy of the type <code>'a gen</code> and its associated function
<code>next : 'a gen -&gt; 'a option</code>
into reality. Here there are several approaches available to us, but one particularly clean one
using higher-order functions is to represent <code>'a gen</code> as a function <code>unit -&gt; 'a option</code>. Then,
<code>next</code> becomes trivial to implement.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> next f = f ()</span></code></pre></div>
<p>Hence, we implement <code>enumerate_assignments</code> to return a function <code>unit -&gt; bool list option</code>, such
that each time this function is called, it emits the next item in the sequence.</p>
<aside>
<p>This analysis <em>identifies</em> the generator with its <code>next</code> function. Since the thing we care to do
to a generator is to call <code>next</code> on it, we can represent the generator itself with such a function.</p>
</aside>
<div class="sourceCode" id="cb12"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> state = <span class="dt">ref</span> <span class="co">(* ? *)</span> <span class="kw">in</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>            (state := next; a)</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>            go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* previously: go n [] *)</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">fun</span> () -&gt; ???</span></code></pre></div>
<p>We’re almost finished now. What’s left is to make it so that the first time the returned function
is called, it emits the first item in the sequence.</p>
<p>The missing insight has to do with the initial value of <code>state</code>: it should be a function that makes
the initial call <code>go n []</code>. This makes it so that the ‘driver function’ returned by
<code>enumerate_assignments</code> can be implemented as <code>fun () -&gt; !state ()</code>. Recall that the state stores a
function that generates the next item in the sequence, so initially we store the function that
generates the first item of the sequence <code>fun () -&gt; go n []</code>. Moreover, we implemented <code>go</code> to save
the current continuation back into the <code>state</code> just before it returns. Therefore, the next time the
driver function is called, it emits the next item in the sequence!</p>
<p>But there’s a small wrinkle in <code>fun () -&gt; go n []</code>: there’s an argument missing! What continuation
do we pass in this initial call to go?</p>
<p>The continuation passed here ends up saved by <code>go</code> in <code>state</code> after the whole sequence of truth
assignments is generated. Therefore, we need to arrange that when this continuation ends up stored,
the driver function returns <code>None</code>. The driver function has the form <code>fun () -&gt; !state ()</code>, so this
initial continuation passed to <code>go</code> ought to be <code>fun () -&gt; None</code>.</p>
<p>But previously, the continuation had the type <code>unit -&gt; 'a</code>, so we need to adjust <code>go</code> slightly to
accommodate this change. This leads to the finalized generator using CPS and state.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>            <span class="co">(* we wrap the next item in Some *)</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>            (state := next; <span class="dt">Some</span> a)</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>            go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">and</span> state = <span class="dt">ref</span> (<span class="kw">fun</span> () -&gt; go n [] (<span class="kw">fun</span> () -&gt; <span class="dt">None</span>))</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* and arrange that the last continuation to be stored in</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a><span class="co">       `state` just returns `None`. *)</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">fun</span> () -&gt; !state ()</span></code></pre></div>
<p>Now the state reference, which initially contains a call to <code>go</code>, must be mutually recursive with
<code>go</code>, which refers back to the state reference.</p>
<p>Let’s witness the fruits of our handiwork. Here’s an OCaml REPL demonstrating the generator.</p>
<pre><code>&gt; let next = enumerate_assignments 5 ;;
val next : unit -&gt; bool list option = &lt;fun&gt;

&gt; next () ;;
- : bool list option = Some [true; true; true; true; true]

&gt; next () ;;
- : bool list option = Some [false; true; true; true; true]

&gt; next () ;;
- : bool list option = Some [true; false; true; true; true]

&gt; next () ;;
- : bool list option = Some [false; false; true; true; true]</code></pre>
<p>In the next section, we explore how to eliminate the mutable variable from this implementation.
This will give rise to an implementation suitable to purely functional languages, which lack
(genuine) mutable variables.</p>
<h2 id="eliminating-state">Eliminating state</h2>
<p>The implementation we have arrived at can be made stateless. Notice that there are two ways that
the driver function <code>fun () -&gt; !state ()</code> can return: it can return <code>Some a</code> after storing the
continuation, or it can return <code>None</code> which happens when the sequence ends and the initial
continuation <code>fun () -&gt; None</code> has been stored in the variable <code>state</code>.</p>
<p>Rather than store the continuation in some hidden stateful variable, we can simply return <em>both</em>
the assignment <em>and</em> the continuation in the <code>Some</code> case. That gives rise to the following
intuitive implementation.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Some</span> (a, next) <span class="co">(* return the value _and_ the continuation *)</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>      go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  go n [] (<span class="kw">fun</span> () -&gt; <span class="dt">None</span>)</span></code></pre></div>
<p>Slight problem with this implementation: it doesn’t typecheck! And the error is not a simple
“expect this type, got this other type,” but rather</p>
<pre><code>Error: The expression `go (n-1) (false :: a) next`
       has type (bool list * (unit -&gt; &#39;a)) option
       but an expression was expected of type &#39;a
       The type variable &#39;a occurs inside (bool list * (unit -&gt; &#39;a)) option</code></pre>
<p>According to this error, the return type of <code>go</code>, which is so far inferred as
<code>(bool list * (unit -&gt; 'a)) option</code> (due to the expression <code>Some (a, next)</code>) has to equal the
return type of <code>next</code> which is so far inferred as <code>'a</code>. This circularity is forbidden, so OCaml
rejects the program.</p>
<p>We can resolve this by introducing a recursive type, let’s say <code>L</code>,
such that <code>L = (bool list * (unit -&gt; L)) option</code>. The base case of this recursive type arises from
the <code>None</code> constructor of the <code>option</code> type. Now we can fix the circular variable type variable
<code>'a</code> to be <code>L</code> and eliminate the forbidden circular instantiation.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> l = Next <span class="kw">of</span> (<span class="dt">bool</span> <span class="dt">list</span> * (<span class="dt">unit</span> -&gt; l)) <span class="dt">option</span></span></code></pre></div>
<aside>
<p>Notice that the constructor <code>Next</code> witnesses the recursive equality
<code>L = (bool list * (unit -&gt; L)) option</code>. We see <code>Next : (bool list * (unit -&gt; l)) option -&gt; l</code>
witnessing one direction of the equality, and since <code>l</code> has only one constructor, pattern matching
on a value of type <code>l</code> witnesses the other direction.</p>
</aside>
<p>We can slightly refactor this type by introducing a second constructor and eliminating the
<code>option</code>.</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> l =</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  | Done</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  | More <span class="kw">of</span> <span class="dt">bool</span> <span class="dt">list</span> * (<span class="dt">unit</span> -&gt; l)</span></code></pre></div>
<p>And we can generalize the type by replacing <code>bool list</code> with a type variable.</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> &#39;a l =</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  | Done</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  | More <span class="kw">of</span> &#39;a * (<span class="dt">unit</span> -&gt; &#39;a l)</span></code></pre></div>
<p>And would you look at that! This is simply a list, but whose tail is computed by a function <code>unit -&gt; 'a l</code> rather than being already materialized.</p>
<p>Now we’re equipped to rewrite <code>enumerate_assignments</code> but having the type
<code>int -&gt; unit -&gt; bool list l</code>.</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>      More (a, next) <span class="co">(* return the value _and_ the continuation *)</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>      go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">fun</span> () -&gt; go n [] (<span class="kw">fun</span> () -&gt; Done)</span></code></pre></div>
<p>Have we achieved our goal of making <code>enumerate_assignments</code> stateless? Yes and no.</p>
<p>Indeed we have eliminated the mutable variable, so on the one hand we can say “mission
accomplished.” But on the other hand, the state of the walk through the space of truth assignments
is still very much present in our program. That state is captured in the continuation, which is
returned explicitly via the <code>More</code> constructor of our <em>lazy list</em> type <code>l</code>. The state of our
generator implementation is no longer mutable and hidden, but rather immutable and explicitly
passed around. We can therefore view lazy lists as <em>purely functional generators.</em></p>
<p>Another consideration is that in order to make this approach work in a strongly and statically
typed setting as in OCaml, we did need to introduce the recursive type <code>l</code>. In the setting of a
different type system, this might not be necessary. For instance, in a dynamically-typed setting,
e.g. in Python, it is unnecessary to introduce an extra type: we can simply return <code>None</code> when the
sequence ends and <code>(a, next)</code> when the sequence continues.</p>
<p>In the next section, we revisit our implementation using hidden, mutable state, and eliminate from
it the higher-order functions. This will give rise to a first-order implementation suitable for
translation into a language such as C, which is moreover well-equipped to handle mutable state.</p>
<h2 id="defunctionalizing-the-continuation-of-a-generator">Defunctionalizing the continuation of a generator</h2>
<p>Recall from the first section the <code>enumerate_assignments</code> implementation using mutable state.</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>      (state := next; <span class="dt">Some</span> a)</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>      go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">and</span> state = <span class="dt">ref</span> (<span class="kw">fun</span> () -&gt; go n [] (<span class="kw">fun</span> () -&gt; <span class="dt">None</span>))</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span></span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">fun</span> () -&gt; !state ()</span></code></pre></div>
<p>We can apply <em>defunctionalization</em> to eliminate the higher-order functions present in this program
(see <a href="/posts/2023-02-12-defunctionalizing-continuations.html">here</a>). In short, we replace each function type <span class="math inline">\(T = T_1 \to T_2\)</span> that occurs in the
program with a new datatype <span class="math inline">\(D(T)\)</span>. Then, for each function
<span class="math inline">\(\Gamma \vdash \text{fun}\, x \to e_i : T_1 \to T_2\)</span>, define a
constructor <span class="math inline">\(C_i : P(\Gamma) \to D(T)\)</span> where <span class="math inline">\(P(x_1 : S_1, \ldots, x_n : S_n) = (S_1, \ldots, S_n)\)</span>. Next, define the function <span class="math inline">\(\text{apply}\, : D(T) \to T1 \to T2\)</span> as follows (in pseudo-OCaml)</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> apply (f : D(T)) (x : T1) : T2 = <span class="kw">match</span> f <span class="kw">with</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>  | C_i (x1, ..., xN) -&gt; e_i</span></code></pre></div>
<p>In other words, the function <code>apply</code> takes the <em>representation</em> <span class="math inline">\(f : D(T)\)</span> of the original
function and recovers the original function: notice that <span class="math inline">\(\text{apply}\, f : T_1 \to T_2\)</span> has the
original function’s type!</p>
<p>Concretely for <code>enumerate_assignments</code>, we introduce a type <code>stack</code> to represent the function type
<code>unit -&gt; bool list option</code>.
There are three functions of this type passed as arguments to other functions.</p>
<ul>
<li><code>fun () -&gt; go n [] (fun () -&gt; None)</code>: this is the initial continuation and it contains a free
variable <code>n : int</code>. We generate from this a constructor <code>Start : int -&gt; stack</code>.</li>
<li><code>fun () -&gt; None</code>: this is the final continuation and it contains no free variables. We generate a
constructor <code>Finished : stack</code></li>
<li><code>fun () -&gt; go (n-1) (false :: a) next</code>: this is the continuation passed when making a recursive
call to <code>go</code>. It has the free variables <code>n : int</code>, <code>a : bool list</code>, and
<code>next : unit -&gt; bool list option</code>.
Notice that the function we’re translating refers to a function of the type we’re
defunctionalizing. This will make our type <code>stack</code> into a recursive type. Moreover, since the new
continuation defined by this anonymous function refers to exactly one other continuation, we are
finally justified in calling our type “stack”: these continuations were implicitly forming a
linked list that now is explicitly represented.
From this analysis we generate the constructor <code>Continue : int * bool list * stack -&gt; stack</code>.</li>
</ul>
<p>We will make a small refactoring: we will separate the “stack frames” from the stack by introducing
a type <code>frame</code> and changing the constructor <code>Continue</code> to instead have the type
<code>Continue : frame * stack -&gt; stack</code>.</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> frame = { n : <span class="dt">int</span>; a : <span class="dt">bool</span> <span class="dt">list</span> }</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> state =</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  | Start</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>  | Continue <span class="kw">of</span> frame * state</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>  | Finished</span></code></pre></div>
<p>Equipped with this representation of the functions of type <code>unit -&gt; bool list option</code> occurring in
the program, we can translate <code>enumerate_assignments</code> to use these constructors instead of using
anonymous functions. Anywhere we <em>call</em> an anonymous function, we instead call the function <code>apply</code>
that we implement to recover the behaviour of the anonymous function.
The parameter <code>next : unit -&gt; bool list option</code> becomes <code>s : stack</code>.</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> state = <span class="dt">ref</span> (Start n) <span class="kw">in</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">(* ^ previously: fun () -&gt; go n [] (fun () -&gt; None) *)</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> <span class="kw">rec</span> go n a s =</span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>      (state := s; <span class="dt">Some</span> a)</span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>     go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (Continue ({n; a}, s))</span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>     <span class="co">(* ^ previously: fun () -&gt; go (n-1) (false :: a) next *)</span></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>  <span class="co">(* Apply pops a frame from the stack and runs until the next item is produced, if any.</span></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a><span class="co">     When `go` runs, it will manipulate the stack, saving it into `state` in particular right</span></span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a><span class="co">     before returning `Some a`. *)</span></span>
<span id="cb24-13"><a href="#cb24-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">and</span> apply s = <span class="kw">match</span> s <span class="kw">with</span></span>
<span id="cb24-14"><a href="#cb24-14" aria-hidden="true" tabindex="-1"></a>    | Start n -&gt; go n [] Finished</span>
<span id="cb24-15"><a href="#cb24-15" aria-hidden="true" tabindex="-1"></a>    | Continue ({n; a}, s) -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) s</span>
<span id="cb24-16"><a href="#cb24-16" aria-hidden="true" tabindex="-1"></a>    | Finished -&gt; <span class="dt">None</span></span>
<span id="cb24-17"><a href="#cb24-17" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span></span>
<span id="cb24-18"><a href="#cb24-18" aria-hidden="true" tabindex="-1"></a>  <span class="co">(* And now we have implemented a function `unit -&gt; bool list option` without using any</span></span>
<span id="cb24-19"><a href="#cb24-19" aria-hidden="true" tabindex="-1"></a><span class="co">     higher-order functions internally! *)</span></span>
<span id="cb24-20"><a href="#cb24-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">fun</span> () -&gt; apply !state</span></code></pre></div>
<p>This program is now completely first-order with the exception of the “higher-order interface”
provided at the very end in the form of the function <code>fun () -&gt; apply !state</code>.</p>
<p>This first-order nature will make it possible for us to (somewhat) straightforwardly translate this
into C. Of course, we can translate it “as is”, which would mean using a linked list structure for
the type <code>stack</code> and for the type <code>bool list</code>, but since we’re going lower-level, we may as well
choose more efficient representations for these types too.</p>
<h3 id="translating-to-c">Translating to C</h3>
<p>The resulting C program is around 100 lines of code whereas the defunctionalized OCaml program
is around 20 lines of code. (Both counts ignore blank lines and comments.) We need the following
includes in this development.</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;stdint.h&gt;</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;stdlib.h&gt;</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;stdio.h&gt;</span></span></code></pre></div>
<p>Our first choice for efficient data representation will be to represent <code>bool list</code> as simply
<code>uint64_t</code>. This limits the number of variables to 64, but it also has the nice property that on a
64-bit machine such as most, a truth assignment fits into a register.
We will need to define some operations for setting and clearing specific bits.</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">typedef</span> <span class="dt">uint64_t</span> truth_assignment<span class="op">;</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="kw">typedef</span> <span class="dt">uint8_t</span> var_index<span class="op">;</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>truth_assignment set_true<span class="op">(</span>truth_assignment a<span class="op">,</span> var_index i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> a <span class="op">|</span> <span class="op">(</span><span class="dv">1</span><span class="bu">UL</span> <span class="op">&lt;&lt;</span> i<span class="op">);</span></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>truth_assignment set_false<span class="op">(</span>truth_assignment a<span class="op">,</span> var_index i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> a <span class="op">&amp;</span> <span class="op">~(</span><span class="dv">1</span><span class="bu">UL</span> <span class="op">&lt;&lt;</span> i<span class="op">);</span></span>
<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb26-11"><a href="#cb26-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-12"><a href="#cb26-12" aria-hidden="true" tabindex="-1"></a>truth_assignment <span class="dt">const</span> EMPTY_TRUTH_ASSIGNMENT <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span></code></pre></div>
<p>Next, we will translate the type <code>frame</code> from the OCaml implementation into a simple C struct.</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> frame <span class="op">{</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>    var_index i<span class="op">;</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>    truth_assignment a<span class="op">;</span></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> frame make_frame<span class="op">(</span>var_index i<span class="op">,</span> truth_assignment a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">(</span><span class="kw">struct</span> frame<span class="op">)</span> <span class="op">{</span></span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>i <span class="op">=</span> i<span class="op">,</span></span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>a <span class="op">=</span> a<span class="op">,</span></span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Next, recall the <code>stack</code> type from the OCaml implementation.</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> stack =</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>    | Start <span class="kw">of</span> <span class="dt">int</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    | Continue <span class="kw">of</span> frame * stack</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>    | Finished</span></code></pre></div>
<p>We will represent the linked list structure as a simple array of <code>struct frame</code>s. Notice that the
depth of recursion is bounded by the parameter <code>n</code> given to <code>enumerate_assignments</code>. The maximum
value of the parameter <code>n</code> in the development here is <code>64</code>. The maximum recursion depth informs the
maximum stack size.</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>var_index <span class="dt">const</span> MAX_VARS <span class="op">=</span> <span class="dv">64</span><span class="op">;</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>var_index <span class="dt">const</span> STACK_LIMIT <span class="op">=</span> MAX_VARS<span class="op">;</span></span></code></pre></div>
<p>To manage this array of frames, we will need to track a <em>frame pointer:</em> this is the index of the
next unused frame in the stack. Seen differently, the frame pointer is the count of frames
currently in the stack.</p>
<p>The frame pointer, being at least 8 bits wide, can accommodate values greater than the count of
frames we will ever store.
This means we can use the upper bits of the frame pointer to help identify what state the generator
is in.
When the generator is in the start state, the stack is empty, so we can use the value
<code>1 &lt;&lt; (WIDTH-1)</code> for the frame pointer to signify that the generator is in the start state.</p>
<p>In the <code>Start</code> state, we need to know the count <code>n</code> of variables we’re enumerating truth
assignments for, but afterwards we can forget this <code>n</code> and just keep the array of frames.
This suggests using a <code>union</code> to reuse space here.</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> generator <span class="op">{</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">uint8_t</span> frame_pointer<span class="op">;</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">union</span> <span class="op">{</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>        var_index num_variables<span class="op">;</span></span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">struct</span> frame stack<span class="op">[</span>STACK_LIMIT<span class="op">];</span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> data<span class="op">;</span></span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> state <span class="op">{</span></span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>    START <span class="op">=</span> <span class="dv">1</span><span class="op">,</span></span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a>    CONTINUE <span class="op">=</span> <span class="dv">0</span><span class="op">,</span></span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> state generator_state<span class="op">(</span><span class="kw">struct</span> generator <span class="op">*</span>gen<span class="op">)</span> <span class="op">{</span></span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// extract the uppermost bit of the frame pointer</span></span>
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> gen<span class="op">-&gt;</span>frame_pointer <span class="op">&gt;&gt;</span> <span class="dv">7</span><span class="op">;</span></span>
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-19"><a href="#cb30-19" aria-hidden="true" tabindex="-1"></a><span class="co">// constructs a generator&#39;s initial state</span></span>
<span id="cb30-20"><a href="#cb30-20" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> generator enumerate_assignments<span class="op">(</span>var_index num_variables<span class="op">)</span> <span class="op">{</span></span>
<span id="cb30-21"><a href="#cb30-21" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">(</span><span class="kw">struct</span> generator<span class="op">)</span> <span class="op">{</span></span>
<span id="cb30-22"><a href="#cb30-22" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>data<span class="op">.</span>num_variables <span class="op">=</span> num_variables<span class="op">,</span></span>
<span id="cb30-23"><a href="#cb30-23" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span>frame_pointer <span class="op">=</span> <span class="dv">1</span> <span class="op">&lt;&lt;</span> <span class="dv">7</span><span class="op">,</span></span>
<span id="cb30-24"><a href="#cb30-24" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb30-25"><a href="#cb30-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Next, we need operations to push to and pop from the stack held in a <code>generator</code>.</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="co">/**</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="co"> * Returns -1 if pushing fails: wrong generator state or stack is full.</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a><span class="co"> * Otherwise copies the given frame into the top of the stack, increments the frame pointer,</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a><span class="co"> * and returns 1. */</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> gen_stack_push<span class="op">(</span><span class="kw">struct</span> generator <span class="op">*</span> gen<span class="op">,</span> <span class="kw">struct</span> frame <span class="dt">const</span> <span class="op">*</span> frame<span class="op">)</span> <span class="op">{</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>gen<span class="op">-&gt;</span>frame_pointer <span class="op">&gt;=</span> STACK_LIMIT<span class="op">)</span> <span class="op">{</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>    gen<span class="op">-&gt;</span>data<span class="op">.</span>stack<span class="op">[</span>gen<span class="op">-&gt;</span>frame_pointer<span class="op">++]</span> <span class="op">=</span> <span class="op">*</span>frame<span class="op">;</span></span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a><span class="co">/**</span></span>
<span id="cb31-14"><a href="#cb31-14" aria-hidden="true" tabindex="-1"></a><span class="co"> * Returns -1 if popping is forbidden: wrong generator state.</span></span>
<span id="cb31-15"><a href="#cb31-15" aria-hidden="true" tabindex="-1"></a><span class="co"> * Returns 0 if the stack is empty.</span></span>
<span id="cb31-16"><a href="#cb31-16" aria-hidden="true" tabindex="-1"></a><span class="co"> * Otherwise decrements the frame pointer, and copies the top frame into `out`,</span></span>
<span id="cb31-17"><a href="#cb31-17" aria-hidden="true" tabindex="-1"></a><span class="co"> * and returns 1 */</span></span>
<span id="cb31-18"><a href="#cb31-18" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> gen_stack_pop<span class="op">(</span><span class="kw">struct</span> generator <span class="op">*</span> gen<span class="op">,</span> <span class="kw">struct</span> frame <span class="op">*</span> out<span class="op">)</span> <span class="op">{</span></span>
<span id="cb31-19"><a href="#cb31-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>START <span class="op">==</span> generator_state<span class="op">(</span>gen<span class="op">))</span> <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb31-20"><a href="#cb31-20" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span><span class="dv">0</span> <span class="op">==</span> gen<span class="op">-&gt;</span>frame_pointer<span class="op">)</span> <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb31-21"><a href="#cb31-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-22"><a href="#cb31-22" aria-hidden="true" tabindex="-1"></a>    <span class="op">*</span>out <span class="op">=</span> gen<span class="op">-&gt;</span>data<span class="op">.</span>stack<span class="op">[--</span> gen<span class="op">-&gt;</span>frame_pointer<span class="op">];</span></span>
<span id="cb31-23"><a href="#cb31-23" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb31-24"><a href="#cb31-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Now that we’ve translated all the type definitions, we can translate the programs <code>go</code> and <code>apply</code>
from OCaml into C. Recall the OCaml implementation:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> state = <span class="dt">ref</span> (Start n) <span class="kw">in</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> go n a s =</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>            (state := s; <span class="dt">Some</span> a)</span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>            go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (Continue ({n; a}, s))</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">and</span> apply s = <span class="kw">match</span> s <span class="kw">with</span></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>        | Start -&gt; go n [] Finished <span class="co">(* Finished comes from fun () -&gt; None *)</span></span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>        | Continue ({n; a}, s) -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) s</span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>        | Finished -&gt; <span class="dt">None</span></span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">fun</span> () -&gt; apply !state</span></code></pre></div>
<p>Notice that <code>go</code> refers to the variable <code>state</code> that is not a parameter of <code>go</code>. In other words,
the definition of <code>go</code> constructs a <em>closure.</em> Sadly, C does not have closures, so we will
implement this by passing our translation of <code>go</code> a pointer to the <code>generator</code>. This way when <code>go</code>
makes a recursive call, it can simply use <code>gen_stack_push</code> to implement the expression <code>Continue ({n; a}, s)</code> at the same time as <code>state := s</code>. In other words, rather than building up the stack in
a parameter to save it just before returning, our translation of <code>go</code> will be mutating the stack
along the way.</p>
<p>Observe also that <code>go</code> is <em>tail-recursive:</em> the recursive call is the last thing the function does.
The OCaml compiler transforms this into a while-loop during compilation. This transformation is
called <em>tail-call optimization.</em> We will also perform this transformation in our translation, to
avoid using the C call stack.</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> go<span class="op">(</span><span class="kw">struct</span> generator <span class="op">*</span> gen<span class="op">,</span> var_index i<span class="op">,</span> truth_assignment <span class="op">*</span> ta<span class="op">)</span> <span class="op">{</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> frame frame<span class="op">;</span></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// due to the --&gt; &#39;operator&#39;,</span></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// `i` will have its value decremented by one inside the loop</span></span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="op">(</span>i <span class="op">--&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">*</span>ta <span class="op">=</span> set_true<span class="op">(*</span>ta<span class="op">,</span> n<span class="op">);</span></span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a>        <span class="co">// in the OCaml program, the frame that gets pushed by the recursive call</span></span>
<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a>        <span class="co">// `go (n-1) (true :: a) (Continue ({n; a}, s))`</span></span>
<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a>        <span class="co">// stores the value `n`, but here we are storing n-1 as a consequence</span></span>
<span id="cb33-12"><a href="#cb33-12" aria-hidden="true" tabindex="-1"></a>        <span class="co">// of the decrement that happens in the while loop condition.</span></span>
<span id="cb33-13"><a href="#cb33-13" aria-hidden="true" tabindex="-1"></a>        frame <span class="op">=</span> <span class="op">=</span> make_frame<span class="op">(</span>n<span class="op">,</span> <span class="op">*</span>ta<span class="op">);</span></span>
<span id="cb33-14"><a href="#cb33-14" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span><span class="op">(-</span><span class="dv">1</span> <span class="op">==</span> gen_stack_push<span class="op">(</span>gen<span class="op">,</span> <span class="op">&amp;</span>frame<span class="op">))</span> <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb33-15"><a href="#cb33-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb33-16"><a href="#cb33-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb33-17"><a href="#cb33-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Notice that <code>go</code> returns a status code here, whereas the original OCaml program returned the truth
assignment. The C program ‘returns’ the truth assignment via the pointer parameter <code>ta</code>, and rather
than construct a new truth assignment, it simply modifies the given one.</p>
<p>Finally, we can translate <code>apply</code>. We will call it <code>next</code> in the C program, since it will dispatch
on the current generator state to compute the next item in the sequence, updating the generator
state.</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> next<span class="op">(</span><span class="kw">struct</span> generator <span class="op">*</span> gen<span class="op">,</span> truth_assignment <span class="op">*</span> ta<span class="op">)</span> <span class="op">{</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> status<span class="op">;</span></span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> frame frame<span class="op">;</span></span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">switch</span> <span class="op">(</span>generator_state<span class="op">(</span>gen<span class="op">))</span> <span class="op">{</span></span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> CONTINUE<span class="op">:</span></span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a>        status <span class="op">=</span> gen_stack_pop<span class="op">(</span>gen<span class="op">,</span> <span class="op">&amp;</span>frame<span class="op">);</span></span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a>        <span class="co">// handle generator exit</span></span>
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span><span class="dv">0</span> <span class="op">==</span> status <span class="op">||</span> <span class="op">-</span><span class="dv">1</span> <span class="op">==</span> status<span class="op">)</span> <span class="cf">return</span> status<span class="op">;</span></span>
<span id="cb34-11"><a href="#cb34-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-12"><a href="#cb34-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">*</span>ta <span class="op">=</span> set_false<span class="op">(</span>frame<span class="op">.</span>a<span class="op">,</span> frame<span class="op">.</span>i<span class="op">);</span></span>
<span id="cb34-13"><a href="#cb34-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(-</span><span class="dv">1</span> <span class="op">==</span> go<span class="op">(</span>gen<span class="op">,</span> frame<span class="op">.</span>i<span class="op">,</span> ta<span class="op">))</span> <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb34-14"><a href="#cb34-14" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb34-15"><a href="#cb34-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-16"><a href="#cb34-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> START<span class="op">:</span></span>
<span id="cb34-17"><a href="#cb34-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">*</span>ta <span class="op">=</span> EMPTY_TRUTH_ASSIGNMENT<span class="op">;</span></span>
<span id="cb34-18"><a href="#cb34-18" aria-hidden="true" tabindex="-1"></a>        gen<span class="op">-&gt;</span>frame_pointer <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb34-19"><a href="#cb34-19" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span><span class="op">(-</span><span class="dv">1</span> <span class="op">==</span> go<span class="op">(</span>gen<span class="op">,</span> gen<span class="op">-&gt;</span>data<span class="op">.</span>num_variables<span class="op">,</span> ta<span class="op">))</span> <span class="cf">return</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb34-20"><a href="#cb34-20" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb34-21"><a href="#cb34-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb34-22"><a href="#cb34-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And what good is all this code if we don’t try it out. Here’s a <code>main</code> function to run the
generator until it exits, printing out the truth assignments along the way.</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> generator gen <span class="op">=</span> enumerate_assignments<span class="op">(</span><span class="dv">5</span><span class="op">);</span></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> status <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a>    truth_assignment a<span class="op">;</span></span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(;</span> status <span class="op">=</span> next<span class="op">(&amp;</span>gen<span class="op">,</span> <span class="op">&amp;</span>a<span class="op">),</span> <span class="dv">1</span> <span class="op">!=</span> status<span class="op">;)</span> <span class="op">{</span></span>
<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a>        printf<span class="op">(</span><span class="st">&quot;truth assignment: %d</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">,</span> a<span class="op">);</span></span>
<span id="cb35-8"><a href="#cb35-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb35-9"><a href="#cb35-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-10"><a href="#cb35-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(-</span><span class="dv">1</span> <span class="op">==</span> status<span class="op">)</span> <span class="op">{</span></span>
<span id="cb35-11"><a href="#cb35-11" aria-hidden="true" tabindex="-1"></a>        printf<span class="op">(</span><span class="st">&quot;Generator encountered an error, sorry.</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">);</span></span>
<span id="cb35-12"><a href="#cb35-12" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> EXIT_FAILURE<span class="op">;</span></span>
<span id="cb35-13"><a href="#cb35-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb35-14"><a href="#cb35-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-15"><a href="#cb35-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> EXIT_SUCCESS<span class="op">;</span></span>
<span id="cb35-16"><a href="#cb35-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Collecting all this C code into a file <code>enumerate.c</code>, we can witness the fruits of our labour:</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> gcc enumerate.c <span class="kw">&amp;&amp;</span> <span class="ex">./a.out</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 31</span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 30</span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 29</span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 28</span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 27</span>
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 26</span>
<span id="cb36-8"><a href="#cb36-8" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 25</span>
<span id="cb36-9"><a href="#cb36-9" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 24</span>
<span id="cb36-10"><a href="#cb36-10" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 23</span>
<span id="cb36-11"><a href="#cb36-11" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 22</span>
<span id="cb36-12"><a href="#cb36-12" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 21</span>
<span id="cb36-13"><a href="#cb36-13" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 20</span>
<span id="cb36-14"><a href="#cb36-14" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 19</span>
<span id="cb36-15"><a href="#cb36-15" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 18</span>
<span id="cb36-16"><a href="#cb36-16" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 17</span>
<span id="cb36-17"><a href="#cb36-17" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 16</span>
<span id="cb36-18"><a href="#cb36-18" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 15</span>
<span id="cb36-19"><a href="#cb36-19" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 14</span>
<span id="cb36-20"><a href="#cb36-20" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 13</span>
<span id="cb36-21"><a href="#cb36-21" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 12</span>
<span id="cb36-22"><a href="#cb36-22" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 11</span>
<span id="cb36-23"><a href="#cb36-23" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 10</span>
<span id="cb36-24"><a href="#cb36-24" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 9</span>
<span id="cb36-25"><a href="#cb36-25" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 8</span>
<span id="cb36-26"><a href="#cb36-26" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 7</span>
<span id="cb36-27"><a href="#cb36-27" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 6</span>
<span id="cb36-28"><a href="#cb36-28" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 5</span>
<span id="cb36-29"><a href="#cb36-29" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 4</span>
<span id="cb36-30"><a href="#cb36-30" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 3</span>
<span id="cb36-31"><a href="#cb36-31" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 2</span>
<span id="cb36-32"><a href="#cb36-32" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 1</span>
<span id="cb36-33"><a href="#cb36-33" aria-hidden="true" tabindex="-1"></a><span class="ex">truth</span> assignment: 0</span></code></pre></div>
<p>And there you have it: the most complicated program you’ve ever seen to count down from <code>2^n -1</code>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>This article covered a lot of ground.</p>
<p>At first, we were motivated by Python’s elegant generator syntax and curious about how these ideas
are implemented. We implemented the idea of stateful generators using continuation-passing style to
give us access to a representation of the evaluation context, so we could store that context in a
mutable variable. That gave us the following implementation.</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> <span class="kw">rec</span> go n a next =</span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>            <span class="co">(* we wrap the next item in Some *)</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>            (state := next; <span class="dt">Some</span> a)</span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span></span>
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a>            go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (<span class="kw">fun</span> () -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) next)</span>
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">and</span> state = <span class="dt">ref</span> (<span class="kw">fun</span> () -&gt; go n [] (<span class="kw">fun</span> () -&gt; <span class="dt">None</span>))</span>
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* and arrange that the last continuation to be stored in</span></span>
<span id="cb37-10"><a href="#cb37-10" aria-hidden="true" tabindex="-1"></a><span class="co">       `state` just returns `None`. *)</span></span>
<span id="cb37-11"><a href="#cb37-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span></span>
<span id="cb37-12"><a href="#cb37-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">fun</span> () -&gt; !state ()</span></code></pre></div>
<p>In the following section, we explored a purely functional take on this idea, motivated by the
simple idea of returning the continuation together with the generated value. To make this
typecheck, we needed to introduce the following recursive type.</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> &#39;a l =</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a>  | Done</span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a>  | More <span class="kw">of</span> &#39;a * (<span class="dt">unit</span> -&gt; &#39;a l)</span></code></pre></div>
<p>This recursive type (or some variant thereof) is often presented in programming languages courses
simply as “a lazy list”. The development in this article, on the other hand, <em>derived</em> this
representation by eliminating the mutable variable from the program in the previous section.
This demonstrates that lazy lists are purely functional generators, where the state of the
generator is captured in the continuation of type <code>unit -&gt; 'a l</code> that is explicitly returned.</p>
<p>In the following section, we applied defunctionalization to the stateful CPS generator to convert
it into a state machine using an explicit stack.</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> enumerate_assignments n =</span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> state = <span class="dt">ref</span> (Start n) <span class="kw">in</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> <span class="kw">rec</span> go n a s =</span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> n = <span class="dv">0</span> <span class="kw">then</span></span>
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a>      (state := s; <span class="dt">Some</span> a)</span>
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a>     go (n<span class="dv">-1</span>) (<span class="kw">true</span> :: a) (Continue ({n; a}, s))</span>
<span id="cb39-8"><a href="#cb39-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">and</span> apply s = <span class="kw">match</span> s <span class="kw">with</span></span>
<span id="cb39-9"><a href="#cb39-9" aria-hidden="true" tabindex="-1"></a>    | Start n -&gt; go n [] Finished</span>
<span id="cb39-10"><a href="#cb39-10" aria-hidden="true" tabindex="-1"></a>    | Continue ({n; a}, s) -&gt; go (n<span class="dv">-1</span>) (<span class="kw">false</span> :: a) s</span>
<span id="cb39-11"><a href="#cb39-11" aria-hidden="true" tabindex="-1"></a>    | Finished -&gt; <span class="dt">None</span></span>
<span id="cb39-12"><a href="#cb39-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span></span>
<span id="cb39-13"><a href="#cb39-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">fun</span> () -&gt; apply !state</span></code></pre></div>
<p>In the final section, we translated the defunctionalized program into C, using efficient data
representations along the way where possible.</p>
<p>I hope that this sheds some light on the connection between CPS, generators, and state machines.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Loop once... (f)or else! (Or, Python pro-tip number 2)</title>
    <link href="https://jerrington.me/posts/2023-03-25-loop-once-for-else.html" />
    <id>https://jerrington.me/posts/2023-03-25-loop-once-for-else.html</id>
    <published>2023-03-25T00:00:00Z</published>
    <updated>2023-03-25T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on March 25, 2023
    
</div>

<p>Once upon a time, some seven years ago, I wrote <a href="/posts/2016-04-01-python-protip">a post</a> about a Python trick for
accessing the first element of any kind of sequence.</p>
<p>The gist of that article is that just using indexing isn’t general enough: if the sequence is
lazily computed by a generator, then indexing won’t work.
What does work, however, is to iterate over the sequence using a <code>for</code> loop. But since we just want
the first element, let’s immediately break out of the loop.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> x <span class="kw">in</span> seq:</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">print</span>(x) <span class="co"># or do whatever</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">break</span></span></code></pre></div>
<p>But there’s something I missed in that post! What if the sequence is empty?</p>
<p>An obvious solution is to use a boolean:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>entered <span class="op">=</span> <span class="va">False</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> x <span class="kw">in</span> seq:</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    entered <span class="op">=</span> <span class="va">True</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="bu">print</span>(x)</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">break</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="kw">not</span> entered:</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">pass</span> <span class="co"># do whatever</span></span></code></pre></div>
<p>But that’s pretty ugly if not outright disgusting. Instead, we can take advantage of a
little-known feature of Python’s for-loops: in Python, a for-loop can have an <code>else</code> block! The
semantics are that if the loop terminates <em>normally,</em> then the <code>else</code>-block is run; else, if the
loop exits early, e.g. by a <code>break</code>, then the <code>else</code>-block is skipped.</p>
<p>These semantics are frankly weird to me, but they end up working out marvellously for our current
use case. It almost makes me think that this is why <code>else</code> was allowed in the first place for a
<code>for</code>-loop. Consider this.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> x <span class="kw">in</span> seq:</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">print</span>(x)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">break</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="cf">else</span>:</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="bu">print</span>(<span class="st">&quot;nothing in the sequence&quot;</span>)</span></code></pre></div>
<p>If the sequence is nonempty, then we will print the first item in the sequence and abort the loop,
skipping the <code>else</code>-block. If the sequence <em>is</em> empty, then <strong>the loop will exit normally,</strong> so the
<code>else</code>-block will run!</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Functional programmers hate this one trick</title>
    <link href="https://jerrington.me/posts/2023-02-12-defunctionalizing-continuations.html" />
    <id>https://jerrington.me/posts/2023-02-12-defunctionalizing-continuations.html</id>
    <published>2023-02-12T00:00:00Z</published>
    <updated>2023-02-12T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on February 12, 2023
    
</div>

<p>Originally developed as a technique for implementing compilers for
(higher-order) functional languages, <em>defunctionalization</em> (d17n) is a program
transformation that eliminates higher-order functions.
It is based on the following observation: although there might be infinitely
many possible functions one might pass to a higher-order function, there are
only finitely many functions that are <em>actually</em> passed in any given program.
Therefore, we can define a (finite) data type to represent our choice of
function and we can define an interpreter for this data type that recovers the
behaviour of the original function.</p>
<p>One situation we might want to employ d17n as programmers is in networked
applications –
higher-order functions give us lots of expressive power, but we unfortunately
can’t send functions over the network!
In fact, you might have already done this without
realizing it. Rather than send a function, which as more or less impossible, we
send some representation of a function that the remote side interprets to
execute the function we wanted.
The canonical example in web development is the use of a <code>return_to</code> URL parameter:
when a user attemps to perform an action while not logged in, we redirect them
to a login page with a <code>return_to</code> URL parameter. Once the user logs in, they
are redirected to the URL stored in that parameter. That parameter is precisely
a defunctionalized <em>continuation</em>.</p>
<p>This article will demonstrate d17n first for the standard higher-order function
<code>filter</code>, followed by a discussion of defunctionalized continuations.</p>
<h2 id="defunctionalizing-filter">Defunctionalizing <code>filter</code></h2>
<p>Let’s see d17n in action with an example. Suppose our program filters lists.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> filter p = <span class="kw">function</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  | [] -&gt; []</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  | x :: xs -&gt; <span class="kw">if</span> p x <span class="kw">then</span> x :: filter p xs <span class="kw">else</span> filter p xs</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> _ = filter (<span class="kw">fun</span> x -&gt; x <span class="kw">mod</span> <span class="dv">2</span> = <span class="dv">0</span>) [<span class="dv">1</span>;<span class="dv">2</span>;<span class="dv">3</span>;<span class="dv">4</span>;<span class="dv">5</span>;<span class="dv">6</span>;<span class="dv">7</span>;<span class="dv">8</span>;<span class="dv">9</span>]</span></code></pre></div>
<p>Now let’s see the defunctionalized form of this program.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="co">(* This is the data structure that represents our choice of function. *)</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> predicate = IsEven</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="co">(* This is the interpreter for this data structure,</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="co">   which recovers the behaviour of the function. *)</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> apply p_rep x = <span class="kw">match</span> p_rep <span class="kw">with</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  | IsEven -&gt; x <span class="kw">mod</span> <span class="dv">2</span> = <span class="dv">0</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="co">(* This is the defunctionalized filter.</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="co">   Instead of receiving a function as input, it receives a</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="co">   value of type `predicate`, which is a _representation_ of a function. *)</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> filter_df p_rep = <span class="kw">function</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>  | [] -&gt; []</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>  | x :: xs -&gt;</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* We pass the predicate to our interpreter. *)</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> apply p_rep x</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">then</span> x :: filter_df p_rep xs</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> filter_df p_rep xs</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> _ = filter_df IsEven [<span class="dv">1</span>;<span class="dv">2</span>;<span class="dv">3</span>;<span class="dv">4</span>;<span class="dv">5</span>;<span class="dv">6</span>;<span class="dv">7</span>;<span class="dv">8</span>;<span class="dv">9</span>]</span></code></pre></div>
<p>Look, no more higher-order functions!</p>
<p>That was a quite simple example though.
Let’s see how to accommodate more complicated functions one by one.</p>
<p>First, what happens when the function we pass to <code>filter</code> is a <em>closure</em>, i.e.
it contains variables that are not its parameters?</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> divisible_by k l = filter (<span class="kw">fun</span> x -&gt; x <span class="kw">mod</span> k = <span class="dv">0</span>) l</span></code></pre></div>
<p>Notice that the function <code>fun x -&gt; x mod k = 0</code> refers to <code>k</code>, which is not a
parameter of the function. To accommodate this, we will add a constructor to our
type <code>predicate</code> called <code>IsDivisible</code>, and that new constructor will crucially
have one field to store the value of this <code>k</code>. Then, when our interpreter
<code>apply</code> matches on the <code>predicate</code> it can recover the value of <code>k</code> and use it to
recover the behaviour of the original function.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> predicate = IsEven | IsDivisible <span class="kw">of</span> <span class="dt">int</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> apply p_rep x = <span class="kw">match</span> p_rep <span class="kw">with</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  | IsEven -&gt; x <span class="kw">mod</span> <span class="dv">2</span> = <span class="dv">0</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  | IsDivisible k -&gt; x <span class="kw">mod</span> k = <span class="dv">0</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="co">(* The implementation of `filter` itself is unchanged. *)</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> divisible_by k l = filter_df (IsDivisible k) l</span></code></pre></div>
<p>Next, what happens when we combine multiple predicates into one? For example, we
might want to filter a list to select all elements that satisfy <em>two</em>
properties. Actually, we can define this as a separate combinator, which takes
two functions as input and produces a function as output.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> both f g = <span class="kw">fun</span> x -&gt; f x &amp;&amp; g x</span></code></pre></div>
<p>Notice that the type of <code>f</code> and of <code>g</code> is also the type of <code>both f g</code>, namely
<code>'a -&gt; bool</code>. That’s precisely the higher-order type that we’re eliminating via
d17n. This will end up making our representation type <code>predicate</code> into a recursive type.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> predicate =</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  | IsEven</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  | IsDivisible <span class="kw">of</span> <span class="dt">int</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  | Both <span class="kw">of</span> predicate * predicate</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="co">(* And correspondingly, our implementation of `apply` will be recursive too. *)</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> apply p_rep x = <span class="kw">match</span> p_rep <span class="kw">with</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  | IsEven -&gt; x <span class="kw">mod</span> <span class="dv">2</span> = <span class="dv">0</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  | IsDivisible k -&gt; x <span class="kw">mod</span> k = <span class="dv">0</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>  | Both (p1, p2) -&gt; apply p1 x &amp;&amp; apply p2 x</span></code></pre></div>
<p>Now the astute reader might have noticed that our type <code>predicate</code> is actually
quite limiting: it only works for one type and in this case that’s <code>int</code>.
The crux of the issue is that the predicate <code>IsDivisible</code> and <code>IsEven</code> only work
for <code>int</code>, whereas the predicate <code>Both (p1, p2)</code> should work for any <code>x : 'a</code>
provided that both <code>p1</code> and <code>p2</code> are predicates that work on <code>'a</code>.
More to the point, what if we had a predicate <code>IsPalidrome</code> that should work on on <code>string</code>?
How would we define a well-typed <code>apply</code>? It would need to be able to accept either a string or an
int, requiring that the given predicate be “for a string” or “for an int”.</p>
<p>It is possible to further generalize the type <code>predicate</code> by making it into a
<em>generalized algebraic datatype</em> (GADT). With a GADT, it becomes possible to implement a well-typed
<code>apply</code>, but a demonstration of this will need to wait for a future article.</p>
<h2 id="defunctionalizing-continuations">Defunctionalizing continuations</h2>
<p>One amazing use of higher-order functions is a technique called
continuation-passing style (CPS). In this style of programming, rather than write
a function that returns its result normally, we instead write a function that
returns its result by passing it to another function. The upshot is that every call in a CPS
program is a tail-call. In the presence of <a href="https://en.wikipedia.org/wiki/Tail_call">tail-call optimization</a>, such programs do not use
the call stack as function calls are implemented (more or less) as simple <code>jump</code> instructions.
For the functional programmer, this means we have <code>goto</code> in OCaml!</p>
<p>A few months ago, I wrote <a href="/posts/2022-10-22-higher-order-continuations.html">an article</a> explaining CPS in some detail
and showing a mindblowing use of it to implement a backtracking search through a
tree. I recommend reading that article before the rest of this one.</p>
<p>That article presents a simple definition of boolean formulas and an evaluator
for such formulas:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> formula =</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  | Conj <span class="kw">of</span> formula * formula</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  | Disj <span class="kw">of</span> formula * formula</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  | Neg <span class="kw">of</span> formula</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  | Var <span class="kw">of</span> <span class="dt">string</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> name = <span class="dt">string</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> env = (name * <span class="dt">bool</span>) <span class="dt">list</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> eval (r : env) = <span class="kw">function</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  | Var x -&gt; <span class="dt">List</span>.assoc x r</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>  | Neg e -&gt; <span class="dt">not</span> (eval r e)</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>  | Conj (e1, e2) -&gt; eval r e1 &amp;&amp; eval r e2</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>  | Disj (e1, e2) -&gt; eval r e1 || eval r e2</span></code></pre></div>
<p>The challenge is this: devise a way to find for a given <code>phi : formula</code> a
satisfying assignment to its variables, i.e. a value <code>r : env</code> such that <code>eval r phi = true</code>, <em>in “one pass”.</em>
Of course, it can’t actually be in one pass because this is an NP-complete
problem; that’s why I put quotes around “one pass”. What I mean by “one pass” is
that we want to solve this formula without <em>separately</em> enumerating all the
possible truth assignments of the variables and evaluating them.</p>
<p>I found a way to do this using CPS. The core idea of the below algorithm is that we want to save
the current execution state whenever we encounter a variable we haven’t seen before. These occur in
the <em>leaves</em> of the expression tree. If we find at the end of evaluating the tree that the result
is <code>false</code>, then we successively jump back to those saved states to try a different value for the
corresponding variable.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> solve (r : env) (fail : <span class="dt">unit</span> -&gt; &#39;r) (phi : formula)</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    (assign : env -&gt; <span class="dt">bool</span> -&gt; (<span class="dt">unit</span> -&gt; &#39;r) -&gt; &#39;r) : &#39;r =</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">match</span> phi <span class="kw">with</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  | Var x -&gt; <span class="kw">begin</span> <span class="kw">match</span> <span class="dt">List</span>.assoc_opt x r <span class="kw">with</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    | <span class="dt">Some</span> b -&gt; <span class="co">(* we already have a value for `x` *)</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>      assign r b fail</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    | <span class="dt">None</span> -&gt; <span class="co">(* we don&#39;t have a value for `x` *)</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>      assign ((x, <span class="kw">true</span>) :: r) <span class="kw">true</span> @@ <span class="kw">fun</span> () -&gt;</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>      assign ((x, <span class="kw">false</span>) :: r) <span class="kw">false</span> fail</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">end</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>  | Neg e -&gt;</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>    solve r fail e @@ <span class="kw">fun</span> r b fail -&gt; assign r (<span class="dt">not</span> b) fail</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>  | Conj (e1, e2) -&gt;</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>    solve r fail e1 @@ <span class="kw">fun</span> r b1 fail -&gt;</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> b1 <span class="kw">then</span> <span class="co">(* short-circuiting *)</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>      solve r fail e2 @@ <span class="kw">fun</span> r b2 fail -&gt; assign r (b1 &amp;&amp; b2) fail</span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>      assign r <span class="kw">false</span> fail</span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>  | Disj (e1, e2) -&gt;</span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>    solve r fail e1 @@ <span class="kw">fun</span> r b1 fail -&gt;</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> b1 <span class="kw">then</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>      assign r <span class="kw">true</span> fail</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>      solve r fail e2 @@ <span class="kw">fun</span> r b2 fail -&gt;</span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>      assign r (b1 || b2) fail</span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a><span class="co">(* From the CPS solver, we recover a function `formula -&gt; env option` that decides</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a><span class="co">   whether the given formula is satisfiable, giving the satisfying assignment</span></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a><span class="co">   in that case.</span></span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a><span class="co">   To do so we provide the initial continuations for `fail` and `assign`:</span></span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a><span class="co">   - The initial `fail` continuation is reached if we have exhausted every</span></span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true" tabindex="-1"></a><span class="co">     assignment to the variables. The formula is therefore unsatisfiable.</span></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a><span class="co">   - The initial `assign` continuation is reached when we finish evaluating</span></span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a><span class="co">     the whole expression, having worked out an assignment `r : env` under</span></span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a><span class="co">     which the expression&#39;s value is `res : bool`.</span></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a><span class="co">*)</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> solve_enter (phi : formula) : env <span class="dt">option</span> =</span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a>  solve [] (<span class="kw">fun</span> () -&gt; <span class="dt">None</span>) phi (<span class="kw">fun</span> r res fail -&gt; <span class="kw">if</span> res <span class="kw">then</span> <span class="dt">Some</span> r <span class="kw">else</span> fail ())</span></code></pre></div>
<p>What’s challenging and mysterious about this implementation is that the <code>assign</code> continuation,
which represents a normal return from <code>solve</code>, takes in addition to an <code>env</code> and a <code>bool</code> a
function of type <code>unit -&gt; 'r</code>.
<em>This</em> function represents an <em>abnormal</em> return, like throwing an exception.
Therefore, <em>we can undo a return from <code>solve</code></em> by having the continuation we pass as
<code>assign</code> call its given failure continuation.</p>
<p>The most interesting and important part of the algorithm is in the <code>None</code>
subcase of the <code>Var</code> case. In that case, we have encountered a variable for
which we don’t have an assigned value in the environment <code>r : env</code>.
So we call <code>assign</code> with an extended environment <em>and</em> an augmented failure
continuation. It is exactly here that we express the idea “try to return <code>true</code> here
<em>but if that fails</em> then return <code>false</code>.”</p>
<p>At first it seems terrifying to try to defunctionalize this, but fortunately,
d17n is a completely systematic, mechanical process.</p>
<ol type="1">
<li>For every type of function that is passed, we define a new datatype.
We define one interpreter for each of these types, although at this point all
we can do is work out the signature of the interpreter, as we haven’t decided what the
constructors of these new types will be.</li>
<li>Find every position where we pass an anonymous function.
Each of those functions becomes a constructor of the datatype corresponding
to the function’s type.
Then, we have to identify for each anonymous function all the variables it
contains that aren’t its parameters – the fancy math-name for those is <em>free
variables</em>.
The types of the free variables become the fields of the constructor corresponding to the
function.</li>
<li>Find every place where we <em>call</em> a function received through a parameter;
these will become calls to the <code>apply</code> interpreter we will write.
Replace every anonymous function with its corresponding constructor generated by the above
process.</li>
<li>Implement apply to recover the original functions</li>
</ol>
<p>We’ll follow these steps one by one in modifying the implementation of <code>solve</code>.</p>
<h3 id="step-1-type-definitions">Step 1: type definitions</h3>
<p>There are two higher-order types we seek to eliminate in the original program:
we define a type <code>failure</code> to represent the function <code>unit -&gt; 'r</code> and a type
<code>assign</code> to represent the function <code>env -&gt; bool -&gt; (unit -&gt; 'r) -&gt; 'r</code>.</p>
<p>There is sadly a small wrinkle arising from the fact that without using a GADT, we can’t express
polymorphism in our defunctionalized program. Therefore, we will have to decide what <code>'r</code> is
going to be. We observe that the initial continuations return <code>env option</code>, so that is
what we fix <code>'r</code> to be. The interpreters we define will be <code>apply_failure : failure -&gt; env option</code>
and <code>apply_assign : assign -&gt; env -&gt; bool -&gt; failure -&gt; env option</code>.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> failure = ...</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> assign = ...</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> apply_failure (sf : failure) : env <span class="dt">option</span> = <span class="dt">failwith</span> <span class="st">&quot;todo&quot;</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> apply_assign (sa : assign) (r : env) (b : <span class="dt">bool</span>) (sf : failure) : env <span class="dt">option</span> =</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">failwith</span> <span class="st">&quot;todo&quot;</span></span></code></pre></div>
<h3 id="step-2-constructor-definitions">Step 2: constructor definitions</h3>
<p>Here’s the code for the CPS solver, this time annotated to identify all the anonymous functions
that are passed as arguments. Annotations <code>F-n</code> indicate an anonymous function passed as a <code>fail</code>
continuation whereas <code>A-n</code> indicate a function passed as an <code>assign</code> continuation.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> solve (r : env) (fail : <span class="dt">unit</span> -&gt; &#39;r) (phi : formula)</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    (assign : env -&gt; <span class="dt">bool</span> -&gt; (<span class="dt">unit</span> -&gt; &#39;r) -&gt; &#39;r) : &#39;r =</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">match</span> phi <span class="kw">with</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  | Var x -&gt; <span class="kw">begin</span> <span class="kw">match</span> <span class="dt">List</span>.assoc_opt x r <span class="kw">with</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    | <span class="dt">Some</span> b -&gt; assign r b fail</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    | <span class="dt">None</span> -&gt;</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>      assign ((x, <span class="kw">true</span>) :: r) <span class="kw">true</span> @@ <span class="kw">fun</span> () -&gt;</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>      assign ((x, <span class="kw">false</span>) :: r) <span class="kw">false</span> fail <span class="co">(* F-1 *)</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">end</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>  | Neg e -&gt;</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>    solve r fail e @@ <span class="kw">fun</span> r b fail -&gt; <span class="co">(* A-1 *)</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>    assign r (<span class="dt">not</span> b) fail</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>  | Conj (e1, e2) -&gt;</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>    solve r fail e1 @@ <span class="kw">fun</span> r b1 fail -&gt; <span class="co">(* A-2 *)</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> b1 <span class="kw">then</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>      solve r fail e2 @@ <span class="kw">fun</span> r b2 fail -&gt; <span class="co">(* A-3 *)</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>      assign r (b1 &amp;&amp; b2) fail</span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>      assign r <span class="kw">false</span> fail</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>  | Disj (e1, e2) -&gt;</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>    solve r fail e1 @@ <span class="kw">fun</span> r b1 fail -&gt; <span class="co">(* A-4 *)</span></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> b1 <span class="kw">then</span></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a>      assign r <span class="kw">true</span> fail</span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a>      solve r fail e2 @@ <span class="kw">fun</span> r b2 fail -&gt; <span class="co">(* A-5 *)</span></span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a>      assign r (b1 || b2) fail</span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> solve_enter (phi : formula) : env <span class="dt">option</span> =</span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a>  solve []</span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">fun</span> () -&gt; <span class="dt">None</span>) <span class="co">(* F-2 *)</span></span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true" tabindex="-1"></a>    phi</span>
<span id="cb10-32"><a href="#cb10-32" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">fun</span> r res fail -&gt; <span class="kw">if</span> res <span class="kw">then</span> <span class="dt">Some</span> r <span class="kw">else</span> fail ()) <span class="co">(* A-6 *)</span></span></code></pre></div>
<p>Since only two functions are passed as the <code>fail</code> continuation, let’s start there. The initial
continuation has no free variables, so its constructor will just be <code>Failed</code> with no fields.
On the other hand, the function <code>F-1</code> has the free variables <code>assign</code>, <code>x : name</code>, <code>r : env</code>, and
<code>fail</code>. This leads to the following definition.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> assign = ...</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> failure =</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  | Failed</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  | Retry <span class="kw">of</span> assign * name * env * failure</span></code></pre></div>
<p>And we can refactor this by observing that this pair of constructors give rise to a list structure:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> failure_frame = assign * name * env</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> failure = failure_frame <span class="dt">list</span></span></code></pre></div>
<p>Next, we apply the same reasoning to the functions passed as <code>assign</code>. We can immediately observe
that a list structure will again arise as each function passed as <code>assign</code> refers to the outer
<code>assign</code> as a free variable, except for the initial <code>assign</code> continuation which has no free
variables. I will annotate each constructor field with the name of the free variable that
corresponds to that field.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> failure = failure_frame <span class="dt">list</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> failure_frame = assign * name * env</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> assign = assign_frame <span class="dt">list</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  <span class="co">(* and the [] case of the list corresponds to A-6 *)</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> assign_frame =</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>  | Neg1 <span class="co">(* A-1 *)</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>  | Conj1 <span class="co">(* A-2 *)</span> <span class="kw">of</span> formula <span class="co">(* e2 *)</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>  | Conj2 <span class="co">(* A-3 *)</span> <span class="kw">of</span> <span class="dt">bool</span> <span class="co">(* b1 *)</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>  | Disj1 <span class="co">(* A-4 *)</span> <span class="kw">of</span> formula <span class="co">(* e2 *)</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>  | Disj2 <span class="co">(* A-5 *)</span> <span class="kw">of</span> <span class="dt">bool</span> <span class="co">(* b1 *)</span></span></code></pre></div>
<p>Due to the list structure, we should keep in mind that when our interpreter examines a <code>Disj1</code>, for
example, there will be a sublist of <code>assign_frame</code>s as well. This sublist corresponds to the
<code>assign</code> free variable present in the original function. Calling <code>assign</code> from within an augmented
<code>assign</code> continuation in the original program will be translated into a call to <code>apply_assign</code> on
the sublist of <code>assign_frame</code>s.</p>
<h3 id="step-3-replace-unknown-functions-with-apply-and-anonymous-functions-with-constructors">Step 3: Replace unknown functions with <code>apply</code> and anonymous functions with constructors</h3>
<p>In this step, we change the implementation of <code>solve</code> and <code>solve_enter</code>.
By “unknown function”, I mean a function received through a parameter.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> solve (r : env) (fail : failure) (phi : formula) (assign : assign) : &#39;r =</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">match</span> phi <span class="kw">with</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  | Var x -&gt; <span class="kw">begin</span> <span class="kw">match</span> <span class="dt">List</span>.assoc_opt x r <span class="kw">with</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    | <span class="dt">Some</span> b -&gt;</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>      apply_assign assign r b fail</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    | <span class="dt">None</span> -&gt;</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>      <span class="co">(* Here we used to both call assign and pass it an anonymous function. *)</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>      apply_assign assign ((x, <span class="kw">true</span>) :: r) <span class="kw">true</span> @@ (assign, x, r) :: fail</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>      <span class="co">(* previously: fun () -&gt; assign ((x, false) :: r) false fail *)</span></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">end</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>  | Neg e -&gt;</span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>    solve r fail e (Neg1 :: assign)</span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* previously: fun r b fail -&gt; assign r (not b) fail *)</span></span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a>  | Conj (e1, e2) -&gt;</span>
<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a>    solve r fail e1 (Conj1 e2 :: assign)</span>
<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* previously: fun r b1 fail -&gt;</span></span>
<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a><span class="co">    if b1 then (* short-circuiting *)</span></span>
<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a><span class="co">      solve r fail e2 @@ fun r b2 fail -&gt; assign r (b1 &amp;&amp; b2) fail</span></span>
<span id="cb14-19"><a href="#cb14-19" aria-hidden="true" tabindex="-1"></a><span class="co">    else</span></span>
<span id="cb14-20"><a href="#cb14-20" aria-hidden="true" tabindex="-1"></a><span class="co">      assign r false fail *)</span></span>
<span id="cb14-21"><a href="#cb14-21" aria-hidden="true" tabindex="-1"></a>  | Disj (e1, e2) -&gt;</span>
<span id="cb14-22"><a href="#cb14-22" aria-hidden="true" tabindex="-1"></a>    solve r fail e1 (Disj1 e2 :: assign)</span>
<span id="cb14-23"><a href="#cb14-23" aria-hidden="true" tabindex="-1"></a>    <span class="co">(* previously: fun r b1 fail -&gt;</span></span>
<span id="cb14-24"><a href="#cb14-24" aria-hidden="true" tabindex="-1"></a><span class="co">    if b1 then</span></span>
<span id="cb14-25"><a href="#cb14-25" aria-hidden="true" tabindex="-1"></a><span class="co">      assign r true fail</span></span>
<span id="cb14-26"><a href="#cb14-26" aria-hidden="true" tabindex="-1"></a><span class="co">    else</span></span>
<span id="cb14-27"><a href="#cb14-27" aria-hidden="true" tabindex="-1"></a><span class="co">      solve r fail e2 @@ fun r b2 fail -&gt;</span></span>
<span id="cb14-28"><a href="#cb14-28" aria-hidden="true" tabindex="-1"></a><span class="co">      assign r (b1 || b2) fail *)</span></span>
<span id="cb14-29"><a href="#cb14-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-30"><a href="#cb14-30" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> solve_enter (phi : formula) : env <span class="dt">option</span> =</span>
<span id="cb14-31"><a href="#cb14-31" aria-hidden="true" tabindex="-1"></a>  solve [] <span class="co">(* the initial environment *)</span></span>
<span id="cb14-32"><a href="#cb14-32" aria-hidden="true" tabindex="-1"></a>    [] <span class="co">(* previously: fun () -&gt; None *)</span></span>
<span id="cb14-33"><a href="#cb14-33" aria-hidden="true" tabindex="-1"></a>    phi</span>
<span id="cb14-34"><a href="#cb14-34" aria-hidden="true" tabindex="-1"></a>    [] <span class="co">(* previously: fun r res fail -&gt; if res then Some r else fail () *)</span></span></code></pre></div>
<h3 id="step-4-implement-apply">Step 4: Implement <code>apply</code></h3>
<p>This step is straightforward. We write recursive functions <code>apply_failure</code> and <code>apply_assign</code> to
process the lists of type <code>failure</code> and <code>assign</code>. Notice that in the ‘previously’ comments from the
above code, some of the continuations we replaced with constructors will need to call <code>solve</code>. This
means that <code>apply_failure</code>, <code>apply_assign</code> and <code>solve</code> will all need to be mutually recursive.</p>
<p>To implement each case of <code>apply</code>, we just have to take the code from those ‘previously’ comments:
we continue translating each anonymous function into a constructor and each call to an unknown
function into a call to the corresponding <code>apply</code>.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode ocaml"><code class="sourceCode ocaml"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> <span class="kw">rec</span> solve r fail phi assign = ... <span class="co">(* as above *)</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> apply_failure (sf : failure) : env <span class="dt">option</span> = <span class="kw">match</span> sf <span class="kw">with</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  | [] -&gt; <span class="dt">None</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  | (sa, x, r) :: sf -&gt; apply_assign sa ((x, <span class="kw">false</span>) :: r) <span class="kw">false</span> sf</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="kw">and</span> apply_assign (assign : assign) (r : env) (b : <span class="dt">bool</span>) (fail : failure) : env <span class="dt">option</span> =</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">match</span> assign <span class="kw">with</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>  | [] -&gt; <span class="kw">if</span> b <span class="kw">then</span> <span class="dt">Some</span> r <span class="kw">else</span> apply_failure fail</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>  | a :: assign -&gt; <span class="kw">match</span> a <span class="kw">with</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>    | Neg -&gt; apply_assign assign r (<span class="dt">not</span> b) fail</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>    | Conj1 e2 -&gt;</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>      <span class="kw">if</span> b <span class="kw">then</span> solve r fail e2 (Conj2 b) <span class="kw">else</span> apply_assign assign r <span class="kw">false</span> fail</span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>    | Conj2 b1 -&gt;</span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>      apply_assign assign r (b1 &amp;&amp; b) fail</span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>    | Disj1 e2 -&gt;</span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>      <span class="kw">if</span> b1 <span class="kw">then</span> apply_assign assign r <span class="kw">true</span> fail <span class="kw">else</span> solve r fail e2 (Disj2 b1)</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>    | Disj2 b1 -&gt;</span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a>      apply_assign assign r (b1 &amp;&amp; b) fail</span></code></pre></div>
<h2 id="conclusion">Conclusion</h2>
<p>This is certainly a strange way of programming. Whereas in the original implementation with
higher-order continuations all the code was in pretty much one tight function, now we have the code
spread across three functions! Let’s take a step back and think about what we’ve done.</p>
<p>At first, our CPS program expressed the logic of what to do after the recursive call by placing
that logic within a continuation. Since each new continuation refers to the previous one, these
form a linked list, although this structure is not immediately obvious. At positions where the
solver wants to return a value, it instead invokes the continuation, e.g. <code>assign r (not b) fail</code>.
The continuation <code>assign</code> contains all the pending operations to do ‘on the way back’ of the
recursion. In its defunctionalized form, the solver expresses the logic of what to do next by
pushing onto a literal stack some kind of token e.g. <code>Conj1 e2</code>. When it wants to return, it
invokes <code>apply_assign</code> passing it the stack of tokens representing the remaining work to do. Then,
<code>apply_assign</code> dispatches on the stack to perform the logic that we used to express in the
anonymous function.</p>
<p>Ultimately, what we have done is rewrite the higher-order CPS code into a first-order <em>state
machine</em>. Calls to functions such as <code>solve</code>, <code>apply_failure</code>, and <code>apply_success</code> represent a
<em>state transition</em> and the collection of arguments given to such functions <em>is the state</em>.
These functions <em>examine</em> the current state to figure out what to do: <code>apply_assign</code>, for instance,
examines the call stack (represented as the type <code>assign</code>) to decide whether we finished evaluating
the formula.</p>
<p>Transforming our code in this way can serve as a guide for implementation in a lower-level
language. We can fairly straightforwardly translate this code into C: since every call in the
defunctionalized program is to a statically-known first-order function, we won’t even need to use
function pointers in implementing the C code. The resulting C program won’t even need to be
recursive: we can code it as one big while loop by effectively performing tail-call optimization
ourselves. Seeing how to translate the final code we arrived at in this article might be the topic
of a future post.</p>
<p>Naturally, defunctionalization has an inverse called <em>refunctionalization</em> (r17n). The idea
of r17n really is the opposite: we identify each position where we branch on a first-order data
structure and replace the data structure with a function that we instead call. Remarkably, this
concept is actually <a href="https://refactoring.guru/replace-conditional-with-polymorphism">a well-known refactoring</a> in the OOP world; we call it “replace
conditional with polymorphism” in that context since (object) polymorphism is effectively how one
gets higher-order functions in an OOP language. I have also written <a href="/posts/2021-08-12-its-my-first-time.html">an article</a>
previously (<em>and unknowingly!</em>) about r17n in JavaScript. Specifically, the very first example
discussed in that article shows how to replace a first-order implementation of a ‘thunk’ with a
higher-order implementation that has some garbage-collection related benefits.</p>
<p>Finally, the takeaway is that d17n and r17n are fascinating refactorings that apply across a wide
range of programming languages. Using d17n, we can prototype something in a higher-order way and
systematically lower it to a first-order implementation. The benefits are multiple: we can
reimplement in a lower-level language for performance, or we can transfer defunctionalized
continuations across nodes in a networked application. Using r17n we can convert natural
first-order code into higher-order code. The benefits in that case are less obvious, but I have yet
to see so far a refunctionalized program shorter than its corresponding first-order implementation.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>
<entry>
    <title>Refactoring Asynchronous Recursion with Continuation-Passing Style</title>
    <link href="https://jerrington.me/posts/2023-01-22-refactoring-asynchronous-recursion-continuations.html" />
    <id>https://jerrington.me/posts/2023-01-22-refactoring-asynchronous-recursion-continuations.html</id>
    <published>2023-01-22T00:00:00Z</published>
    <updated>2023-01-22T00:00:00Z</updated>
    <summary type="html"><![CDATA[<div class="info">
    Posted on January 22, 2023
    
</div>

<p>(This article was originally drafted in February 2022. The topic is very much
related to the previous article’s,
<a href="/posts/2023-01-20-recursive-closures.html">Implementing environment-based evaluation of recursive functions in OCaml</a>,
but they can very much be read independently.)</p>
<p>Whew, that’s a title that takes some unpacking!
Asynchronous recursion is a concept in JavaScript, and presumably in other
languages with some form of async-await. Maybe another way to call it would
be “indirect recursion”. A picture is worth a thousand words, so let me paint
a picture with some code. Let’s count down from a given number until we reach
zero, pausing for a second at each recursive call.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">countdown</span>(n) {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (n <span class="op">&lt;=</span> <span class="dv">0</span>) {</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>      <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>          <span class="st">&quot;No more bottles of beer on the wall, no more bottles of beer!&quot;</span><span class="op">,</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>      )<span class="op">;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span><span class="op">;</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`</span><span class="sc">${</span>n<span class="sc">}</span><span class="vs"> bottles of beer on the wall, </span><span class="sc">${</span>n<span class="sc">}</span><span class="vs"> bottles of beer! ...`</span>)<span class="op">;</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="pp">setTimeout</span>(() <span class="kw">=&gt;</span> <span class="fu">countdown</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">,</span> <span class="dv">1000</span>)<span class="op">;</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>This is what I mean by “asynchronous recursion” or “indirect recursion”. Rather
than making a recursive call as a statement of the main body of <code>countdown</code>, the
recursive call is made in a callback function to an asynchronous operation – in
this case, a timeout.</p>
<p>This pattern of recursion can be converted to a kind of continuation-passing
style (CPS). A JavaScript programmer is probably already intimately familiar
with this style of programming. For example in NodeJS, most of the standard
library works this way. Here’s an example where we delete a file:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> fs <span class="op">=</span> <span class="pp">require</span>(<span class="st">&#39;fs&#39;</span>)<span class="op">;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>fs<span class="op">.</span><span class="fu">unlink</span>(<span class="st">&#39;/tmp/hello&#39;</span><span class="op">,</span> (err) <span class="kw">=&gt;</span> {</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (err) { <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;yikes&#39;</span>)<span class="op">;</span> <span class="cf">return</span><span class="op">;</span> }</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="st">&#39;deleted /tmp/hello&#39;</span>)<span class="op">;</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>})<span class="op">;</span></span></code></pre></div>
<p>What’s special about this is that the code to execute <em>after</em> the delete has
taken place is represented as a function passed as the second parameter of
<code>unlink</code>. The call to <code>unlink</code> returns immediately so other work can be
done concurrently. When the deletion finishes, the NodeJS runtime invokes the
callback we passed, and we see either “yikes” or “deleted <code>/tmp/hello</code>”.</p>
<p>From the internal implementation of <code>unlink</code>’s point of view, it has been passed
a function that it can consider a “return function”. When <code>unlink</code>’s IO
operation is finished, it would like to return back into our code, but because
all of this happened asynchronously, there isn’t a stack frame in our code that
we can simply return to! Instead, it calls the “return function” it was passed.</p>
<p>This concept of “return function” is an instance of taking a baked-in notion
of control flow – in this case, returning from a function call – and
<em>reflecting</em> it into our code as an explicit function we can call.</p>
<p>To refactor the example of asynchronous recursion I showed earlier, we can apply
this same idea. Let’s take the control-flow idea of “making a recursive call”
and reflect it into our code as an explicit function, by rewriting <code>countdown</code>
to take an extra parameter which I’ll unimaginatively call <code>recurse</code>:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> <span class="fu">countdown</span>(recurse<span class="op">,</span> n) {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (n <span class="op">&lt;=</span> <span class="dv">0</span>) {</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>      <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>          <span class="st">&quot;No more bottles of beer on the wall, no more bottles of beer!&quot;</span><span class="op">,</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>      )<span class="op">;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span><span class="op">;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="bu">console</span><span class="op">.</span><span class="fu">log</span>(<span class="vs">`</span><span class="sc">${</span>n<span class="sc">}</span><span class="vs"> bottles of beer on the wall, </span><span class="sc">${</span>n<span class="sc">}</span><span class="vs"> bottles of beer! ...`</span>)<span class="op">;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">recurse</span>(n <span class="op">-</span> <span class="dv">1</span>)<span class="op">;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Notice that I also got rid of the <code>setTimeout</code>. The big idea here is that
<code>countdown</code> <em>doesn’t care</em> what kind of recursion the caller wants. The caller
can choose what to pass as <code>recurse</code> and get either synchronous or asynchronous
recursion as desired! The accomplishment here is also a separation of concerns:
we decoupled the behaviour for a single iteration of a recursive loop from the
“loop behaviour”.</p>
<p>The change we made to <code>countdown</code> comes at a cost, however. What exactly are we
supposed to put as a value for <code>recurse</code> when we call <code>countdown</code>??</p>
<p>To address this, we will model each kind of recursive behaviour as a separate,
higher-order function to which we can pass <code>countdown</code>. The result of applying
such a <em>recursion combinator</em> to <code>countdown</code> should be a function that takes all
the “real” parameters of <code>countdown</code>, i.e. <code>n</code>. Let’s figure out how to
implement a “standard” recursion first, then we’ll move on to asynchronous
recursion.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> recursively <span class="op">=</span> (f) <span class="kw">=&gt;</span> (<span class="op">...</span>args) <span class="kw">=&gt;</span> <span class="fu">f</span>(<span class="fu">recursively</span>(f)<span class="op">,</span> <span class="op">...</span>args)<span class="op">;</span></span></code></pre></div>
<p>To see how this works, let’s evaluate <code>recursively(countdown)</code>. There’s only
one step to do: substitute <code>countdown</code> for <code>f</code> and we arrive at
<code>(...args) =&gt; countdown(recursively(countdown), ...args)</code>.
The result is that when we call <em>this</em> function with a number such as <code>100</code>, we
in fact end up calling <em>countdown</em> passing <code>recursively(countdown)</code> itself as
the argument for the <code>recurse</code> parameter. The process then continues
recursively, we might say.</p>
<p>Finally, to make this asynchronous, we’ll need to construct a new <code>recurse</code>
function that’s more complicated than just <code>f</code>. But only a <em>bit</em> more
complicated. It will simply need to call itself within a call to <code>setTimeout</code>.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> delayedRecursively <span class="op">=</span> (f<span class="op">,</span> delay) <span class="kw">=&gt;</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    (<span class="op">...</span>args) <span class="kw">=&gt;</span> <span class="fu">f</span>(</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>        (<span class="op">...</span>args) <span class="kw">=&gt;</span> <span class="pp">setTimeout</span>(</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>            () <span class="kw">=&gt;</span> <span class="fu">f</span>(<span class="fu">delayedRecursively</span>(f<span class="op">,</span> delay)<span class="op">,</span> <span class="op">...</span>args)<span class="op">,</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>            delay<span class="op">,</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>        )<span class="op">,</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">...</span>args</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    )<span class="op">;</span></span></code></pre></div>
<p>Let’s convince ourselves that this works by evaluating <code>delayedRecursively(countdown, 100)</code>.
Substituting, we get</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>(<span class="op">...</span>args) <span class="kw">=&gt;</span> <span class="fu">countdown</span>((<span class="op">...</span>args) <span class="kw">=&gt;</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="pp">setTimeout</span>(() <span class="kw">=&gt;</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>        <span class="fu">countdown</span>(<span class="fu">delayedRecursively</span>(countdown<span class="op">,</span> <span class="dv">100</span>)<span class="op">,</span> <span class="op">...</span>args)<span class="op">,</span> <span class="dv">100</span>)<span class="op">,</span> <span class="op">...</span>args)</span></code></pre></div>
<p>If we imagine for a moment that JavaScript allows partial application, then we
can substitute further and get the following:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>(n) <span class="kw">=&gt;</span> {</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">/* ... the countdown implementation ... */</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="pp">setTimeout</span>(() <span class="kw">=&gt;</span> <span class="fu">countdown</span>(<span class="fu">delayedRecursively</span>(countdown<span class="op">,</span> <span class="dv">100</span>)<span class="op">,</span> n<span class="op">-</span><span class="dv">1</span>)<span class="op">,</span> <span class="dv">100</span>)</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>And if we ran this as <code>delayedRecursively(countdown, 500)(10)</code> we would see the
messages printed out slowly.</p>
<p>This approach works! We were able to get different recursive behaviours out of
the same implementation of <code>countdown</code>, provided it recurse through an auxiliary
function rather than directly.</p>
<p>There is however a glaring issue with this approach: there is no way for the
recursive call to meaningfully return a value to the caller! Sure, <code>recursively</code>
simply returns whatever <code>f</code> returns, so one could simply write <code>const result = recurse(...);</code> but what about when we use <code>delayedRecursively</code>? We would then
get whatever <code>setTimeout</code> returns! To address this, we will need a uniform way
to return a value, that works whether the recursion is synchronous or
asynchronous.</p>
<h2 id="returning-via-yet-another-function">Returning via yet another function</h2>
<p>The trick, as always, is to introduce yet another layer of indirection.</p>
<p>As a motivating example, let’s consider a recursive algorithm that sums the
integer values contained in a binary tree.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> sumTree <span class="op">=</span> (t) <span class="kw">=&gt;</span> {</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (t <span class="op">===</span> <span class="kw">null</span>) <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span> <span class="cf">return</span> <span class="fu">sumTree</span>(t<span class="op">.</span><span class="at">left</span>) <span class="op">+</span> t<span class="op">.</span><span class="at">value</span> <span class="op">+</span> <span class="fu">sumTree</span>(t<span class="op">.</span><span class="at">right</span>)<span class="op">;</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>First and as before, we make the recursion indirect via a <code>recurse</code> function.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> sumTree <span class="op">=</span> (recurse<span class="op">,</span> t) <span class="kw">=&gt;</span> {</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (t <span class="op">===</span> <span class="kw">null</span>) <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span> <span class="cf">return</span> <span class="fu">recurse</span>(t<span class="op">.</span><span class="at">left</span>) <span class="op">+</span> t<span class="op">.</span><span class="at">value</span> <span class="op">+</span> <span class="fu">recurse</span>(t<span class="op">.</span><span class="at">right</span>)<span class="op">;</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>Next, we observe that we have a problem if we use <code>delayedRecursively</code>: the
return value of <code>recurse(t.left)</code>, for example, won’t be the sum of the left
subtree’s elements! Let’s introduce another function parameter called <em>resolve</em>
this time. Rather than returning via the <code>return</code> statement, our function will
instead return by calling <code>resolve</code>.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> sumTree <span class="op">=</span> (recurse<span class="op">,</span> t<span class="op">,</span> resolve) <span class="kw">=&gt;</span> {</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (t <span class="op">===</span> <span class="kw">null</span>) <span class="fu">resolve</span>(<span class="dv">0</span>)<span class="op">;</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>        <span class="fu">recurse</span>(t<span class="op">.</span><span class="at">left</span><span class="op">,</span> (n1) <span class="kw">=&gt;</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>            <span class="fu">recurse</span>(t<span class="op">.</span><span class="at">right</span><span class="op">,</span> (n2) <span class="kw">=&gt;</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>                <span class="fu">resolve</span>(n1 <span class="op">+</span> t<span class="op">.</span><span class="at">value</span> <span class="op">+</span> n2)))<span class="op">;</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>What’s nice about this approach is that it works without us needing to modify
any of our recursion combinators from the previous section. We can evaluate
<code>delayedRecursively(sumTree, 100)(sampleTree, (n) =&gt; console.log(n))</code> and it
(slowly) calculates the sum of the tree and prints out the sum.</p>
<h2 id="conclusion">Conclusion</h2>
<p>In this article, we saw how to separate two concerns that at first glance seem
inextricably tried: the pattern of recursion was isolated from the recursive
algorithm itself. We introduced some combinators, <code>recursively</code> and
<code>delayedRecursively</code>, to each represent a different pattern of recursion.
Then, we rewrote our recursive algorithm to <em>recurse via a function</em> which we
named <code>recurse</code>. That refactored version of the algorithm expresses the base and
step cases of the recursive algorithm without explicitly performing the
recursion, leaving it up to the recursion combinator to decide how exactly that
will be done.
Finally, to account for a desire to return values from our functions, we
introduced one more layer of indirection by returning via a function which we
named <code>resolve</code>. No changes to the recursion combinators were necessary to
accommodate this.</p>
<p>The choice of <code>resolve</code> for the name of this function is no accident. The code
<code>recurse(t.left, (n1) =&gt; recurse(t.right, (n2) =&gt; resolve(n1 + t.value + n2)))</code>
is honestly gross. It’s callback hell. There is certainly a way of writing some
slightly different recursion combinators that take advantage of JavaScript’s
promises and <code>async</code>/<code>await</code> syntax. I leave it to the interested reader to
work this out.</p>

<script src="/js/article.js"></script>
]]></summary>
</entry>

</feed>
