<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>benjamin.pizza</title>
    <link href="http://www.benjamin.pizza/atom.xml" rel="self" />
    <link href="http://www.benjamin.pizza" />
    <id>http://www.benjamin.pizza/atom.xml</id>
    <author>
        <name>Benjamin Hodgson</name>
        
        <email>bhodgson@stackoverflow.com</email>
        
    </author>
    <updated>2025-05-21T00:00:00Z</updated>
    <entry>
    <title>Type-Level Dependency Injection</title>
    <link href="http://www.benjamin.pizza/posts/2025-05-21-type-level-dependency-injection.html" />
    <id>http://www.benjamin.pizza/posts/2025-05-21-type-level-dependency-injection.html</id>
    <published>2025-05-21T00:00:00Z</published>
    <updated>2025-05-21T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>Let’s have fun with some of C#’s recent features.</p>
<p>Imagine you’re working on a recipe app. Users can type in what ingredients they have to hand and the app will suggest some recipe ideas from its library.</p>
<p>As usual, each service in the app gets an <code>interface</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ILogger</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">Log</span><span class="op">(</span><span class="dt">string</span> message<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRecipeRepository</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>Recipe<span class="op">&gt;</span> <span class="fu">FindRecipesWithIngredient</span><span class="op">(</span><span class="dt">string</span> ingredientName<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRecipeSuggester</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>Recipe<span class="op">&gt;</span> <span class="fu">SuggestRecipes</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> ingredients<span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>When a service needs to depend on another service (via its interface), the traditional way is to use a class constructor: each dependency becomes a constructor parameter. You can change out implementations of a service by passing different arguments, and compose multiple dependencies by using multiple parameters. While it’s <em>possible</em> to hand-write your app’s composition root with <code>new</code> expressions, it can be tedious, so people use an IOC container which calls all of your services’ constructors by magic.</p>
<p>The design I want to explore instead involves declaring dependencies by using <strong>constraints on a type parameter</strong>. Each service in the system is going to take a <code>TServices</code> type parameter,</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> TopTenRecipeSuggester<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> IRecipeSuggester</span></code></pre></div><p>and each <code>interface</code> will have a corresponding “provider”.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ILoggerProvider</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">abstract</span> ILogger Logger <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRecipeRepositoryProvider</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">abstract</span> IRecipeRepository RecipeRepository <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRecipeSuggesterProvider</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="kw">abstract</span> IRecipeSuggester RecipeSuggester <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>(Why make these abstract properties <code>static</code>? It’ll become clear later.) I think of these provider interfaces as defining composable fragments of a <em>namespace</em>. Each provider claims one name (or more, why not) for its corresponding interface(s). Generic type constraints let us put the building blocks together.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> TopTenRecipeSuggester<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> IRecipeSuggester</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where TServices <span class="op">:</span> IRecipeRepositoryProvider<span class="op">,</span> ILoggerProvider</span></code></pre></div><p>That’s why the providers need to be interfaces — so we can use more than one in a constraint.</p>
<p>This is nice and composable. Each service specifies exactly the dependencies it needs, as a set of constraints on the shared <code>TServices</code> type parameter. The type system takes care of union-ing these constraints; eventually we’ll specify a single concrete type to stand in for all the instances of <code>TServices</code> and we’ll be required to implement exactly the providers that were requested by the services.</p>
<p>Now when the code needs to call a dependency, it just looks it up in the <code>TServices</code> namespace.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> TopTenRecipeSuggester<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> IRecipeSuggester</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where TServices <span class="op">:</span> IRecipeRepositoryProvider<span class="op">,</span> ILoggerProvider</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> IEnumerable<span class="op">&lt;</span>Recipe<span class="op">&gt;</span> <span class="fu">SuggestRecipes</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> ingredients<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        TServices<span class="op">.</span><span class="fu">Logger</span><span class="op">.</span><span class="fu">Log</span><span class="op">(</span><span class="st">&quot;finding recipes...&quot;</span><span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> results <span class="op">=</span> <span class="op">(</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            from i <span class="kw">in</span> ingredients</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            from r <span class="kw">in</span> TServices<span class="op">.</span><span class="fu">RecipeRepository</span><span class="op">.</span><span class="fu">FindRecipesWithIngredient</span><span class="op">(</span>i<span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            group i by r into g</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            orderby g<span class="op">.</span><span class="fu">Count</span><span class="op">()</span> descending</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            select g<span class="op">.</span><span class="fu">Key</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="op">).</span><span class="fu">Take</span><span class="op">(</span><span class="dv">10</span><span class="op">).</span><span class="fu">ToList</span><span class="op">();</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        TServices<span class="op">.</span><span class="fu">Logger</span><span class="op">.</span><span class="fu">Log</span><span class="op">(</span><span class="st">&quot;found some recipes&quot;</span><span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> results<span class="op">;</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>The dependencies are injected through a single (type) parameter. Is this <a href="https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/">the dreaded “Service Locator” anti-pattern</a>? <strong>No!</strong> The issue with Service Locator is that it makes dependencies invisible: you can’t tell how to set up a component’s dependencies without reading its source code. The constraints on the <code>TServices</code> type parameter are explicit and visible. If you want to use a service, you’re forced by the type checker to satisfy its dependencies. And the service class can’t access any dependencies other than the ones declared in the <code>where</code> clause.</p>
<p>How <em>do</em> you satisfy a set of dependencies? At the app’s <a href="https://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/#0c19d443c1ad4fd6a4c7883dcc9abb3c">composition root</a>, we need to provide a type that can stand in for the <code>TServices</code> type parameter. That amounts to defining a class that implements all of the <code>Provider</code> interfaces by supplying a concrete implementation of each service.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> CompositionRoot <span class="op">:</span> ILoggerProvider<span class="op">,</span> IRecipeRepositoryProvider<span class="op">,</span> IRecipeSuggesterProvider</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// CompositionRoot supplies itself as the TServices type parameter</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> ILogger Logger <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> ConsoleLogger<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> IRecipeRepository RecipeRepository <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> DbRecipeRepository<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;();</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> IRecipeSuggester RecipeSuggester <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> TopTenRecipeSuggester<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;();</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Finally, at the app’s entry point, you can pick out services directly from the <code>CompositionRoot</code>. (Typically you want to keep this layer thin: just call out to a controller object.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">// Program.cs</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>CompositionRoot<span class="op">.</span><span class="fu">RecipeSuggestionController</span><span class="op">.</span><span class="fu">Run</span><span class="op">();</span></span></code></pre></div><h2 id="composable-composition-root"><a href="#composable-composition-root">Composable Composition Root</a></h2>
<p>One problem with the <code>CompositionRoot</code> is that it’s difficult to swap out an implementation of a service. <code>CompositionRoot</code> passes itself as the <code>TServices</code> type parameter — not “the concrete type of the instance” — so you can’t override a property by subclassing it.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> TestCompositionRoot <span class="op">:</span> CompositionRoot</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// This doesn&#39;t work - the TopTenRecipeSuggester is still going to</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// look in CompositionRoot to find its dependencies.</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> <span class="kw">override</span> IRecipeRepository RecipeRepository <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> MockRecipeRepository<span class="op">&lt;</span>TestCompositionRoot<span class="op">&gt;();</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>You’d have to define an entirely separate composition root for testing instead.</p>
<blockquote class="callout callout-note">
<h3>Note</h3>
<p>I actually don’t think this is too bad, or at least, it’s also a weak spot for classic constructor injection. With classic constructor injection, tests typically <code>new</code> up the SUT and specify all of its dependencies by hand anyway. Type-Level DI has somewhat more boilerplate but not, like, asymptotically more.</p>
</blockquote>
<p>Anyway, we can patch this up using one of my favourite cursed tricks: <em>F-bounds</em> (aka the <em>curiously recurring template pattern</em>). <code>CompositionRoot</code> will (become an interface and) take a <code>TServices</code> type parameter itself. <code>TServices</code> stands in for the eventual concrete type of the composition root.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ICompositionRoot<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> ILoggerProvider<span class="op">,</span> IRecipeRepositoryProvider<span class="op">,</span> IRecipeSuggesterProvider</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where TServices <span class="op">:</span> ICompositionRoot<span class="op">&lt;</span>TServices<span class="op">&gt;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> ILogger ILoggerProvider<span class="op">.</span><span class="fu">Logger</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> ConsoleLogger<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> IRecipeRepository IRecipeRepositoryProvider<span class="op">.</span><span class="fu">RecipeRepository</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> DbRecipeRepository<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> IRecipeSuggester IRecipeSuggesterProvider<span class="op">.</span><span class="fu">RecipeSuggester</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> TopTenRecipeSuggester<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><blockquote class="callout callout-note">
<h3>Note</h3>
<p>Now you can see why I made the providers’ properties <code>static</code>. Interfaces can’t have (non-static) fields, and accordingly non-static interface properties can’t have initialisers because there’s no corresponding storage location.</p>
</blockquote>
<p>This arrangement allows you to derive another interface from <code>CompositionRoot</code>, override whatever you need, and forward the type parameter.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMockCompositionRoot<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> ICompositionRoot<span class="op">&lt;</span>TServices<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where TServices <span class="op">:</span> IMockCompositionRoot<span class="op">&lt;</span>TServices<span class="op">&gt;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> IRecipeRepository IRecipeRepositoryProvider<span class="op">.</span><span class="fu">RecipeRepository</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> MockRecipeRepository<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Eventually, when it’s time to run code, someone will derive an <em>empty</em> concrete class which plugs itself in as the <code>TServices</code> type parameter.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> CompositionRoot <span class="op">:</span> ICompositionRoot<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;</span> <span class="op">{}</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> MockCompositionRoot <span class="op">:</span> IMockCompositionRoot<span class="op">&lt;</span>MockCompositionRoot<span class="op">&gt;</span> <span class="op">{}</span></span></code></pre></div><p>Why stop here? Let’s split up <code>CompositionRoot</code>’s fields into individual interfaces. Each concrete service implementation now has its own provider…</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IConsoleLoggerProvider<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> ILoggerProvider</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> ILogger ILoggerProvider<span class="op">.</span><span class="fu">Logger</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> ConsoleLogger<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IDbRecipeRepositoryProvider<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> IRecipeRepositoryProvider</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> IRecipeRepository IRecipeRepositoryProvider<span class="op">.</span><span class="fu">RecipeRepository</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> DbRecipeRepository<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ITopTenRecipeSuggesterProvider<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span> IRecipeSuggesterProvider</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    where TServices <span class="op">:</span> ILoggerProvider<span class="op">,</span> IRecipeRepositoryProvider</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> IRecipeSuggester IRecipeSuggesterProvider<span class="op">.</span><span class="fu">RecipeSuggester</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> TopTenRecipeSuggester<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>… and the <code>CompositionRoot</code> just composes the concrete providers by inheritance, once again passing itself as the <code>TServices</code> type parameter. You don’t need to write out the concrete service implementations any more.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> CompositionRoot <span class="op">:</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    IConsoleLoggerProvider<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IDbRecipeRepositoryProvider<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    ITopTenRecipeSuggesterProvider<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Beautiful! (I rather like nesting the concrete providers inside their corresponding concrete service, so, <code>ConsoleLogger&lt;TServices&gt;.Provider</code> instead of <code>IConsoleLoggerProvider&lt;TServices&gt;</code>. You can even nest the abstract providers in the service interfaces: <code>ILogger.Provider</code>.)</p>
<p>You can mix and match if you like: bundle some or all of your services into a single interface, and override them one at a time with inheritance.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ICompositionRoot<span class="op">&lt;</span>TServices<span class="op">&gt;</span> <span class="op">:</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    IConsoleLoggerProvider<span class="op">&lt;</span>TServices<span class="op">&gt;,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IDbRecipeRepositoryProvider<span class="op">&lt;</span>TServices<span class="op">&gt;,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    ITopTenRecipeSuggesterProvider<span class="op">&lt;</span>TServices<span class="op">&gt;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    where TServices <span class="op">:</span> ICompositionRoot<span class="op">&lt;</span>TServices<span class="op">&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> CompositionRoot <span class="op">:</span> ICompositionRoot<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> MockCompositionRoot <span class="op">:</span> ICompositionRoot<span class="op">&lt;</span>MockCompositionRoot<span class="op">&gt;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> IRecipeRepository IRecipeRepositoryProvider<span class="op">.</span><span class="fu">RecipeRepository</span> <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="op">=</span> <span class="kw">new</span> MockRecipeRepository<span class="op">&lt;</span>TServices<span class="op">&gt;();</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>There’s one minor inconvenience with this arrangement: at your app’s entry point, it’s now a little more difficult to use <code>CompositionRoot</code> directly. You have to go via a (constrained) type parameter to access the interface’s static properties.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">// Program.cs</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>GetController<span class="op">&lt;</span>CompositionRoot<span class="op">&gt;().</span><span class="fu">Run</span><span class="op">();</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> IRecipeSuggestionController GetController<span class="op">&lt;</span>T<span class="op">&gt;()</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> IRecipeSuggestionControllerProvider</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> T<span class="op">.</span><span class="fu">RecipeSuggestionController</span><span class="op">;</span></span></code></pre></div><p>Writing an additional provider interface for each component in your system (a concrete provider for each concrete service, and an abstract provider for each of their interfaces) is tedious boilerplate, but at least it’s the kind of thing you can automate with a source generator.</p>
<h2 id="some-thoughts-on-modules"><a href="#some-thoughts-on-modules">Some Thoughts on Modules</a></h2>
<p>Why do we do dependency injection with constructors and interfaces? Object oriented languages expect you to do all your modelling, at every level of your system, using the tools of objects. But in practice I feel there are (at least) two separate types of objects. Honest-to-goodness <em>objects</em> manage data, have a lifetime, may have many instances. But <em>services</em> are really just organisational conveniences — they simply bundle up a set of functions and dependencies, they’re stateless, and there’s typically only one of each service in a given application.</p>
<p>It’s weird that we model both of these concepts with classes! We want to do <strong>modular</strong> programming: make components loosely coupled, program to well-designed interfaces and hide implementations. But mainstream object oriented languages don’t have tools for programming modules, so we’re stuck reusing constructs that are better suited to managing units of data. Shut up and write classes!</p>
<p>I freely admit my design for TLDI is grotesque. But let’s admit that IOC containers like <a href="https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection">MEDI</a> are grotesque too. They exist to paper over the deficiency of modular programming in OO languages. It was tedious to write <code>new</code> statements to wire up concrete dependencies for every service in your system, and frameworks like ASP.NET needed a generic way to create instances of service classes, manage their lifetimes, and provide their dependencies. I don’t think IOC registration code is very much more tasteful than <code>new</code> statements, but in any case we should recognise that “instances of service classes” is a thoroughly object-oriented framing of the problem: IOC containers are caused by constructor injection.</p>
<p>I don’t quite understand why today’s industrial strength languages don’t have built-in facilities for managing components and dependencies. I would love to see a language (other than OCaml) take modular programming and dependency injection seriously. Maybe next time I’ll jot down some ideas of how to design such a system.</p>

]]></summary>
</entry>
<entry>
    <title>Prettier. Happier. More Imperative.</title>
    <link href="http://www.benjamin.pizza/posts/2024-08-15-prettier-happier-more-imperative.html" />
    <id>http://www.benjamin.pizza/posts/2024-08-15-prettier-happier-more-imperative.html</id>
    <published>2024-08-15T00:00:00Z</published>
    <updated>2024-08-15T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>Phil Wadler’s pearl <a href="https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf"><em>A Prettier Printer</em></a> is a classic example of functional design. Starting with a simple model and some algebraic laws, Wadler <em>derives</em> an implementation of a well behaved layout algorithm. It’s a great read — go and read it if you haven’t! (I’m going to assume you have read it and try not to recapitulate too much below.)</p>
<p>I learned a lot about Wadler’s algorithm by translating it to an imperative language. I think Wadler’s explanation skims over a couple of interesting behavioural details of his algorithm, and those details are actually a little easier to see in an imperative setting.</p>
<p>You can find (a productionised version of) the code I’m going to present today <a href="https://github.com/benjamin-hodgson/Gutenberg/blob/main/Gutenberg/LayoutEngine.cs">in my library <code>Gutenberg</code></a>. As you’ll see, the code fuses together lots of my favourite programming ideas: it’s a combinator library, with a purely functional front end, backed by a logic programming engine, written as a stack machine! Let’s dive in.</p>
<h2 id="wadlers-code"><a href="#wadlers-code">Wadler’s Code</a></h2>
<p>Wadler’s library is designed around a datatype of <em>documents</em>. A document represents a block of text with some optional line breaks and indentation. To use the library, you construct a document using the provided combinators, and then invoke the layout algorithm to render the document as a string.</p>
<p>For example, you might construct a document containing a code listing for a function call. If the function’s arguments can all fit on one line then the expression should be flattened,</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>printf<span class="op">(</span><span class="st">&quot;My </span><span class="sc">%s</span><span class="st"> is named </span><span class="sc">%s</span><span class="st">.&quot;</span><span class="op">,</span> <span class="st">&quot;cat&quot;</span><span class="op">,</span> <span class="st">&quot;Prune&quot;</span><span class="op">);</span></span></code></pre></div><p>but a longer expression might need to be broken up with each argument on its own line.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>printf<span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;My </span><span class="sc">%s</span><span class="st"> is named </span><span class="sc">%s</span><span class="st">. She eats </span><span class="sc">%s</span><span class="st">&quot;</span><span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;cat&quot;</span><span class="op">,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;Prune&quot;</span><span class="op">,</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="st">&quot;Tender Chicken Chunks&quot;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">);</span></span></code></pre></div><p>Typically you’ll annotate your document with several different sets of line break hints. So a given document can be laid out in a number of ways. The layout algorithm’s job is to choose the best layout — meaning one which makes good use of the available horizontal space and doesn’t introduce more line breaks than necessary.</p>
<p>Internally, the notion of a <em>choice of layouts</em> is represented by the <code>:&lt;|&gt;</code> constructor: <code>doc1 :&lt;|&gt; doc2</code> means “<code>doc1</code> is a preferable layout, but <code>doc2</code> can be used as a fallback if <code>doc1</code> causes the text to overflow the page width”. The layout algorithm takes a document containing <code>:&lt;|&gt;</code>s and produces one without.</p>
<p>The work is done by the function <code>best</code>. Here it is, with some cosmetic tweaks:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>best</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Int</span>  <span class="co">-- ^ The page width</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Int</span>  <span class="co">-- ^ The number of characters already consumed on the current line</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">DOC</span>  <span class="co">-- ^ The document to lay out</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Doc</span>  <span class="co">-- ^ The laid-out document</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>best w k x <span class="ot">=</span> be k [(<span class="dv">0</span>, x)]</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        be k [] <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        be k ((i, <span class="dt">NIL</span>)<span class="op">:</span>z) <span class="ot">=</span> be k z</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        be k ((i, x <span class="op">:&lt;&gt;</span> y)<span class="op">:</span>z) <span class="ot">=</span> be k ((i, x)<span class="op">:</span>(i, y)<span class="op">:</span>z)</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        be k ((i, <span class="dt">NEST</span> j x)<span class="op">:</span>z) <span class="ot">=</span> be k ((i<span class="op">+</span>j, x)<span class="op">:</span>z)</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        be k ((i, <span class="dt">TEXT</span> s)<span class="op">:</span>z) <span class="ot">=</span> <span class="dt">Text</span> s (be (k <span class="op">+</span> <span class="fu">length</span> s) z)</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        be k ((i, <span class="dt">LINE</span>)<span class="op">:</span>z) <span class="ot">=</span> <span class="dt">Line</span> i (be i z)</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        be k ((i, x <span class="op">:&lt;|&gt;</span> y)<span class="op">:</span>z)</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            <span class="ot">=</span> better k</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                (be k ((i, x)<span class="op">:</span>z))</span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                (be k ((i, y)<span class="op">:</span>z))</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        better k x y <span class="ot">=</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> fits (w<span class="op">-</span>k) x</span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            then x</span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>            else y</span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>fits w x <span class="op">|</span> w <span class="op">&lt;</span> <span class="dv">0</span> <span class="ot">=</span> <span class="dt">False</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>fits w <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">True</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>fits w (<span class="dt">Text</span> s x) <span class="ot">=</span> fits (w <span class="op">-</span> <span class="fu">length</span> s) x</span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>fits w (<span class="dt">Line</span> i x) <span class="ot">=</span> <span class="dt">True</span></span></code></pre></div><p>Let’s try to reconstruct Wadler’s code in an imperative style.</p>
<h2 id="wadlers-two-documents"><a href="#wadlers-two-documents">Wadler’s Two Documents</a></h2>
<p>Section 3 of the paper is all about designing an efficient representation for documents. Wadler calls it <code>DOC</code>. It took me a while to grasp the reason for the new name: he’s keeping the old <code>Doc</code> around (in modified form — it lacks the <code>Union</code> constructor).</p>
<ul>
<li><strong><code>DOC</code> is the API</strong>. It’s the core representation of documents that users of the library interact with. It’s an abstract type — you create <code>DOC</code>s using the provided combinators, not by calling its constructors directly.
</li>
<li><strong><code>Doc</code> is an intermediate representation</strong>. It’s the result of laying out a document (it’s returned by <code>best</code>). Wadler gives a function (awkwardly named <code>layout</code>) to display a <code>Doc</code> as a string but you can imagine other backends (for example, writing directly to the console).
</li>
</ul>
<p>I think Wadler’s choice of names could use some improvement — <a href="https://hackage.haskell.org/package/prettyprinter">the modern <code>prettyprinter</code> library</a> uses <code>SimpleDocStream</code> for the latter. Structurally, <code>Doc</code>(/<code>SimpleDocStream</code>) is a <em>list</em> of literal text chunks interspersed with line-breaks-with-indentation:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Doc</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Text</span> <span class="dt">String</span> <span class="dt">Doc</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Line</span> <span class="dt">Int</span> <span class="dt">Doc</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="co">-- equivalently,</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Doc</span> <span class="ot">=</span> [<span class="dt">Either</span> <span class="dt">String</span> <span class="dt">Int</span>]</span></code></pre></div><p>But in an imperative language it might be better to conceive of <code>Doc</code> as a <em>sequence of instructions</em> for a rendering backend. In C#, it’s more natural to abstract over backends using an interface, rather than an intermediate data structure:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IDocumentRenderer</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">WriteText</span><span class="op">(</span><span class="dt">string</span> text<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">WriteLineBreak</span><span class="op">(</span><span class="dt">int</span> indentation<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="best-is-a-stack-machine"><a href="#best-is-a-stack-machine"><code>best</code> is a Stack Machine</a></h2>
<p>In Section 3, Wadler somewhat opaquely describes “generalising each operation to work on a list of indentation-document pairs”. He’s talking specifically about <code>be</code> (<code>best</code>’s inner loop). Let’s take a look at a few of its clauses to figure out what he means:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>best w k x <span class="ot">=</span> be k [(<span class="dv">0</span>, x)]</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        be k [] <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        be k ((i, <span class="dt">NIL</span>)<span class="op">:</span>z) <span class="ot">=</span> be k z</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        be k ((i, x <span class="op">:&lt;&gt;</span> y)<span class="op">:</span>z) <span class="ot">=</span> be k ((i, x)<span class="op">:</span>(i, y)<span class="op">:</span>z)</span></code></pre></div><p>The list is initialised to a single item and thereafter the code only manipulates the front few items. The list is being treated as a stack. This stack represents a work stream — each item in the stack is a fragment of the document which hasn’t been laid out yet. The top item is the <em>next</em> fragment to be laid out.</p>
<p>So let’s write a loop that mutates a stack. (I’ll come back to the <code>:&lt;|&gt;</code> case — it requires special consideration!)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">Layout</span><span class="op">(</span>Document doc<span class="op">,</span> IDocumentRenderer renderer<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> stack <span class="op">=</span> <span class="kw">new</span> Stack<span class="op">&lt;(</span><span class="dt">int</span><span class="op">,</span> Document<span class="op">)&gt;();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span><span class="dv">0</span><span class="op">,</span> doc<span class="op">));</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">while</span> <span class="op">(</span>stack<span class="op">.</span><span class="fu">Count</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="fu">var</span> <span class="op">(</span>indentation<span class="op">,</span> current<span class="op">)</span> <span class="op">=</span> stack<span class="op">.</span><span class="fu">Pop</span><span class="op">();</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">switch</span> <span class="op">(</span>current<span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">case</span> Empty<span class="op">:</span>  <span class="co">// NIL</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                <span class="kw">break</span><span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">case</span> LineBreak<span class="op">:</span>  <span class="co">// LINE</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                renderer<span class="op">.</span><span class="fu">WriteLineBreak</span><span class="op">(</span>indentation<span class="op">);</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                <span class="kw">break</span><span class="op">;</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            <span class="kw">case</span> <span class="fu">Text</span><span class="op">(</span><span class="dt">var</span> s<span class="op">):</span>  <span class="co">// TEXT</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                renderer<span class="op">.</span><span class="fu">WriteText</span><span class="op">(</span>s<span class="op">);</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>                <span class="kw">break</span><span class="op">;</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>            <span class="kw">case</span> <span class="fu">Concat</span><span class="op">(</span><span class="dt">var</span> l<span class="op">,</span> <span class="dt">var</span> r<span class="op">):</span>  <span class="co">// l :&lt;&gt; r</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>                stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>indentation<span class="op">,</span> r<span class="op">));</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>                stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>indentation<span class="op">,</span> l<span class="op">));</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>                <span class="kw">break</span><span class="op">;</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>            <span class="kw">case</span> <span class="fu">Nested</span><span class="op">(</span><span class="dt">var</span> i<span class="op">,</span> <span class="dt">var</span> d<span class="op">):</span>  <span class="co">// NEST i d</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>                stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>indentation <span class="op">+</span> i<span class="op">,</span> d<span class="op">));</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>                <span class="kw">break</span><span class="op">;</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>For example, here’s a diagram of what happens to the stack when processing a document consisting of two literal strings.</p>
<pre><code>                             +-----------+
                             |   &quot;foo&quot;   |
+---------------------+      +-----------+      +-----------+
| Concat(&quot;foo&quot;,&quot;bar&quot;) |      |   &quot;bar&quot;   |      |   &quot;bar&quot;   |
+---------------------+  =&gt;  +-----------+  =&gt;  +-----------+  =&gt;  +-------+
|          ...        |      |    ...    |      |    ...    |      |  ...  |
                                         Output:    &quot;foo&quot;          &quot;foobar&quot;
</code></pre>
<h2 id="backtracking"><a href="#backtracking">Backtracking</a></h2>
<p>Now let’s look at the <code>:&lt;|&gt;</code> case.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>be k ((i, x <span class="op">:&lt;|&gt;</span> y)<span class="op">:</span>z)</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> better k</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        (be k ((i, x)<span class="op">:</span>z))</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        (be k ((i, y)<span class="op">:</span>z))</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>better k x y <span class="ot">=</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> fits (w<span class="op">-</span>k) x</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">then</span> x</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> y</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>fits w x <span class="op">|</span> w <span class="op">&lt;</span> <span class="dv">0</span> <span class="ot">=</span> <span class="dt">False</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>fits w <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">True</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>fits w (<span class="dt">Text</span> s x) <span class="ot">=</span> fits (w <span class="op">-</span> <span class="fu">length</span> s) x</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>fits w (<span class="dt">Line</span> i x) <span class="ot">=</span> <span class="dt">True</span></span></code></pre></div><p>This is the key part of the layout algorithm: deciding which of two alternative layouts to use, based on whether it causes the document to overflow the available horizontal space.</p>
<p>The stack <code>z</code> represents <em>the rest of the document</em> to be laid out. The code concatenates the first alternative <code>x</code> onto the front of the document <code>z</code> and lays out the document to see if it’ll fit in the allocated page width. If it doesn’t fit, we’ll push the fallback layout <code>y</code> onto the stack and lay that out instead.</p>
<p>It’s important that we attempt to lay out the whole document — <code>x</code> <em>and</em> <code>z</code>, not just <code>x</code> — when seeing if it’ll fit. Choosing the <code>x</code> alternative might cause an overflow later (when processing a document that’s right now buried somewhere below the current top of the stack), even if <code>x</code> fits on its own. In other words this is a <em>backtracking</em> operation: if a layout with <code>x</code> overflows later in the line, we backtrack to the point at which we chose <code>x</code>, forgetting any layout decisions we made while rendering <code>x:z</code>.</p>
<p>This code is tricky to port to an imperative style because it makes central use of immutability and laziness:</p>
<ul>
<li><strong>The rest of the document is duplicated</strong>. Using <code>z</code> twice like that requires <code>z</code> to be immutable (well, persistent). If we mutate <code>z</code> while laying out the first alternative, by pushing and popping things from it, it won’t be in the same state by the time we decide to fall back on <code>y</code> if it doesn’t fit!
</li>
<li><strong><code>fits</code> only reads as far as the end of the line</strong>, so backtracking is bounded to <code>lineWidth</code> characters. If the current line fits, then there’s nothing to be gained by trying a less-flat alternative. This requires lazy evaluation: we don’t want to lay out the entire document just to see whether the first line fits!
</li>
<li>We need some way of <em>undoing</em> any calls to the <code>IDocumentRenderer</code> that were made in the course of laying out <code>x</code>.
</li>
</ul>
<blockquote class="callout callout-note">
<h3>Aside: A Thought On Laziness</h3>
<p></p>
<p>Wadler wrote a function that looks like it lays out the entire document, but because the language is lazy it never actually processes more than one line at a time. Cool! But, I dunno, understanding this took me some head-scratching because this important aspect of the control flow is not visible in the text of the code. Laziness can be a mixed blessing — it lets us separate producers and consumers in novel ways, <em>but</em> it makes control flow implicit. Perhaps I’m still just not good enough at thinking lazily.</p>
<p>(I tried implementing the backtracking behaviour <a href="https://gist.github.com/benjamin-hodgson/8b3062e9715f10b6c74f65424cab9b27">using a failure continuation</a>. The code is certainly more complex and uglier than Wadler’s — there are two mutually recursive continuation types! — but it has the benefit of being very explicit about <a href="https://gist.github.com/benjamin-hodgson/8b3062e9715f10b6c74f65424cab9b27#file-prettiercps-hs-L48">when backtracking can happen</a> and <a href="https://gist.github.com/benjamin-hodgson/8b3062e9715f10b6c74f65424cab9b27#file-prettiercps-hs-L61">what to do when it does</a>.)</p>
</blockquote>
<p>Anyway, we can handle the latter two issues imperatively by <em>buffering</em> the output text one line at a time. If we reach the end of the line without overflowing, we can flush the buffer’s contents out to the <code>IDocumentRenderer</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">Layout</span><span class="op">(</span>Document doc<span class="op">,</span> IDocumentRenderer renderer<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> buffer <span class="op">=</span> <span class="kw">new</span> List<span class="op">&lt;</span><span class="dt">char</span><span class="op">&gt;();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> stack <span class="op">=</span> <span class="kw">new</span> Stack<span class="op">&lt;(</span><span class="dt">int</span><span class="op">,</span> Document<span class="op">)&gt;();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span><span class="dv">0</span><span class="op">,</span> doc<span class="op">));</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">while</span> <span class="op">(</span>stack<span class="op">.</span><span class="fu">Count</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="fu">var</span> <span class="op">(</span>indentation<span class="op">,</span> current<span class="op">)</span> <span class="op">=</span> stack<span class="op">.</span><span class="fu">Pop</span><span class="op">();</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">switch</span> <span class="op">(</span>current<span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            <span class="kw">case</span> LineBreak<span class="op">:</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>                <span class="co">// Flush the buffer</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                renderer<span class="op">.</span><span class="fu">WriteText</span><span class="op">(</span><span class="kw">new</span> <span class="dt">string</span><span class="op">(</span>buffer<span class="op">.</span><span class="fu">ToArray</span><span class="op">()));</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                renderer<span class="op">.</span><span class="fu">WriteLineBreak</span><span class="op">(</span>indentation<span class="op">);</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                buffer<span class="op">.</span><span class="fu">Clear</span><span class="op">();</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                <span class="kw">break</span><span class="op">;</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="kw">case</span> <span class="fu">Text</span><span class="op">(</span><span class="dt">var</span> s<span class="op">):</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>                buffer<span class="op">.</span><span class="fu">Add</span><span class="op">(</span>s<span class="op">);</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>                <span class="kw">break</span><span class="op">;</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            <span class="co">// ... other cases unchanged</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>What to do in the case of an overflow? We need to reset the state of the layout algorithm to how it was before we tried to lay out <code>x</code>. This involves putting the stack back how it was at that time and also dropping any chunks that were written to the buffer since then.</p>
<p>Let’s record every alternative we’ve tried in a separate stack of <em>choice points</em>. A choice point is a data structure containing a fallback alternative and the current state of the layout algorithm — consisting of the length of the buffer and the state of the stack. We have to make a copy of the stack because it’s mutable.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> choicePoints <span class="op">=</span> <span class="kw">new</span> Stack<span class="op">&lt;</span>ChoicePoint<span class="op">&gt;();</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="co">// ... in the switch block:</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">case</span> <span class="fu">ChoiceDoc</span><span class="op">(</span><span class="dt">var</span> x<span class="op">,</span> <span class="dt">var</span> y<span class="op">):</span>  <span class="co">// x :&lt;|&gt; y</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    choicePoints<span class="op">.</span><span class="fu">Push</span><span class="op">(</span><span class="kw">new</span> <span class="fu">ChoicePoint</span><span class="op">(</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        indentation<span class="op">,</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        y<span class="op">,</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        buffer<span class="op">.</span><span class="fu">Count</span><span class="op">,</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="fu">Copy</span><span class="op">(</span>stack<span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">));</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>indentation<span class="op">,</span> x<span class="op">));</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">break</span><span class="op">;</span></span></code></pre></div><p>Now when an overflow happens we can backtrack to the last choice point. And if we reach the end of the line without overflowing, we can discard any remaining choice points.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">case</span> <span class="fu">Text</span><span class="op">(</span><span class="dt">var</span> s<span class="op">):</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    buffer<span class="op">.</span><span class="fu">AddRange</span><span class="op">(</span>s<span class="op">);</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>buffer<span class="op">.</span><span class="fu">Count</span> <span class="op">&gt;</span> LineWidth <span class="op">&amp;&amp;</span> choicePoints<span class="op">.</span><span class="fu">Count</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="fu">Backtrack</span><span class="op">();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">break</span><span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="kw">case</span> LineBreak<span class="op">:</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    renderer<span class="op">.</span><span class="fu">WriteText</span><span class="op">(</span><span class="kw">new</span> <span class="dt">string</span><span class="op">(</span>buffer<span class="op">.</span><span class="fu">ToArray</span><span class="op">()));</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    renderer<span class="op">.</span><span class="fu">WriteLineBreak</span><span class="op">(</span>indentation<span class="op">);</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    buffer<span class="op">.</span><span class="fu">Clear</span><span class="op">();</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="fu">Commit</span><span class="op">();</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">break</span><span class="op">;</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">Backtrack</span><span class="op">()</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="fu">var</span> <span class="op">(</span>i<span class="op">,</span> y<span class="op">,</span> bufLen<span class="op">,</span> s<span class="op">)</span> <span class="op">=</span> choicePoints<span class="op">.</span><span class="fu">Pop</span><span class="op">();</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    stack <span class="op">=</span> s<span class="op">;</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    buffer<span class="op">.</span><span class="fu">RemoveRange</span><span class="op">(</span>bufLen<span class="op">,</span> buffer<span class="op">.</span><span class="fu">Count</span> <span class="op">-</span> bufLen<span class="op">);</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>i<span class="op">,</span> y<span class="op">));</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">Commit</span><span class="op">()</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>    choicePoints<span class="op">.</span><span class="fu">Clear</span><span class="op">();</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="a-cue-from-prolog"><a href="#a-cue-from-prolog">A Cue From Prolog</a></h2>
<p>Copying the stack when we create a choice point is ugly and inefficient: each copy operation takes linear time and space, and we make a linear number of copies (one for every choice point), resulting in quadratic performance.</p>
<p>I thought about trying to amortise the copying operation with some sort of copy-on-write mechanism. But around the time I was working on this library I’d been <a href="https://github.com/a-yiorgos/wambook">reading about Warren’s Abstract Machine</a> — a backend for Prolog implementations — and that gave me a better idea.</p>
<p>In the WAM, choice points are stored <em>on the execution stack</em> interspersed with the predicates’ stack frames. Things are arranged such that choice points are only popped from the stack after backtracking, not during normal execution. This prevents any preceding stack frames from being discarded, so that the state of the call stack can be restored upon backtracking. (The relevant section of <a href="https://github.com/a-yiorgos/wambook">the book</a> is Section 4.1, <em>Environment Protection</em>.)</p>
<p>We can apply this idea to the layout engine. The items in the work stream will now be either a <code>Document</code> to be rendered or a choice point.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">case</span> <span class="fu">ChoiceDoc</span><span class="op">(</span><span class="dt">var</span> x<span class="op">,</span> <span class="dt">var</span> y<span class="op">):</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        indentation<span class="op">,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">ChoicePoint</span><span class="op">(</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            y<span class="op">,</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            buffer<span class="op">.</span><span class="fu">Count</span><span class="op">,</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            canBacktrack<span class="op">,</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>            continuation<span class="op">:</span> stack<span class="op">.</span><span class="fu">Count</span> <span class="op">-</span> <span class="dv">1</span>  <span class="co">// see below</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">));</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>indentation<span class="op">,</span> x<span class="op">));</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    canBacktrack <span class="op">=</span> <span class="kw">true</span><span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">break</span><span class="op">;</span></span></code></pre></div><p>The stack transition looks like this (supposing that the <code>Choice</code> document is encountered when the stack has two items):</p>
<pre><code>                          +------------------+
3                         |         x        |
    +--------------+      +------------------+
    |              |      |   ChoicePoint    |
2   | Choice(x, y) |      | Continuation = 1 |
    |              |      |   Fallback = y   |
    +--------------+  =&gt;  +------------------+
1   |     ...      |      |        ...       |
    +--------------+      +------------------+
0   |              |      |                  |
</code></pre>
<p>Upon encountering a choice point in the work stream, we’ll <em>leave the choice point where it is</em> and continue rendering the document that’s underneath it. This may result in new document fragments being piled on top of the choice point (and then being processed themselves). That means we’ll likely encounter each choice point multiple times. Each choice point will maintain a <em>continuation pointer</em> to the next document fragment to render in the non-backtracking code path.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">case</span> ChoicePoint cp<span class="op">:</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> continuation <span class="op">=</span> <span class="fu">GetContinuation</span><span class="op">(</span>cp<span class="op">.</span><span class="fu">Continuation</span><span class="op">);</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>continuation <span class="op">&lt;</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="co">// We’ve processed the whole document!</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        renderer<span class="op">.</span><span class="fu">WriteText</span><span class="op">(</span><span class="kw">new</span> <span class="dt">string</span><span class="op">(</span>buffer<span class="op">.</span><span class="fu">ToArray</span><span class="op">()));</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span><span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// put the choice point back where it was</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// and process the continuation</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    cp<span class="op">.</span><span class="fu">Continuation</span> <span class="op">=</span> continuation <span class="op">-</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>indentation<span class="op">,</span> cp<span class="op">));</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    stack<span class="op">.</span><span class="fu">Push</span><span class="op">(</span>stack<span class="op">[</span>continuation<span class="op">]);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">break</span><span class="op">;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> <span class="fu">GetContinuation</span><span class="op">(</span><span class="dt">int</span> i<span class="op">)</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">while</span> <span class="op">(</span>i <span class="op">&gt;=</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> stack<span class="op">[</span>i<span class="op">]</span> <span class="kw">is</span> ChoicePoint cp<span class="op">)</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        i <span class="op">=</span> cp<span class="op">.</span><span class="fu">Continuation</span><span class="op">;</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> i<span class="op">;</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>The stack transition looks like this. The document fragment that was at the <code>Continuation</code> index is duplicated to the top of the stack.</p>
<pre><code>                              +------------------+
3                             |        z         |
    +------------------+      +------------------+
    |   ChoicePoint    |      |   ChoicePoint    |
2   | Continuation = 1 |      | Continuation = 0 |
    |   Fallback = y   |      |   Fallback = y   |
    +------------------+  =&gt;  +------------------+
1   |        z         |      |        z         |
    +------------------+      +------------------+
0   |       ...        |      |       ...        |
</code></pre>
<p>When backtracking, we’ll discard any stack items on top of the latest choice point.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">Backtrack</span><span class="op">()</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">while</span> <span class="op">(</span>stack<span class="op">.</span><span class="fu">Count</span> <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="fu">var</span> <span class="op">(</span>indentation<span class="op">,</span> item<span class="op">)</span> <span class="op">=</span> stack<span class="op">.</span><span class="fu">Pop</span><span class="op">();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(</span>item <span class="kw">is</span> <span class="fu">ChoicePoint</span><span class="op">(</span><span class="dt">var</span> y<span class="op">,</span> <span class="dt">var</span> bufLen<span class="op">,</span> <span class="dt">var</span> b<span class="op">,</span> _<span class="op">))</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>            stack<span class="op">.</span><span class="fu">Push</span><span class="op">((</span>indentation<span class="op">,</span> y<span class="op">));</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            buffer<span class="op">.</span><span class="fu">RemoveRange</span><span class="op">(</span>bufLen<span class="op">,</span> buffer<span class="op">.</span><span class="fu">Count</span> <span class="op">-</span> bufLen<span class="op">);</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            canBacktrack <span class="op">=</span> b<span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span><span class="op">;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Finally, when we reach the end of a line, any choice points (and the document fragments they were protecting) can be discarded. The <code>Empty</code> document does double duty as a tombstone.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> <span class="fu">Commit</span><span class="op">()</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// why iterate backwards?</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// https://github.com/benjamin-hodgson/Gutenberg/blob/9ce96d354806ccb7d9c33d89514108045951b3b8/Gutenberg/LayoutEngine.cs#L395-L400</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">for</span> <span class="op">(</span><span class="dt">var</span> i <span class="op">=</span> stack<span class="op">.</span><span class="fu">Count</span> <span class="op">-</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">;</span> i<span class="op">--)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="fu">var</span> <span class="op">(</span>_<span class="op">,</span> item<span class="op">)</span> <span class="op">=</span> stack<span class="op">[</span>i<span class="op">];</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(</span>stack<span class="op">[</span>i<span class="op">]</span> <span class="kw">is</span> ChoicePoint cp<span class="op">)</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="co">// Everything between a ChoicePoint and</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="co">// its continuation has been written to</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            <span class="co">// the renderer.</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">for</span> <span class="op">(</span><span class="dt">var</span> j <span class="op">=</span> cp<span class="op">.</span><span class="fu">Continuation</span> <span class="op">+</span> <span class="dv">1</span><span class="op">;</span> j <span class="op">&lt;=</span> i<span class="op">;</span> j<span class="op">++)</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                stack<span class="op">[</span>j<span class="op">]</span> <span class="op">=</span> <span class="op">(</span><span class="dv">0</span><span class="op">,</span> <span class="kw">new</span> <span class="fu">Empty</span><span class="op">());</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
]]></summary>
</entry>
<entry>
    <title>Incremental T4 Text Templating</title>
    <link href="http://www.benjamin.pizza/posts/2022-11-28-incremental-t4-text-templating.html" />
    <id>http://www.benjamin.pizza/posts/2022-11-28-incremental-t4-text-templating.html</id>
    <published>2022-11-28T00:00:00Z</published>
    <updated>2022-11-28T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>Since starting at Microsoft earlier this year I’ve done a lot of maintenance work on my team’s build system. One of the things I’ve been working on has been <em>incremental building</em>: if you run a build in Visual Studio, and then run another build straight away, it should detect that nothing has changed and skip rebuilding. Incremental building is very important for day-to-day productivity, especially in large codebases, since rebuilding one project usually forces all of its downstream dependents to rebuild too. (The devs in my department typically have around 60 projects loaded into Visual Studio; the whole repo consists of around 1300 projects(!). So as you can imagine a cascading incremental build failure can take quite some time and be a major productivity drag.)</p>
<p>Anyway, here’s one of the incremental build issues I fixed. It’s a bit outside my usual wheelhouse but I wanted to write it down because I couldn’t find anything online when I was first investigating this issue.</p>
<h2 id="debugging-the-up-to-date-check"><a href="#debugging-the-up-to-date-check">Debugging the Up-To-Date Check</a></h2>
<p>I noticed that my team’s project wasn’t building incrementally: whenever I tried to re-run a unit test I had to wait for the whole project to recompile. The first thing to do, when you notice yourself feeling annoyed by recompilation, is to <a href="https://github.com/dotnet/project-system/blob/main/docs/up-to-date-check.md#sdk-style-projects">enable Up-To-Date Check Logging in Visual Studio</a>. (I recommend just leaving the logging on “minimal” mode at all times.) The “Up-To-Date Check” is the component of Visual Studio which is responsible for incremental builds. It works by looking at the timestamps of the project’s input and output files; if all of the output files are newer than all of the input files then the project doesn’t need to be rebuilt.</p>
<p>After turning on the logging and rebuilding, I saw this message in the Output window:</p>
<pre><code>FastUpToDate: Input Compile item 'CodeGen\Templates\AdapterTextTemplate.cs' is newer than earliest output 'bin\net472\ScopeCompiler.dll', not up-to-date.
</code></pre>
<p>That <code>AdapterTextTemplate.cs</code> file is generated using <a href="https://learn.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates">T4 Text Templating</a>. We’d set T4 up to run as part of the build, so we didn’t need to check in the generated files and you didn’t have to manually run T4 before building. We did this by setting <code>TransformOnBuild</code> in the <code>csproj</code> file, and adding a <code>Target</code> to include any newly generated <code>cs</code> files:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">PropertyGroup</span>&gt;</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="co">&lt;!--</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="co">        In MSBuild parlance, a &quot;property&quot; is a scalar (string) value.</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="co">        Anything appearing inside a `PropertyGroup` is a property.</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="co">        The `TransformOnBuild` property tells T4 to run at build time.</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="co">    --&gt;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">TransformOnBuild</span>&gt;true&lt;/<span class="kw">TransformOnBuild</span>&gt;</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">PropertyGroup</span>&gt;</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="co">&lt;!--</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="co">        MSBuild manages lists of &quot;items&quot;; an item roughly corresponds</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="co">        to a file. Inside an `ItemGroup` you can add items to a list</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="co">        using `Include`. So this line of code adds all of the `tt`</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="co">        files in the `CodeGen\Templates` folder to the list of</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="co">        `T4Transform` items.</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="co">    --&gt;</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">T4Transform</span> <span class="ot">Include=</span><span class="st">&quot;CodeGen\Templates\*.tt&quot;</span> /&gt;</span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="co">&lt;!-- Make the .tt files visible in Visual Studio --&gt;</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">None</span> <span class="ot">Include=</span><span class="st">&quot;CodeGen\Templates\*.tt&quot;</span> /&gt;</span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">ItemGroup</span>&gt;</span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!-- This `targets` file contains code to read the `T4Transform` item list and invoke T4. --&gt;</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">Import</span> <span class="ot">Project=</span><span class="st">&quot;$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets&quot;</span> /&gt;</span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!--</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a><span class="co">    A &quot;target&quot; is a coarse-grained unit of work —</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a><span class="co">    a stage in MSBuild&#39;s pluggable pipeline.</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a><span class="co">    This target runs in between the `ExecuteTransformations`</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a><span class="co">    target (from `Microsoft.TextTemplating.targets`) and the</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a><span class="co">    standard `Compile` target. It adds any output files that</span></span>
<span id="34"><a href="#34" aria-hidden="true" tabindex="-1"></a><span class="co">    were generated by T4 (the `GeneratedFiles` item list)</span></span>
<span id="35"><a href="#35" aria-hidden="true" tabindex="-1"></a><span class="co">    to the list of `Compile` items.</span></span>
<span id="36"><a href="#36" aria-hidden="true" tabindex="-1"></a><span class="co">--&gt;</span></span>
<span id="37"><a href="#37" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">Target</span> <span class="ot">Name=</span><span class="st">&quot;IncludeT4GeneratedFiles&quot;</span></span>
<span id="38"><a href="#38" aria-hidden="true" tabindex="-1"></a>        <span class="ot">AfterTargets=</span><span class="st">&quot;ExecuteTransformations&quot;</span></span>
<span id="39"><a href="#39" aria-hidden="true" tabindex="-1"></a>        <span class="ot">BeforeTargets=</span><span class="st">&quot;Compile&quot;</span>&gt;</span>
<span id="40"><a href="#40" aria-hidden="true" tabindex="-1"></a></span>
<span id="41"><a href="#41" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="42"><a href="#42" aria-hidden="true" tabindex="-1"></a>        <span class="co">&lt;!-- Don&#39;t include already included files --&gt;</span></span>
<span id="43"><a href="#43" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">Compile</span> <span class="ot">Include=</span><span class="st">&quot;@(GeneratedFiles)&quot;</span> <span class="ot">Exclude=</span><span class="st">&quot;@(Compile)&quot;</span> /&gt;</span>
<span id="44"><a href="#44" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">ItemGroup</span>&gt;</span>
<span id="45"><a href="#45" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">Target</span>&gt;</span></code></pre></div><p>I realised that the incremental build failure was due to an interaction between build-time text templating and MSBuild’s <a href="https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#default-includes-and-excludes">default includes</a>. The Up-To-Date Check scans the source tree for any <code>cs</code> files; if any of them have changed (or been created) since the last time a build ran, then the project needs rebuilding. Then, during the build (before compilation), T4 runs and generates some <code>cs</code> files; by default these <code>cs</code> files are placed alongside the <code>tt</code> file — ie, in the source tree. The next time you run a build, Visual Studio sees that the generated <code>cs</code> files have been touched, meaning the project needs to be rebuilt, meaning that T4 needs to run, which touches the generated <code>cs</code> files…</p>
<h2 id="the-fix"><a href="#the-fix">The Fix</a></h2>
<p>For the fix I made a few changes:</p>
<ol>
<li>I excluded the generated <code>cs</code> files from the default list of files to track in the Up-To-Date Check.
</li>
<li>Instead, I included them dynamically, after T4 has run. (Visual Studio doesn’t look at dynamically added items when determining whether a project needs rebuilding.)
</li>
<li>I configured MSBuild to run T4 only if the input <code>tt</code> files have changed.
</li>
</ol>
<h3 id="excluding-the-generated-files"><a href="#excluding-the-generated-files">Excluding the Generated Files</a></h3>
<p>One way to do this would be to tell T4 to put the generated files in the <code>obj</code> directory by default:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">&lt;!-- An `ItemDefinitionGroup` contains default metadata definitions for items. --&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">ItemDefinitionGroup</span>&gt;</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">T4Transform</span>&gt;</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">OutputFilePath</span>&gt;$(MSBuildProjectDirectory)$(IntermediateOutputPath)&lt;/<span class="kw">OutputFilePath</span>&gt;</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">T4Transform</span>&gt;</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">T4Preprocess</span>&gt;</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">OutputFilePath</span>&gt;$(MSBuildProjectDirectory)$(IntermediateOutputPath)&lt;/<span class="kw">OutputFilePath</span>&gt;</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">T4Preprocess</span>&gt;</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">ItemDefinitionGroup</span>&gt;</span></code></pre></div><p>(As far as I can tell the <code>OutputFilePath</code> metadata is not documented anywhere; I found it by decompiling the <code>TransformTemplatesBase</code> task in <code>Microsoft.TextTemplating.Build.Tasks.dll</code>.)</p>
<p>This probably would’ve been the cleaner way to do it, as it doesn’t pollute the source tree with generated files, but I didn’t want to break my teammates’ workflow by making it harder to find the generated code. Instead, I simply removed the generated files’ <code>Compile</code> items:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="co">&lt;!-- by convention, an underscore denotes private implementation details --&gt;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">_T4OutputFile</span> <span class="ot">Include=</span><span class="st">&quot;@(T4Preprocess -&gt; &#39;%(RelativeDir)%(Filename).cs&#39;)&quot;</span> /&gt;</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">_T4OutputFile</span> <span class="ot">Include=</span><span class="st">&quot;@(T4Transform -&gt; &#39;%(RelativeDir)%(Filename).cs&#39;)&quot;</span> /&gt;</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">Compile</span> <span class="ot">Remove=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span> /&gt;</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">ItemGroup</span>&gt;</span></code></pre></div><p>T4 can generate any text file, not just <code>cs</code> files, so you’d need to tweak this code if your project happens to have T4 templates which generate other files.</p>
<h3 id="including-the-generated-files-dynamically"><a href="#including-the-generated-files-dynamically">Including the Generated Files Dynamically</a></h3>
<p>Top-level properties and items are evaluated up-front, at the start of a build, but you can also <a href="https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-items?view=vs-2022#create-items-during-execution">manipulate properties and item lists dynamically</a> by nesting them inside a <code>Target</code>. So all I had to do was plug in to the <code>TransformDuringBuild</code> target (implemented in <code>Microsoft.TextTemplating.targets</code>) and include the <code>_T4OutputFile</code>s after they’d been generated — much like the <code>IncludeT4GeneratedFiles</code> target I mentioned earlier.</p>
<p>I could’ve used <code>AfterTargets=&quot;TransformDuringBuild&quot;</code> but instead I decided to <strong>override</strong> the <code>TransformDuringBuild</code> target. (To override a target, you just define a new target with the same name — last one wins. Overriding targets is usually not a good idea, but I had a good reason which will shortly become apparent.) The standard <code>TransformDuringBuild</code> target is defined like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">Target</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Name=</span><span class="st">&quot;TransformDuringBuild&quot;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Condition=</span><span class="st">&quot;&#39;$(TransformOnBuild)&#39; == &#39;true&#39;&quot;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">BeforeTargets=</span><span class="st">&quot;CoreCompile&quot;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="ot">DependsOnTargets=</span><span class="st">&quot;TransformAll&quot;</span>&gt;</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">Target</span>&gt;</span></code></pre></div><p>It’s a no-op target which simply causes another target (<code>TransformAll</code>) to be run when the <code>TransformOnBuild</code> property is set. So, for my override, I pasted that code and added an <code>ItemGroup</code> to the target’s body:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">Target</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Name=</span><span class="st">&quot;TransformDuringBuild&quot;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Condition=</span><span class="st">&quot;&#39;$(TransformOnBuild)&#39; == &#39;true&#39;&quot;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">BeforeTargets=</span><span class="st">&quot;CoreCompile&quot;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="ot">DependsOnTargets=</span><span class="st">&quot;TransformAll&quot;</span>&gt;</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">Compile</span> <span class="ot">Include=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span>&gt;</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            &lt;<span class="kw">AutoGen</span>&gt;True&lt;/<span class="kw">AutoGen</span>&gt;</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            &lt;<span class="kw">DesignTime</span>&gt;True&lt;/<span class="kw">DesignTime</span>&gt;</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        &lt;/<span class="kw">Compile</span>&gt;</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="co">&lt;!--</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="co">            Add `FileWrites` items in order to make the generated</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="co">            files get deleted by Visual Studio&#39;s &quot;clean&quot; operation</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="co">        --&gt;</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">FileWrites</span> <span class="ot">Include=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span> /&gt;</span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">ItemGroup</span>&gt;</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">Target</span>&gt;</span></code></pre></div><h3 id="running-t4-incrementally"><a href="#running-t4-incrementally">Running T4 Incrementally</a></h3>
<p>MSBuild supports incremental building at the target level (so, finer-grained than a whole project). You can tell MSBuild to skip a target if its input files haven’t changed, using the <code>Inputs</code> and <code>Outputs</code> attributes. If all of the files listed in the <code>Outputs</code> are newer than the <code>Inputs</code>, then MSBuild will skip the target to save time. (Any items and properties defined in the target will still be included — it caches them from the last time the target was run.) This is why I decided to override the <code>TransformDuringBuild</code> target above — I wanted to give it <code>Inputs</code> and <code>Outputs</code>.</p>
<p>My final <code>TransformDuringBuild</code> target looked like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">Target</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Name=</span><span class="st">&quot;TransformDuringBuild&quot;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Condition=</span><span class="st">&quot;&#39;$(TransformOnBuild)&#39; == &#39;true&#39;&quot;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">BeforeTargets=</span><span class="st">&quot;CoreCompile&quot;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="ot">DependsOnTargets=</span><span class="st">&quot;TransformAll&quot;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Inputs=</span><span class="st">&quot;@(T4Preprocess);@(T4Transform)&quot;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">Outputs=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span>&gt;</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">Compile</span> <span class="ot">Include=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span>&gt;</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            &lt;<span class="kw">AutoGen</span>&gt;True&lt;/<span class="kw">AutoGen</span>&gt;</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            &lt;<span class="kw">DesignTime</span>&gt;True&lt;/<span class="kw">DesignTime</span>&gt;</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        &lt;/<span class="kw">Compile</span>&gt;</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">FileWrites</span> <span class="ot">Include=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span> /&gt;</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">ItemGroup</span>&gt;</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">Target</span>&gt;</span></code></pre></div><h2 id="the-code"><a href="#the-code">The Code</a></h2>
<p>I put all of this code in a file called <code>TextTemplating.CSharp.targets</code> and imported it into the projects which used T4.</p>
<p>Here is the final file in handy pasteable form:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>&lt;<span class="kw">Project</span>&gt;</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">Import</span> <span class="ot">Project=</span><span class="st">&quot;$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets&quot;</span> /&gt;</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">Service</span> <span class="ot">Include=</span><span class="st">&quot;{508349b6-6b84-4df5-91f0-309beebad82d}&quot;</span> /&gt;</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">AvailableItem</span> <span class="ot">Include=</span><span class="st">&quot;T4Preprocess&quot;</span> /&gt;</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">AvailableItem</span> <span class="ot">Include=</span><span class="st">&quot;T4Transform&quot;</span> /&gt;</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">ItemGroup</span>&gt;</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">_T4OutputFile</span> <span class="ot">Include=</span><span class="st">&quot;@(T4Preprocess -&gt; &#39;%(RelativeDir)%(Filename).cs&#39;)&quot;</span> /&gt;</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">_T4OutputFile</span> <span class="ot">Include=</span><span class="st">&quot;@(T4Transform -&gt; &#39;%(RelativeDir)%(Filename).cs&#39;)&quot;</span> /&gt;</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="co">&lt;!--</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="co">            Don&#39;t include the generated files before they&#39;ve been generated</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="co">            as it causes incremental build failure. Instead, include them after</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="co">            running T4, in the (overridden) TransformDuringBuild target</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="co">        --&gt;</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">Compile</span> <span class="ot">Remove=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span> /&gt;</span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        <span class="co">&lt;!-- make visible in visual studio --&gt;</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">None</span> <span class="ot">Include=</span><span class="st">&quot;@(T4Preprocess);@(T4Transform)&quot;</span> /&gt;</span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">None</span> <span class="ot">Include=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span> /&gt;</span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">ItemGroup</span>&gt;</span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="co">&lt;!-- Override the target from MS.TextTemplating.targets in order to set the Inputs/Outputs --&gt;</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    &lt;<span class="kw">Target</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>        <span class="ot">Name=</span><span class="st">&quot;TransformDuringBuild&quot;</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>        <span class="ot">Condition=</span><span class="st">&quot;&#39;$(TransformOnBuild)&#39; == &#39;true&#39;&quot;</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a>        <span class="ot">BeforeTargets=</span><span class="st">&quot;CoreCompile&quot;</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>        <span class="ot">DependsOnTargets=</span><span class="st">&quot;TransformAll&quot;</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a>        <span class="ot">Inputs=</span><span class="st">&quot;@(T4Preprocess);@(T4Transform)&quot;</span></span>
<span id="34"><a href="#34" aria-hidden="true" tabindex="-1"></a>        <span class="ot">Outputs=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span>&gt;</span>
<span id="35"><a href="#35" aria-hidden="true" tabindex="-1"></a></span>
<span id="36"><a href="#36" aria-hidden="true" tabindex="-1"></a>        &lt;<span class="kw">ItemGroup</span>&gt;</span>
<span id="37"><a href="#37" aria-hidden="true" tabindex="-1"></a>            &lt;<span class="kw">Compile</span> <span class="ot">Include=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span>&gt;</span>
<span id="38"><a href="#38" aria-hidden="true" tabindex="-1"></a>                &lt;<span class="kw">AutoGen</span>&gt;True&lt;/<span class="kw">AutoGen</span>&gt;</span>
<span id="39"><a href="#39" aria-hidden="true" tabindex="-1"></a>                &lt;<span class="kw">DesignTime</span>&gt;True&lt;/<span class="kw">DesignTime</span>&gt;</span>
<span id="40"><a href="#40" aria-hidden="true" tabindex="-1"></a>            &lt;/<span class="kw">Compile</span>&gt;</span>
<span id="41"><a href="#41" aria-hidden="true" tabindex="-1"></a>            &lt;<span class="kw">FileWrites</span> <span class="ot">Include=</span><span class="st">&quot;@(_T4OutputFile)&quot;</span> /&gt;</span>
<span id="42"><a href="#42" aria-hidden="true" tabindex="-1"></a>        &lt;/<span class="kw">ItemGroup</span>&gt;</span>
<span id="43"><a href="#43" aria-hidden="true" tabindex="-1"></a>    &lt;/<span class="kw">Target</span>&gt;</span>
<span id="44"><a href="#44" aria-hidden="true" tabindex="-1"></a></span>
<span id="45"><a href="#45" aria-hidden="true" tabindex="-1"></a>&lt;/<span class="kw">Project</span>&gt;</span></code></pre></div><p>That’s the general recipe when you need to generate something at build time: write a <code>Target</code> with <code>Inputs</code> and <code>Outputs</code>. Put an <code>ItemGroup</code> inside the target to inform the rest of the build pipeline about the newly generated bits.</p>

]]></summary>
</entry>
<entry>
    <title>Parallelising Source Positions</title>
    <link href="http://www.benjamin.pizza/posts/2022-07-16-parallelising-source-positions.html" />
    <id>http://www.benjamin.pizza/posts/2022-07-16-parallelising-source-positions.html</id>
    <published>2022-07-16T00:00:00Z</published>
    <updated>2022-07-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>My parsing library <a href="https://github.com/benjamin-hodgson/Pidgin">Pidgin</a> has some infrastructure to track positions in a textual input file, for the purposes of error reporting. The library’s written in C#, but for today let’s work in Haskell.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SourcePos</span> <span class="ot">=</span> <span class="dt">SourcePos</span> {</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    line ::</span> <span class="dt">Natural</span>,</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    col ::</span> <span class="dt">Natural</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>} <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>)</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="ot">startOfFile ::</span> <span class="dt">SourcePos</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>startOfFile <span class="ot">=</span> <span class="dt">SourcePos</span> <span class="dv">1</span> <span class="dv">1</span></span></code></pre></div><p>The parser keeps track of the current <code>SourcePos</code> by looping over the characters in the input file and calling a method called <code>calculateSourcePos</code>. <code>calculateSourcePos</code>’s job is to update the current <code>SourcePos</code> for a single character.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>newSourcePos <span class="ot">=</span> foldl&#39; calculateSourcePos oldSourcePos inputText</span></code></pre></div><p>You can supply your own <code>calculateSourcePos</code> implementation, but the default one looks roughly like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">calculateSourcePos ::</span> <span class="dt">SourcePos</span> <span class="ot">-&gt;</span> <span class="dt">Char</span> <span class="ot">-&gt;</span> <span class="dt">SourcePos</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>calculateSourcePos sp <span class="ch">&#39;\n&#39;</span> <span class="ot">=</span> <span class="dt">SourcePos</span> {</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    line <span class="ot">=</span> line sp <span class="op">+</span> <span class="dv">1</span>,  <span class="co">-- increment the line count</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    col <span class="ot">=</span> <span class="dv">1</span>  <span class="co">-- and reset the column count</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>calculateSourcePos sp _ <span class="ot">=</span> sp { col <span class="ot">=</span> col sp <span class="op">+</span> <span class="dv">1</span> }</span></code></pre></div><p>When the parser encounters a new line, the column counter is reset back to 1.</p>
<p>The signature of <code>calculateSourcePos</code> poses a performance problem: it takes the previous <code>SourcePos</code> as an argument. Each iteration of the loop depends on the result of the previous iteration. This <em>data dependency</em> means the loop can’t be parallelised — you have to wait for each iteration of the loop to finish before you can start the next one.</p>
<p>This article is about redesigning <code>SourcePos</code> to be more parallelisable.</p>
<h2 id="monoids-are-embarrassingly-parallel"><a href="#monoids-are-embarrassingly-parallel">Monoids are Embarrassingly Parallel</a></h2>
<p><em>Monoid</em> is the high-falutin’ mathsy name for a certain variety of composable objects. Composability is very important in programming, and consequently monoids show up all over the place. There are plenty of introductions to monoids out there (mostly by <a href="https://blog.ploeh.dk/2017/10/06/monoids/">better</a> <a href="https://www.youtube.com/watch?v=-mnA8_DWfik">teachers</a> than me), so I’ll keep it brief.</p>
<p>For an object to be a monoid you need two things:</p>
<ol>
<li>
<p>An operator <code>&lt;&gt;</code> which combines two values of your type into a bigger value.</p>
<ul>
<li>It shouldn’t matter how you nest a sequence of <code>&lt;&gt;</code> operations: <code>(x &lt;&gt; y) &lt;&gt; z == x &lt;&gt; (y &lt;&gt; z)</code>.
</li>
</ul>
</li>
<li>
<p>A <code>mempty</code> value, representing some notion of “zero”.</p>
<ul>
<li>Combining <code>mempty</code> with another value should leave that value unchanged: <code>mempty &lt;&gt; x == x == x &lt;&gt; mempty</code>.
</li>
</ul>
</li>
</ol>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Monoid</span> m <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    mempty ::</span> m</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    (&lt;&gt;) ::</span> m <span class="ot">-&gt;</span> m <span class="ot">-&gt;</span> m</span></code></pre></div><p>The rule about nesting <code>&lt;&gt;</code> is what makes monoids good for parallelism. Suppose you have a big array of monoidal values, and you want to combine them all into a single value using <code>&lt;&gt;</code>. It doesn’t matter what order you perform the additions in, so you can safely divide your array into chunks, sum up each chunk in parallel, and then combine the results. (This is the basic idea behind MapReduce.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="fu">mconcat</span><span class="ot"> ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> <span class="dt">Vector</span> m <span class="ot">-&gt;</span> m</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="fu">mconcat</span> <span class="ot">=</span> Vector.foldr (<span class="op">&lt;&gt;</span>) <span class="fu">mempty</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="co">-- performs the same computation but in parallel</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">pmconcat ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> <span class="dt">Vector</span> m <span class="ot">-&gt;</span> m</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>pmconcat <span class="ot">=</span> List.foldr (<span class="op">&lt;&gt;</span>) <span class="fu">mempty</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span> parMap <span class="fu">mconcat</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span> chunksOf <span class="dv">1024</span></span></code></pre></div><p>To put it another way, monoids don’t suffer from the data dependency which made <code>calculateSourcePos</code> hard to parallelise. The challenge, then, is to come up with a way to make <code>SourcePos</code> into a monoid.</p>
<h2 id="deltas"><a href="#deltas">Deltas</a></h2>
<p>If you go hiking, you might bring with you a list of directions on a piece of paper. Directions are monoidal: if you have directions from your house to the beach, and from the beach to the pub, you can follow those directions sequentially to get from your house to the pub. (I’ll tolerate hiking as long as the destination is a pub.)</p>
<p>Directions are relative, not absolute. The directions on your paper might tell you how to get from your house to the pub, but if you start somewhere other than your house you can still follow the directions — you just have to hope you end up in a different pub.</p>
<p>So by analogy, let’s stop worrying about absolute locations in a source file and instead think about offsets relative to an arbitrary location.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SourcePosDelta</span> <span class="ot">=</span> <span class="dt">SourcePosDelta</span> {</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    lines ::</span> <span class="dt">Natural</span>,</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    cols ::</span> <span class="dt">Natural</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div><p>You can add a relative <code>SourcePosDelta</code> to an absolute <code>SourcePos</code> to get a new absolute <code>SourcePos</code>. This is analogous to setting off on a hike from a given starting location.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> <span class="dt">SourcePos</span> <span class="ot">-&gt;</span> <span class="dt">SourcePosDelta</span> <span class="ot">-&gt;</span> <span class="dt">SourcePos</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>add sp delta <span class="ot">=</span> <span class="dt">SourcePos</span> {</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    line <span class="ot">=</span> line sp <span class="op">+</span> <span class="fu">lines</span> delta,</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    col <span class="ot">=</span> (<span class="kw">if</span> <span class="fu">lines</span> delta <span class="op">==</span> <span class="dv">0</span> <span class="kw">then</span> col sp <span class="kw">else</span> <span class="dv">0</span>) <span class="op">+</span> cols delta</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div><p>When the delta spans multiple lines, we discard <code>col sp</code> and only take <code>cols delta</code>. This reflects the behaviour of <code>computeSourcePos</code>, which resets the column counter when a new line is encountered. The asymmetry is interesting, though; the <code>line</code> calculation depends only on the two <code>lines</code> fields, but the <code>col</code> field has some interference from the <code>lines</code>.</p>
<p>Likewise, you can find the difference between two <code>SourcePos</code>es to get the path that would take you from one to the other:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="fu">subtract</span><span class="ot"> ::</span> <span class="dt">SourcePos</span> <span class="ot">-&gt;</span> <span class="dt">SourcePos</span> <span class="ot">-&gt;</span> <span class="dt">SourcePosDelta</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="fu">subtract</span> start end <span class="ot">=</span> <span class="dt">SourcePosDelta</span> {</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">lines</span> <span class="ot">=</span> line end <span class="op">-</span> line start,</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    cols <span class="ot">=</span> col end <span class="op">-</span> (<span class="kw">if</span> line end <span class="op">==</span> line start <span class="kw">then</span> col start <span class="kw">else</span> <span class="dv">0</span>)</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div><p>From here we can see how to add a pair of <code>SourcePosDelta</code>s (and write the <code>Monoid</code> instance). In fact, the code is more or less identical to <code>add</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> <span class="dt">SourcePosDelta</span> <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">SourcePosDelta</span> <span class="dv">0</span> <span class="dv">0</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    </span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    delta1 <span class="op">&lt;&gt;</span> delta2 <span class="ot">=</span> <span class="dt">SourcePosDelta</span> {</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="fu">lines</span> <span class="ot">=</span> <span class="fu">lines</span> delta1 <span class="op">+</span> <span class="fu">lines</span> delta2,</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        cols <span class="ot">=</span> (<span class="kw">if</span> <span class="fu">lines</span> delta2 <span class="op">==</span> <span class="dv">0</span> <span class="kw">then</span> cols delta1 <span class="kw">else</span> <span class="dv">0</span>) <span class="op">+</span> cols delta2</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div><p>I’ll leave it up to you to convince yourself that this definition satisfies the monoid laws.</p>
<p>Each character in the input file corresponds to a small <code>SourcePosDelta</code>: <code>'\n'</code> corresponds to <code>SourcePosDelta 1 0</code> and each other character corresponds to <code>SourcePosDelta 0 1</code>. The parser can map each character to a <code>SourcePosDelta</code>, add up the monoidal deltas (possibly in parallel), and then add the result to the <code>SourcePos</code> corresponding to the start of the <code>inputText</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>calculateSourcePosDelta inputText <span class="ot">=</span> pmconcat <span class="op">$</span> parMap toDelta inputText</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        toDelta <span class="ch">&#39;\n&#39;</span> <span class="ot">=</span> <span class="dt">SourcePosDelta</span> <span class="dv">1</span> <span class="dv">0</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        toDelta _ <span class="ot">=</span> <span class="dt">SourcePosDelta</span> <span class="dv">0</span> <span class="dv">1</span></span></code></pre></div><h2 id="hardware-parallelism"><a href="#hardware-parallelism">Hardware Parallelism</a></h2>
<p><a href="https://github.com/benjamin-hodgson/Pidgin/blob/sourceposdelta/Pidgin.Bench/SourcePosDeltaBench.cs">I tested some implementations of <code>&lt;&gt;</code> (in C#)</a> which made use of modern CPUs’ support for <em>hardware parallelism</em> (also known as SIMD, for Single Instruction Multiple Data). Recent versions of .NET come bundled with opt-in SIMD support, to be found in <a href="https://docs.microsoft.com/en-us/dotnet/api/system.numerics?view=net-6.0">the <code>System.Numerics</code> namespace</a>.</p>
<p>CPUs with SIMD have extra-wide registers (like, 256 bits) divided into <em>lanes</em>. You can stuff four 64-bit integers (or eight 32-bit ones) into a single register, and the CPU supports special instructions to perform the same operation on each of those four integers at once — so (for example) you can add four sets of two integers with a single instruction. Each SIMD operation is a little bit slower than its corresponding single-target instruction, but since they operate on four times the amount of data you can often get reasonable speedups when you’re processing lots of data.</p>
<p><a href="https://github.com/benjamin-hodgson/Pidgin/blob/539ecf23b8ebf0f601a48ade7576343671ef075c/Pidgin.Bench/SourcePosDeltaBench.cs#L278">My fastest attempt</a> involved packing <code>SourcePosDelta</code>’s two integers into <a href="https://github.com/benjamin-hodgson/Pidgin/blob/539ecf23b8ebf0f601a48ade7576343671ef075c/Pidgin.Bench/SourcePosDeltaBench.cs#L320">a single 64-bit integer</a> and doing some <a href="https://github.com/benjamin-hodgson/Pidgin/blob/539ecf23b8ebf0f601a48ade7576343671ef075c/Pidgin.Bench/SourcePosDeltaBench.cs#L334">bit manipulation</a> to implement <code>&lt;&gt;</code>’s “annihilation” semantics. Then I divided the input array into four chunks — one per lane — and ran the bit manipulation algorithm on each lane. Since it’s best to load contiguous data into a SIMD register’s lanes, I had to <a href="https://github.com/benjamin-hodgson/Pidgin/blob/539ecf23b8ebf0f601a48ade7576343671ef075c/Pidgin.Bench/SourcePosDeltaBench.cs#L51">rearrange the input array</a> to line the chunks up with their SIMD lanes.</p>
<p>I decided against putting the SIMD code into the library, because in practice the number of <code>SourcePosDelta</code>s which need summing is often not very large. In any case, the SIMD code offered comparable performance to a much simpler algorithm: loop backwards until you find the last newline in a chunk of text, then ignore any non-newline characters to the left of it.</p>
<h2 id="spans-and-shifts"><a href="#spans-and-shifts">Spans and Shifts</a></h2>
<p>Here’s another cool thing you can do with <code>SourcePosDelta</code>.</p>
<p>In general, each node in a parse tree corresponds to a certain <em>span</em> of the input document: the section of the input text containing a given syntactic construct.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Span</span> <span class="ot">=</span> <span class="dt">Span</span> {</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    start ::</span> <span class="dt">SourcePos</span>,</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    width ::</span> <span class="dt">SourcePosDelta</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="ot">end ::</span> <span class="dt">Span</span> <span class="ot">-&gt;</span> <span class="dt">SourcePos</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>end <span class="fu">span</span> <span class="ot">=</span> add (start <span class="fu">span</span>) (width <span class="fu">span</span>)</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="ot">containsPos ::</span> <span class="dt">Span</span> <span class="ot">-&gt;</span> <span class="dt">SourcePos</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="fu">span</span> <span class="ot">`containsPos`</span> pos <span class="ot">=</span> pos <span class="op">&gt;=</span> start <span class="fu">span</span> <span class="op">&amp;&amp;</span> pos <span class="op">&lt;=</span> end <span class="fu">span</span></span></code></pre></div><p>It’s common in compilers to keep track of these spans in order to report error messages. For example, you might want to colour a piece of code red in an IDE if it contains an error.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Node</span> <span class="ot">=</span> <span class="dt">Node</span> {</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    span ::</span> <span class="dt">Span</span>,</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    data ::</span> <span class="dt">Expr</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">Lit</span> <span class="dt">Int</span> <span class="op">|</span> <span class="dt">Add</span> <span class="dt">Node</span> <span class="dt">Node</span></span></code></pre></div><p>In an interactive IDE, you have a programmer typing code; the IDE’s parser needs to respond in real time to each keystroke. So, for performance’s sake, you only want to re-parse the fragment of code that the user is currently typing, and reuse the rest of the document’s parse tree from the last time you parsed it.</p>
<p>But when the user types characters into the middle of a document, all of the constructs after it get moved right and down. So you need to <code>shift</code> the parse tree over by the amount that the user typed.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">shift ::</span> <span class="dt">SourcePosDelta</span> <span class="ot">-&gt;</span> <span class="dt">Node</span> <span class="ot">-&gt;</span> <span class="dt">Node</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>shift d (<span class="dt">Node</span> <span class="fu">span</span> <span class="kw">data</span>) <span class="ot">=</span> <span class="dt">Node</span> (shiftSpan d <span class="fu">span</span>) (shiftData <span class="kw">data</span>)</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        shiftData l<span class="op">@</span>(<span class="dt">Lit</span> _) <span class="ot">=</span> l</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        shiftData (<span class="dt">Add</span> l r) <span class="ot">=</span> <span class="dt">Add</span> (shift d l) (shift d r)</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="ot">shiftSpan ::</span> <span class="dt">SourcePosDelta</span> <span class="ot">-&gt;</span> <span class="dt">Span</span> <span class="ot">-&gt;</span> <span class="dt">Span</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>shiftSpan d (<span class="dt">Span</span> start width) <span class="ot">=</span> <span class="dt">Span</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- we need to add `d` on the _left_ of `start`,</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- so we can&#39;t use `add start d`. Instead,</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- round-trip via `SourcePosDelta`.</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    (add startOfFile (d <span class="op">&lt;&gt;</span> <span class="fu">subtract</span> startOfFile start))</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    width</span></code></pre></div><p><code>shift</code> rebuilds the entire tree! That’s asymptotically as bad as re-parsing the entire file — clearly not something we want to do on every keystroke. Instead, let’s annotate the tree with the amount by which it’s been shifted. This lets us shift a whole subtree at once without mutating it.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Node</span> <span class="ot">=</span> <span class="dt">Node</span> {</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    shiftedBy ::</span> <span class="dt">SourcePosDelta</span>,</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    originalSpan ::</span> <span class="dt">Span</span>,</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">    expr ::</span> <span class="dt">Expr</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="fu">span</span><span class="ot"> ::</span> <span class="dt">Node</span> <span class="ot">-&gt;</span> <span class="dt">Span</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="fu">span</span> (<span class="dt">Node</span> shift <span class="fu">span</span> _) <span class="ot">=</span> shiftSpan shift <span class="fu">span</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="ot">shift ::</span> <span class="dt">SourcePosDelta</span> <span class="ot">-&gt;</span> <span class="dt">Node</span> <span class="ot">-&gt;</span> <span class="dt">Node</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>shift delta node <span class="ot">=</span> node { shiftedBy <span class="ot">=</span> delta <span class="op">&lt;&gt;</span> shiftedBy node }</span></code></pre></div><p><code>shift</code> is very fast now; it only rebuilds a single node. When the compiler traverses the parse tree, it simply needs to keep track of the current shift amount and apply that shift to any locations reported in error messages.</p>
<p>For completeness, here is some code to apply an edit to a parse tree. <code>edit</code> searches the parse tree to find the node where the edit occurred, replaces that node, and <code>shifts</code> everything that was textually to the right of that node.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">editSpan ::</span> <span class="dt">Span</span>  <span class="co">-- ^ The location and amount the user typed</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="dt">Span</span>  <span class="co">-- ^ The original span</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Span</span>  <span class="co">-- ^ The span with the edit applied</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>editSpan edit <span class="fu">span</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">not</span> (<span class="fu">span</span> <span class="ot">`containsPos`</span> start edit) <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Just</span> <span class="op">$</span> <span class="dt">Span</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        (start <span class="fu">span</span>)</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="co">-- insert `edit`&#39;s `SourcePosDelta` into `span`&#39;s</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        (<span class="fu">subtract</span> (start <span class="fu">span</span>) (start edit)</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="op">&lt;&gt;</span> width edit</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="op">&lt;&gt;</span> <span class="fu">subtract</span> (end <span class="fu">span</span>) (end edit))</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="ot">edit ::</span> <span class="dt">Span</span>  <span class="co">-- ^ The location and amount the user typed</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">Expr</span>  <span class="co">-- ^ The replacement parse tree</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">Node</span>  <span class="co">-- ^ The original parse tree</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">Node</span>  <span class="co">-- ^ The edited parse tree</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>edit s replacement node <span class="ot">=</span> <span class="dt">Node</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mempty</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- this `fromJust` is ok assuming that the edit was inside `span node`</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    (fromJust <span class="op">$</span> editSpan s (<span class="fu">span</span> node))</span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    (editExpr (expr node))</span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        editExpr (<span class="dt">Lit</span> _) <span class="ot">=</span> replacement</span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>        editExpr (<span class="dt">Add</span> l r)</span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="fu">span</span> l <span class="ot">`containsPos`</span> start s <span class="ot">=</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Add</span> (edit s replacement l) (shift (width s) r)</span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="fu">span</span> r <span class="ot">`containsPos`</span> start s <span class="ot">=</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Add</span> l (edit s replacement r)</span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> replacement</span></code></pre></div><p>This code is linear in the <em>depth</em> of the tree, which is usually shallow (typically dozens of nodes deep, rather than hundreds or thousands). You could do even better asymptotically by storing the parse tree in a <a href="https://en.wikipedia.org/wiki/Zipper_(data_structure)">zipper</a> focused on the node the user is currently editing, and lazily apply shifts as the zipper moves around.</p>
<h2 id="monoid-actions"><a href="#monoid-actions">Monoid Actions</a></h2>
<p>Let’s look a little closer at the formalism underlying <code>SourcePosDelta</code>.</p>
<p>This idea of building up a monoid and then using it to transform some other value is formalised using the notion of <em>actions</em> (also known as <em>modules</em>). A monoidal object is said to be a <em>monoid action</em> on some other object <code>a</code> if it can be used to transform <code>a</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">-- &quot;Action a m&quot; means &quot;m acts on a&quot;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> <span class="dt">Action</span> a m <span class="kw">where</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    act ::</span> m <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span></code></pre></div><p>I always thought <em>action monoid</em> would make a better name for this concept than <em>monoid action</em>. The monoidal value <code>m</code> represents an action to be carried out on some other object <code>a</code>.</p>
<p>To be a well-behaved monoid action, the <code>act</code> method should respect the monoidal nature of the action:</p>
<ol>
<li>
<p><code>mempty</code> should be a no-op action: <code>act mempty == id</code>.</p>
</li>
<li>
<p>Building a monoidal value with <code>&lt;&gt;</code> and then acting with it should be the same as acting with the individual pieces of the monoid: <code>(m &lt;&gt; n) `act` x == m `act` (n `act` x)</code>.</p>
<ul>
<li>
<p>This rule defines a “left” monoid action. It turns out that <code>SourcePosDelta</code> is actually a “right” monoid action, for which this rule is flipped: <code>(m &lt;&gt; n) `act` x == n `act` (m `act` x)</code>.</p>
</li>
<li>
<p>In fact, let’s separate the ideas of “left” and “right” actions. I find that the composition law for right actions makes more sense when the arguments are the other way around.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> <span class="dt">LAction</span> a m <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    lact ::</span> m <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> <span class="dt">RAction</span> a m <span class="kw">where</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">    ract ::</span> a <span class="ot">-&gt;</span> m <span class="ot">-&gt;</span> a</span></code></pre></div><p>So now <code>RAction</code>’s composition law reads <code>x `ract` (m &lt;&gt; n) == (x `ract` m) `ract` n</code>.</p>
</li>
</ul>
</li>
</ol>
<p>Basically, these laws assert that you can build actions with <code>&lt;&gt;</code> and it’ll behave in the way you expect.</p>
<p>Here are a couple of examples to help you think about monoid actions.</p>
<ol>
<li>
<p>Yes, <code>SourcePosDelta</code> is a monoid action on <code>SourcePos</code>. Adding a <code>SourcePosDelta</code> to a <code>SourcePos</code> gives you a new <code>SourcePos</code> representing somewhere later in the file — a <code>SourcePosDelta</code> represents the action of moving to a later location. You can convince yourself that the definition of <code>ract</code> does indeed satisfy the laws I outlined above:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">RAction</span> <span class="dt">SourcePos</span> <span class="dt">SourcePosDelta</span> <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    ract sp delta <span class="ot">=</span> <span class="dt">SourcePos</span> {</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        line <span class="ot">=</span> line sp <span class="op">+</span> <span class="fu">lines</span> delta,</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        col <span class="ot">=</span> (<span class="kw">if</span> <span class="fu">lines</span> delta <span class="op">==</span> <span class="dv">0</span> <span class="kw">then</span> col sp <span class="kw">else</span> <span class="dv">0</span>) <span class="op">+</span> cols delta</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div></li>
<li>
<p>I first learned about monoid actions (well, group actions) during a crystallography course at university. Crystallographers are very concerned with symmetry, because crystals are repeating structures which look the same in every direction. Crystals can be categorised by the collection of rotations, reflections and translations (the <em>space group</em>) under which the crystal looks the same. You monoidally build up a sequence of spatial transformations, and then use those transformations to act on a crystal.</p>
<p>A more familiar way of phrasing the same example: When you go hiking with written directions, you can think of the directions as acting on your current location. When you follow a direction such as “walk 200 metres”, you update your location accordingly.</p>
</li>
<li>
<p>Any monoid can always be thought of as acting upon itself, simply by defining <code>act = (&lt;&gt;)</code>.</p>
</li>
</ol>
<h2 id="actions-all-the-way-down"><a href="#actions-all-the-way-down">Actions All the Way Down</a></h2>
<p>It turns out monoid actions can also explain the strange asymmetry in <code>SourcePosDelta</code>’s <code>(&lt;&gt;)</code> method. When computing <code>delta1 &lt;&gt; delta2</code>, we can think of <code>delta2</code>’s <code>lines</code> as acting on <code>delta1</code>’s <code>cols</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Lines</span> <span class="ot">=</span> <span class="dt">Lines</span> <span class="dt">Natural</span> <span class="kw">deriving</span> <span class="dt">Monoid</span> via (<span class="dt">Sum</span> <span class="dt">Natural</span>)</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Cols</span> <span class="ot">=</span> <span class="dt">Cols</span> <span class="dt">Natural</span> <span class="kw">deriving</span> <span class="dt">Monoid</span> via (<span class="dt">Sum</span> <span class="dt">Natural</span>)</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">RAction</span> <span class="dt">Cols</span> <span class="dt">Lines</span> <span class="kw">where</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    ract c (<span class="dt">Lines</span> <span class="dv">0</span>) <span class="ot">=</span> c</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    ract _ _ <span class="ot">=</span> <span class="dt">Cols</span> <span class="dv">0</span></span></code></pre></div><p><code>Lines</code>’s action on <code>Cols</code> is to erase the <code>Cols</code> altogether when the number of <code>Lines</code> is not zero. It’s a weirdly degenerate monoid action, but it’s an action nonetheless. (It seems like <code>Lines</code> basically represents an <a href="https://en.wikipedia.org/wiki/Annihilator_(ring_theory)">annihilator</a> for <code>Cols</code>.)</p>
<p>With <code>Lines</code>’s action on <code>Cols</code> in hand, <code>SourcePosDelta</code>’s <code>Monoid</code> instance can be explained as an instance of a (right) <em>semi-direct product</em>. A semi-direct product is like a regular product type <code>(a, b)</code>, except its <code>Monoid</code> instance allows for one of the fields to interfere with the other by acting on it:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">RSemiDirect</span> a b <span class="ot">=</span> <span class="dt">RSD</span> a b</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Monoid</span> a, <span class="dt">Monoid</span> b, <span class="dt">RAction</span> a b) <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">RSemiDirect</span> a b) <span class="kw">where</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">RSD</span> <span class="fu">mempty</span> <span class="fu">mempty</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">RSD</span> x1 y1) <span class="op">&lt;&gt;</span> (<span class="dt">RSD</span> x2 y2) <span class="ot">=</span> <span class="dt">RSD</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        (ract x1 y2 <span class="op">&lt;&gt;</span> x2)</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        (y1 <span class="op">&lt;&gt;</span> y2)</span></code></pre></div><p><code>RSemiDirect a b</code> is a monoid when <code>b</code>’s action on <code>a</code> respects <code>a</code>’s monoidal structure:</p>
<ol>
<li>
<p>Acting on an empty monoid produces another empty monoid: <code>ract mempty x == mempty</code>.</p>
</li>
<li>
<p><code>b</code>’s monoidal structure distributes over <code>a</code>’s: <code>ract (x &lt;&gt; y) z == ract x z &lt;&gt; ract y z</code>.</p>
</li>
</ol>
<p>I won’t prove it here, but these do hold for <code>Lines</code>’s action on <code>Cols</code>. So we have a clean explanation for <code>SourcePosDelta</code>’s asymmetric monoidal structure in terms of the semi-direct product:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">SourcePosDelta</span> <span class="ot">=</span> <span class="dt">RSemiDirect</span> <span class="dt">Cols</span> <span class="dt">Lines</span></span></code></pre></div><p>I first read about semi-direct products a few years ago in <a href="http://ozark.hendrix.edu/~yorgey/pub/twisted.pdf">the “twisted functors” paper</a>. They use semi-direct products to manage pointer arithmetic while writing to buffers — monoidally building up an offset and using it to act on a base pointer. They also give a couple of other examples.</p>

]]></summary>
</entry>
<entry>
    <title>Some Notes on Variables and Binding</title>
    <link href="http://www.benjamin.pizza/posts/2021-05-18-some-notes-on-variables-and-binding.html" />
    <id>http://www.benjamin.pizza/posts/2021-05-18-some-notes-on-variables-and-binding.html</id>
    <published>2021-05-18T00:00:00Z</published>
    <updated>2021-05-18T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>I’ve been thinking a bit about how to build a library of tools to handle variables, capture-avoiding substitution, etc, on top of <a href="https://github.com/benjamin-hodgson/Sawmill">Sawmill</a>. Pretty much every compiler needs to deal with variables, and they’re notoriously tricky to handle correctly.</p>
<p>I’m a way off having a final design, but I thought I’d publish my unfinished notes, hastily written in an afternoon. You’ll see a few Thinking Emojis throughout this article, indicating things I haven’t figured out yet. Please do get in touch if any of this gives you ideas.</p>
<h2 id="a-quick-look-at-some-prior-art"><a href="#a-quick-look-at-some-prior-art">A quick look at some prior art</a></h2>
<p><a href="https://hackage.haskell.org/package/unbound"><strong><code>unbound</code></strong></a>/<a href="https://hackage.haskell.org/package/unbound-generics"><strong><code>unbound-generics</code></strong></a></p>
<ul>
<li><code>Name</code> is an abstract data type with fixed representation.
<ul>
<li><code>Bound</code> is a depth and an index. Requires patterns to have a canonical ordering, and bind each name only once
</li>
<li><code>Bound</code> discards the original name, but library API expects patterns to contain <code>Name</code>s
</li>
</ul>
</li>
<li>Statically encoded patterns with built in type combinators.
<ul>
<li>I like:
<ul>
<li>Statically declare structure of binders
</li>
<li>Embed your own datatypes as required by language syntax — method header can be <code>[(Name, Type)]</code>
</li>
</ul>
</li>
<li>I don’t like:
<ul>
<li>Generics magic to find/traverse patterns
</li>
<li>Type constructor soup, eg <code>| LetRec (Bind (Rec [(Name, Embed Expr)]) Expr)</code>. Would be even noisier in C#.
</li>
</ul>
</li>
</ul>
</li>
<li>Quite closely integrated with generics libs
<ul>
<li>Most users will be using <code>RepLib</code>/<code>GHC.Generics</code>
</li>
<li>Lib uses <code>RepLib</code>/<code>GHC.Generics</code> internally to traverse patterns
</li>
</ul>
</li>
</ul>
<p><a href="https://www.schoolofhaskell.com/user/edwardk/bound"><strong><code>bound</code></strong></a></p>
<ul>
<li>Choose your own name (<code>data Expr a = Var a | ...</code>).
</li>
<li>Choose your own pattern/index.
<ul>
<li>Library explicitly doesn’t manage patterns or names. It just does substitution using your monad. <code>Scope</code> doesn’t contain a “pattern” object.
</li>
<li>Me gusta
</li>
</ul>
</li>
<li>Nested datatype manages de Bruijn depth statically.
<ul>
<li>Nested datatype is quite awkward in practice — doesn’t play nicely with mutual recursion or Plated.
</li>
<li>Clever trick in <code>Scope</code> to speed up shifting at cost of canonicity. Prob a bit of a gimmick unless you’re dealing with huge trees — but also, not super costly complexity-wise.
</li>
</ul>
</li>
<li>Works really nicely with standard classes: <code>Foldable</code>/<code>Traversable</code> to look at FVs, <code>Functor</code> for renaming, <code>Monad</code> for substitution. <code>Eq1</code> for alpha equivalence, etc. Very pleasing.
<ul>
<li>OTOH, <a href="https://stackoverflow.com/questions/39057576/mutually-recursive-syntaxes-with-bound">doesn’t work with a non-monadic AST</a>.
</li>
</ul>
</li>
<li>Overall, probably not such a good fit for C# since we don’t have HKTs, <code>Monad</code> etc. Not very library-able.
</li>
</ul>
<p><a href="https://github.com/brendanzab/moniker"><strong><code>moniker</code></strong></a></p>
<ul>
<li>More or less a port of <code>unbound</code>.
</li>
<li>Choose your own name (<code>Free&lt;N&gt;</code>/<code>Bound&lt;N&gt;</code>; <code>trait BoundTerm&lt;N&gt;</code>).
</li>
<li>Library defines a couple of traits (<code>BoundTerm</code>/<code>BoundPattern</code>) to locate variables, do substitution, etc. <code>unbound</code> uses generics for this.
</li>
<li>Traverse your own terms, but <code>derive</code> magic assists with implementing the library’s traits.
</li>
</ul>
<h2 id="representing-names"><a href="#representing-names">Representing Names</a></h2>
<p>I definitely want to use de Bruijn indexes (managed by the library) for bound variables.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">readonly</span> <span class="kw">struct</span> Bound</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> Depth <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span>  <span class="co">// how many binding sites up should I look?</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> Index <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span>  <span class="co">// where inside the binding site should I look?</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>For now, I’m not storing names in <code>Bound</code>. If you want to know the original name, go and find it in the pattern. Use of <code>int</code> for <code>Index</code> requires patterns to have a canonical ordering (and bind each variable only once).</p>
<p>Free variables: need an easy way to freshen them.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">readonly</span> <span class="kw">struct</span> Free</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> OriginalName <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> Freshness <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Now just union them to represent names.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">readonly</span> <span class="kw">struct</span> Name</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Bound Bound <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Free Free <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="fu">Name</span><span class="op">(</span>Bound bound<span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        Bound <span class="op">=</span> bound<span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        Free <span class="op">=</span> <span class="kw">default</span><span class="op">;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="fu">Name</span><span class="op">(</span>Free free<span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        Bound <span class="op">=</span> <span class="kw">default</span><span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        Free <span class="op">=</span> free<span class="op">;</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">bool</span> IsBound <span class="op">=&gt;</span> free<span class="op">.</span><span class="fu">OriginalName</span> <span class="op">==</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">bool</span> IsFree <span class="op">=&gt;</span> free<span class="op">.</span><span class="fu">OriginalName</span> <span class="op">!=</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>How much of this should be public? Should these be structs or classes? (<code>Name</code> is like 4 words.) 🤔</p>
<h2 id="representing-scopes"><a href="#representing-scopes">Representing Scopes</a></h2>
<p>I definitely want an explicit type to represent a scope. I personally think <code>BindingSite</code> is a slightly better name, although perhaps that should be reserved for names inside patterns? 🤔</p>
<p>The idea is to treat <code>BindingSite</code> as an abstract data type. To create a <code>BindingSite</code> (such as when parsing a lambda expression), you call <code>Binder.Bind(variables, body)</code>. The binder traverses the <code>body</code> AST, looking for variables which are bound by the lambda and converting them to <code>Bound</code> de Bruijn indexes. Likewise, when you need to go inside a <code>BindingSite</code>, you have to explicitly unbind it.</p>
<p>Don’t want to discard the original names, of course.</p>
<p><strong>Idea 1</strong>: Store the original name with the <code>Bound</code> variable (just as an annotation, ignore in alpha-equivalence etc).</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">readonly</span> <span class="kw">struct</span> Bound</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> Depth <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> Index <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Free OriginalName <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Potential consistency issues — different mentions of the same variable could end up with different tags.</p>
<p><strong>Idea 2</strong>: Store a flat list of original names in the <code>BindingSite</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">readonly</span> <span class="kw">struct</span> BindingSite<span class="op">&lt;</span>T<span class="op">&gt;</span>  <span class="co">// aka Scope (bound/moniker) or Bind (unbound)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// How much of this should be public? 🤔</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableArray<span class="op">&lt;</span>Name<span class="op">&gt;</span> OriginalNames <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Body <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>It feels kinda ugly. Also potential consistency issues — if your binding sites have more syntactic structure than that (patterns, type signatures, etc), you’re gonna end up duplicating information. Also, it doesn’t seem like this would easily support recursive patterns such as letrec or Agda’s dot notation.</p>
<p><strong>Idea 3</strong>: Store the actual pattern in the <code>BindingSite</code>. This is more in line with how <code>unbound</code>/<code>moniker</code> do it.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">readonly</span> <span class="kw">struct</span> BindingSite<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Pattern Pattern <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Body <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> Pattern <span class="op">{}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Variable <span class="op">:</span> Pattern  <span class="co">// Do I need to support &quot;anonymous&quot; variables? 🤔</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Name Name <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Embed<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> Pattern</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Embedded <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Telescope <span class="op">:</span> Pattern  <span class="co">// known as Rebind in other libs</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> BindingSite<span class="op">&lt;</span>Pattern<span class="op">&gt;</span> BindingSite <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Rec <span class="op">:</span> Pattern</span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="co">// technically this is a binding site too. 🤔</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Pattern Body <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Some things about this work really well. We can make <code>Pattern</code> extensible by having it implement <code>IRewritable</code> abstractly. I define a few base patterns which my library recognises, and you can add your own. To (eg) find the variables in a pattern I just need to be able to traverse your custom pattern types with <code>GetChildren</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> Pattern <span class="op">:</span> IRewritable<span class="op">&lt;</span>Pattern<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> IEnumerable<span class="op">&lt;</span>Free<span class="op">&gt;</span> <span class="fu">GetNames</span><span class="op">()</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">this</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">SelfAndDescendants</span><span class="op">()</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">OfType</span><span class="op">&lt;</span>Variable<span class="op">&gt;()</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>            <span class="co">// names which aren&#39;t free in a pattern are recursive</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="co">// references to other names bound in this pattern</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Where</span><span class="op">(</span>v <span class="op">=&gt;</span> v<span class="op">.</span><span class="fu">Name</span><span class="op">.</span><span class="fu">IsFree</span><span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>x <span class="op">=&gt;</span> x<span class="op">.</span><span class="fu">Name</span><span class="op">.</span><span class="fu">Free</span><span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Ways this doesn’t scale:</p>
<ul>
<li>If your language has multiple types of patterns (eg, type variables and value variables) you can’t statically distinguish them.
</li>
<li>The structure of the pattern lives only at runtime — it all gets stuffed into a <code>Pattern</code>-typed variable. You can’t <em>statically</em> encode the syntactic structure of the binding site (at which point it’s not a whole lot better than Idea 2).
</li>
<li>“Rewrite all the embedded terms” is an ad-hoc affair. Long-standing shortcoming of <code>IRewritable</code>, for which I haven’t come up with a satisfactorily simple solution.
</li>
</ul>
<p>What should be the advice for implementing <code>IRewritable</code> on objects containing a binding site? Should you traverse to the body? (Problematic because de Bruijn indexes from different scopes are not comparable.) Are you meant to unbind the body? That would mean you can’t use <code>IRewritable</code> as is, because <code>IRewritable</code> doesn’t have a parameter for a source of fresh names. Perhaps we should be using <code>IRewriter</code> and not <code>IRewritable</code>, although that’s a messier API. 🤔</p>
<blockquote>
<p>This ☝🏻 is a pressing concern because <code>Telescope</code> features a <code>BindingSite</code>!</p>
</blockquote>
<p><strong>Idea 3.1</strong>: Statically type the <code>Pattern</code> using generics.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">readonly</span> <span class="kw">struct</span> BindingSite<span class="op">&lt;</span>TPattern<span class="op">,</span> T<span class="op">&gt;</span> where TPattern <span class="op">:</span> Pattern</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> TPattern Pattern <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Body <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Telescope<span class="op">&lt;</span>L<span class="op">,</span> R<span class="op">&gt;</span> <span class="op">:</span> Pattern</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    where L <span class="op">:</span> Pattern</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    where R <span class="op">:</span> Pattern</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// open question on how to treat BindingSite with IRewritable</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> BindingSite<span class="op">&lt;</span>L<span class="op">,</span> R<span class="op">&gt;</span> BindingSite <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Rec<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> Pattern</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> Pattern</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Body <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Some things about this work really well too, as evidenced by its use in <code>unbound</code>/<code>moniker</code>. I find the “type soup” usability issue a bit concerning, but more pressingly it doesn’t play nicely with <code>IRewritable</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Telescope<span class="op">&lt;</span>L<span class="op">,</span> R<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">()</span> <span class="op">=&gt;</span> <span class="dv">2</span><span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>Span<span class="op">&lt;</span>Pattern<span class="op">&gt;</span> children<span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="co">// debatably we should only be descending to the Pattern,</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="co">// because the Body is in a different scope</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        children<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">=</span> BindingSite<span class="op">.</span><span class="fu">Pattern</span><span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        children<span class="op">[</span><span class="dv">1</span><span class="op">]</span> <span class="op">=</span> BindingSite<span class="op">.</span><span class="fu">Body</span><span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Pattern <span class="fu">SetChildren</span><span class="op">(</span>ReadOnlySpan<span class="op">&lt;</span>Pattern<span class="op">&gt;</span> children<span class="op">)</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> Telescope<span class="op">&lt;</span>L<span class="op">,</span> R<span class="op">&gt;((</span>L<span class="op">)</span>children<span class="op">[</span><span class="dv">0</span><span class="op">],</span> <span class="op">(</span>R<span class="op">)</span>children<span class="op">[</span><span class="dv">1</span><span class="op">]);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="co">//                      ^ damn!</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>That unsafe cast really is unsafe, because a <code>Rewrite</code> operation is liable to change the type of the pattern. Maybe patterns should be read-only? Do I need to split the read/write parts of <code>IRewritable</code>? 🤔</p>
<p><strong>Idea 4</strong>: A reflection-based API, perhaps with attributes? Seems like it definitely has legs, but I find reflection-based APIs distasteful — they’re hard to reason about and hard to program with. (It’s much easier to manipulate values than code.) I’d prefer to come up with a <em>model</em>, which you can manipulate directly, and then layer a reflection API on top.</p>
<h2 id="asts-with-binding-structure"><a href="#asts-with-binding-structure">ASTs with Binding Structure</a></h2>
<p>This part is fairly worked out I think. I’m assuming that your syntax tree has a case for variables, containing a <code>Name</code> (and no children) and a case for binding sites, containing a <code>BindingSite</code> (and no children). So all we need to add to <code>IRewritable</code> is a way to identify those nodes:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IBindable<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span> where T <span class="op">:</span> IBindable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">bool</span> <span class="fu">TryGetName</span><span class="op">(</span><span class="kw">out</span> Name name<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">SetName</span><span class="op">(</span>Name newName<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">bool</span> <span class="fu">TryGetBindingSite</span><span class="op">(</span><span class="kw">out</span> BindingSite<span class="op">&lt;</span>T<span class="op">&gt;</span> bindingSite<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">SetBindingSite</span><span class="op">(</span>BindingSite<span class="op">&lt;</span>T<span class="op">&gt;</span> newBindingSite<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Not so different than <a href="/posts/2019-12-15-generic-unification-with-sawmill.html"><code>IUnifiable</code></a>.</p>
<h2 id="freshening"><a href="#freshening">Freshening</a></h2>
<p>When you go under a binder you (usually) want to replace the de Bruijn indexes in there with named variables. Those variables need to be <em>fresh</em>, that is, they need to not clash with (or <em>capture</em>) any other variables in scope. As a UX concern, you probably want the fresh name to be somewhat similar to the name the programmer typed.</p>
<p>So we have <code>IFreshener</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IFreshener</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Free <span class="fu">Freshen</span><span class="op">(</span>Free name<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>And a straightforward implementation with a global counter.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Freshener <span class="op">:</span> IFreshener</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> _counter <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Free <span class="fu">Freshen</span><span class="op">(</span>Free name<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        _counter<span class="op">++;</span>  <span class="co">// Interlocked.Increment if you need thread safety</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">new</span> <span class="fu">Free</span><span class="op">(</span>name<span class="op">.</span><span class="fu">OriginalName</span><span class="op">,</span> _counter<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>As an optimisation (and as a UX improvement), you can avoid freshening variables if you’re sure they don’t clash with any other names which are in scope. That means keeping track of the set of names we want to avoid:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IFreshener</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Free <span class="fu">Freshen</span><span class="op">(</span>Free name<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">EnterScope</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>Free<span class="op">&gt;</span> names<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">ExitScope</span><span class="op">();</span>  <span class="co">// free up the names from the last EnterScope call</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Freshener <span class="op">:</span> IFreshener</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Free <span class="fu">Freshen</span><span class="op">(</span>Free name<span class="op">)</span> <span class="op">{</span> <span class="co">/* ... */</span> <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">EnterScope</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>Free<span class="op">&gt;</span> names<span class="op">)</span> <span class="op">{}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">ExitScope</span><span class="op">()</span> <span class="op">{}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> LocalFreshener <span class="op">:</span> IFreshener</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// use a better data structure in practice, obv</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> Stack<span class="op">&lt;</span>IEnumerable<span class="op">&lt;</span>Free<span class="op">&gt;&gt;</span> _names <span class="op">=</span> <span class="kw">new</span><span class="op">();</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Free <span class="fu">Freshen</span><span class="op">(</span>Free name<span class="op">)</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="kw">while</span> <span class="op">(</span>_names<span class="op">.</span><span class="fu">Any</span><span class="op">(</span>ns <span class="op">=&gt;</span> ns<span class="op">.</span><span class="fu">Contains</span><span class="op">(</span>name<span class="op">)))</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            name <span class="op">=</span> name<span class="op">.</span><span class="fu">IncrementFreshness</span><span class="op">();</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> name<span class="op">;</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">EnterScope</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>Free<span class="op">&gt;</span> names<span class="op">)</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>        _names<span class="op">.</span><span class="fu">Push</span><span class="op">(</span>names<span class="op">);</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">ExitScope</span><span class="op">()</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a>        _names<span class="op">.</span><span class="fu">Pop</span><span class="op">();</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="traversing-the-tree"><a href="#traversing-the-tree">Traversing the tree</a></h2>
<p>OK, finally we have everything we need to bind and unbind variables in ASTs. Let’s suppose we went with <strong>Idea 2</strong> from above — just storing a flat list of names at the binding site.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">class</span> Binder</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> BindingSite<span class="op">&lt;</span>T<span class="op">&gt;</span> Bind<span class="op">&lt;</span>T<span class="op">&gt;(</span>ImmutableArray<span class="op">&lt;</span>Free<span class="op">&gt;</span> variables<span class="op">,</span> T body<span class="op">)</span> where T <span class="op">:</span> IBindable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> variablesLookup <span class="op">=</span> variables</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Select</span><span class="op">((</span>x<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">new</span> KeyValuePair<span class="op">&lt;</span>Free<span class="op">,</span> <span class="dt">int</span><span class="op">&gt;(</span>x<span class="op">,</span> i<span class="op">))</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">ToImmutableDictionary</span><span class="op">();</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> level <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        T <span class="fu">Go</span><span class="op">(</span>T x<span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> <span class="op">(</span>x<span class="op">.</span><span class="fu">TryGetName</span><span class="op">(</span><span class="kw">out</span> <span class="dt">var</span> name<span class="op">))</span>  <span class="co">// x is a variable</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                <span class="kw">if</span> <span class="op">(</span>name<span class="op">.</span><span class="fu">IsFree</span> <span class="op">&amp;&amp;</span> variablesLookup<span class="op">.</span><span class="fu">TryGetValue</span><span class="op">(</span>name<span class="op">.</span><span class="fu">Free</span><span class="op">,</span> <span class="kw">out</span> <span class="dt">var</span> ix<span class="op">))</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                <span class="op">{</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> x<span class="op">.</span><span class="fu">SetName</span><span class="op">(</span><span class="kw">new</span> <span class="fu">Name</span><span class="op">(</span><span class="kw">new</span> <span class="fu">Bound</span><span class="op">(</span>level<span class="op">,</span> ix<span class="op">)));</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> x<span class="op">;</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span> <span class="kw">if</span> <span class="op">(</span>x<span class="op">.</span><span class="fu">TryGetBindingSite</span><span class="op">(</span><span class="kw">out</span> <span class="dt">var</span> bs<span class="op">))</span>  <span class="co">// x is a binding site</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>                level<span class="op">++;</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>                <span class="dt">var</span> newBody <span class="op">=</span> <span class="fu">Go</span><span class="op">(</span>bs<span class="op">.</span><span class="fu">Body</span><span class="op">);</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>                level<span class="op">--;</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> x<span class="op">.</span><span class="fu">SetBindingSite</span><span class="op">(</span>bs<span class="op">.</span><span class="fu">WithBody</span><span class="op">(</span>newBody<span class="op">));</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> x<span class="op">.</span><span class="fu">RewriteChildren</span><span class="op">(</span>Go<span class="op">);</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">new</span> BindingSite<span class="op">&lt;</span>T<span class="op">&gt;(</span>variables<span class="op">,</span> <span class="fu">Go</span><span class="op">(</span>body<span class="op">));</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="34"><a href="#34" aria-hidden="true" tabindex="-1"></a></span>
<span id="35"><a href="#35" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> <span class="op">(</span>ImmutableArray<span class="op">&lt;</span>Free<span class="op">&gt;,</span> T<span class="op">)</span> Unbind<span class="op">&lt;</span>T<span class="op">&gt;(</span>BindingSite<span class="op">&lt;</span>T<span class="op">&gt;</span> bindingSite<span class="op">,</span> IFreshener freshener<span class="op">)</span> where T <span class="op">:</span> IBindable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="36"><a href="#36" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="37"><a href="#37" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> variables <span class="op">=</span> bindingSite</span>
<span id="38"><a href="#38" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Variables</span></span>
<span id="39"><a href="#39" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>freshener<span class="op">.</span><span class="fu">Freshen</span><span class="op">)</span></span>
<span id="40"><a href="#40" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">ToImmutableArray</span><span class="op">();</span></span>
<span id="41"><a href="#41" aria-hidden="true" tabindex="-1"></a></span>
<span id="42"><a href="#42" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> level <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="43"><a href="#43" aria-hidden="true" tabindex="-1"></a>        T <span class="fu">Go</span><span class="op">(</span>T x<span class="op">)</span></span>
<span id="44"><a href="#44" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="45"><a href="#45" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> <span class="op">(</span>x<span class="op">.</span><span class="fu">TryGetName</span><span class="op">(</span><span class="kw">out</span> <span class="dt">var</span> name<span class="op">))</span></span>
<span id="46"><a href="#46" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="47"><a href="#47" aria-hidden="true" tabindex="-1"></a>                <span class="kw">if</span> <span class="op">(</span>name<span class="op">.</span><span class="fu">IsBound</span> <span class="op">&amp;&amp;</span> name<span class="op">.</span><span class="fu">Bound</span><span class="op">.</span><span class="fu">Level</span> <span class="op">==</span> level<span class="op">)</span></span>
<span id="48"><a href="#48" aria-hidden="true" tabindex="-1"></a>                <span class="op">{</span></span>
<span id="49"><a href="#49" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> x<span class="op">.</span><span class="fu">SetName</span><span class="op">(</span><span class="kw">new</span> <span class="fu">Name</span><span class="op">(</span>variables<span class="op">[</span>name<span class="op">.</span><span class="fu">Bound</span><span class="op">.</span><span class="fu">Index</span><span class="op">]));</span></span>
<span id="50"><a href="#50" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="51"><a href="#51" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> x<span class="op">;</span></span>
<span id="52"><a href="#52" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="53"><a href="#53" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span> <span class="kw">if</span> <span class="op">(</span>x<span class="op">.</span><span class="fu">TryGetBindingSite</span><span class="op">(</span><span class="kw">out</span> <span class="dt">var</span> bs<span class="op">))</span></span>
<span id="54"><a href="#54" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="55"><a href="#55" aria-hidden="true" tabindex="-1"></a>                level<span class="op">++;</span></span>
<span id="56"><a href="#56" aria-hidden="true" tabindex="-1"></a>                <span class="dt">var</span> newBody <span class="op">=</span> <span class="fu">Go</span><span class="op">(</span>bs<span class="op">.</span><span class="fu">Body</span><span class="op">);</span></span>
<span id="57"><a href="#57" aria-hidden="true" tabindex="-1"></a>                level<span class="op">--;</span></span>
<span id="58"><a href="#58" aria-hidden="true" tabindex="-1"></a>                <span class="kw">if</span> <span class="op">(!</span><span class="fu">ReferenceEquals</span><span class="op">(</span>bs<span class="op">.</span><span class="fu">Body</span><span class="op">,</span> newBody<span class="op">))</span></span>
<span id="59"><a href="#59" aria-hidden="true" tabindex="-1"></a>                <span class="op">{</span></span>
<span id="60"><a href="#60" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> x<span class="op">.</span><span class="fu">SetBindingSite</span><span class="op">(</span>bs<span class="op">.</span><span class="fu">WithBody</span><span class="op">(</span>newBody<span class="op">));</span></span>
<span id="61"><a href="#61" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="62"><a href="#62" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> x<span class="op">;</span></span>
<span id="63"><a href="#63" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="64"><a href="#64" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span></span>
<span id="65"><a href="#65" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="66"><a href="#66" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> x<span class="op">.</span><span class="fu">RewriteChildren</span><span class="op">(</span>Go<span class="op">);</span></span>
<span id="67"><a href="#67" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="68"><a href="#68" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="69"><a href="#69" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="op">(</span>variables<span class="op">,</span> <span class="fu">Go</span><span class="op">(</span>bindingSite<span class="op">.</span><span class="fu">Body</span><span class="op">));</span></span>
<span id="70"><a href="#70" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="71"><a href="#71" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>You can develop versions of <code>Rewrite</code>, <code>SelfAndDescendants</code>, and so on, which appropriately <code>Bind</code> and <code>Unbind</code> variables inside the tree.</p>
<p>There are a couple of design issues regarding the performance of <code>Bind</code>/<code>Unbind</code>. Each call traverses and rewrites the whole tree and potentially chews through a bunch of fresh names, so if you bind and unbind a lot then you’re gonna have performance problems.</p>
<p>There might be room for improvement here — off the top of my head, you could rewrite everything up to the next binding site and just store a “substitution to be applied” there. You can defer applying the changes until you’re asked to open that binding site. I suspect that’d give you asymptotic speedups (quadratic -&gt; linear?) for certain algorithms which do lots of renaming.</p>
<p>Also, some tree operations don’t require you to <code>Unbind</code> and re-<code>Bind</code> every single binding site. If you’re doing some sort of operation where you’re not generating new names or binding sites, or moving nodes across binding sites, you can just leave <code>Bound</code> variables where they are. That’s an argument for making (eg) <code>bindingSite.Body</code> public, and going under it in <code>GetChildren</code>/<code>SetChildren</code>. Although in practice that’s the sort of thing which is hard to get right and can cause subtle (or not-so-subtle) bugs in your language implementation.</p>

]]></summary>
</entry>
<entry>
    <title>Building Prolog's Rules Engine</title>
    <link href="http://www.benjamin.pizza/posts/2019-12-22-building-prologs-rules-engine.html" />
    <id>http://www.benjamin.pizza/posts/2019-12-22-building-prologs-rules-engine.html</id>
    <published>2019-12-22T00:00:00Z</published>
    <updated>2019-12-22T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>This is part of a series of posts about implementing a miniature Prolog interpreter in C#.</p>
<nav>
    <ol>
        <li><a href="/posts/2019-12-01-write-you-a-prolog.html">Introduction &amp; Syntax</a></li>
        <li><a href="/posts/2019-12-08-parsing-prolog-with-pidgin.html">Parsing</a></li>
        <li><a href="/posts/2019-12-15-generic-unification-with-sawmill.html">Unification</a></li>
        <li><b>The rules engine</b></li>
    </ol>
</nav>
<img src="/images/2017-11-13-recursion-without-recursion/compiler.jpg" alt="Compiler overview" />
<p>Today’s the day! We’re going to turn last week’s unification algorithm into an actual programming language by filling in the bottom-right part of the above diagram. Prolog’s <em>rules engine</em> is the system which processes the predicates and facts in your program to answer queries.</p>
<h2 id="the-database"><a href="#the-database">The Database</a></h2>
<p>When you load a program into your Prolog interpreter, it reads the collection of rules into an internal data structure. This data structure is known as Prolog’s <em>database</em>. For simplicity we can represent the database as an array of rules (ie, the same structure which comes out of the parser), but a real Prolog interpreter would use a more specialised data structure to make querying more efficient.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Engine</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> ImmutableArray<span class="op">&lt;</span>Rule<span class="op">&gt;</span> _database<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="fu">Engine</span><span class="op">(</span>ImmutableArray<span class="op">&lt;</span>Rule<span class="op">&gt;</span> database<span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        _database <span class="op">=</span> database<span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="a-first-attempt"><a href="#a-first-attempt">A First Attempt</a></h2>
<p>Prolog’s interactive terminal accepts <em>queries</em> (predicates) and outputs a <em>substitution</em> which satisfies the query, according to the rules in the database. So the signature for <code>Query</code> is</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;</span> <span class="fu">Query</span><span class="op">(</span>Term goal<span class="op">)</span></span></code></pre></div><p>If a goal can’t be satisfied, <code>Query</code> will return <code>null</code>.</p>
<p>When you type a query, Prolog looks for the first rule in its database which matches the goal. In code, that means looping over <code>_database</code> and ignoring rules whose <code>Head</code> doesn’t unify with the goal.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;</span> <span class="fu">Query</span><span class="op">(</span>Term goal<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> rule <span class="kw">in</span> _database<span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="co">// call the overload below</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> result <span class="op">=</span> <span class="fu">Query</span><span class="op">(</span>rule<span class="op">,</span> goal<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(</span>result <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> result<span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;</span> <span class="fu">Query</span><span class="op">(</span>Rule rule<span class="op">,</span> Term goal<span class="op">)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;</span> subst<span class="op">;</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        subst <span class="op">=</span> rule<span class="op">.</span><span class="fu">Head</span><span class="op">.</span><span class="fu">Unify</span><span class="op">(</span>goal<span class="op">);</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">catch</span> <span class="op">(</span>UnificationError<span class="op">)</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>If the rule’s head does match the goal, Prolog needs to check the conditions on the right hand side of the rule. Each predicate on the right-hand side becomes a sub-goal; we’ll recursively call <code>Query</code> for each of these sub-goals. These recursive <code>Query</code> calls will return a substitution, and the information from those substitutions needs to be propagated bi-directionally. It’s just like when we were solving a system of equations in the last post: we’ll propagate information forwards by <code>Apply</code>ing the current substitution to later sub-goals, and propagate it backwards by <code>Compose</code>-ing the substitutions from each recursive <code>Query</code> call into the current substitution.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;</span> <span class="fu">Query</span><span class="op">(</span>Rule rule<span class="op">,</span> Term goal<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ... </span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> predicate <span class="kw">in</span> rule<span class="op">.</span><span class="fu">Body</span><span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> subst2 <span class="op">=</span> <span class="fu">Query</span><span class="op">(</span>subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>predicate<span class="op">));</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(</span>subst2 <span class="op">==</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        subst <span class="op">=</span> subst<span class="op">.</span><span class="fu">Compose</span><span class="op">(</span>subst2<span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> subst<span class="op">;</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>If any of the recursive <code>Query</code> calls failed, that means one of the conditions on the right hand side was not satisfiable, so the whole rule fails (this function returns <code>null</code>) and we have to try the next one. Eventually we hope to find a rule whose head matches the goal <em>and</em> whose conditions are satisfied. This means the query was successful, so we return the <code>subst</code> corresponding to the rule.</p>
<p>That’s a decent first stab at the code for <code>Query</code>. Now we have to fix the bugs.</p>
<h2 id="backtracking"><a href="#backtracking">Backtracking</a></h2>
<p>Here’s a trimmed-down version of the example database from the first post.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>likes(benjamin<span class="kw">,</span> asparagus)<span class="kw">.</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>likes(benjamin<span class="kw">,</span> pizza)<span class="kw">.</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>likes(clio<span class="kw">,</span> pizza)<span class="kw">.</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>dinner(<span class="dt">Food</span>) <span class="kw">:-</span> likes(benjamin<span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">,</span> likes(clio<span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">.</span></span></code></pre></div><p>When we feed this database into our <code>Engine</code> and ask it what’s for dinner,</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> program <span class="op">=</span> @<span class="st">&quot;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="fu">likes</span><span class="op">(</span>benjamin<span class="op">,</span> asparagus<span class="op">).</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="fu">likes</span><span class="op">(</span>benjamin<span class="op">,</span> pizza<span class="op">).</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="fu">likes</span><span class="op">(</span>clio<span class="op">,</span> pizza<span class="op">).</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="fu">dinner</span><span class="op">(</span>Food<span class="op">)</span> <span class="op">:-</span> <span class="fu">likes</span><span class="op">(</span>benjamin<span class="op">,</span> Food<span class="op">),</span> <span class="fu">likes</span><span class="op">(</span>clio<span class="op">,</span> Food<span class="op">).</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> ast <span class="op">=</span> PrologParser<span class="op">.</span><span class="fu">ParseProgram</span><span class="op">(</span>program<span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> engine <span class="op">=</span> <span class="kw">new</span> <span class="fu">Engine</span><span class="op">(</span>ast<span class="op">);</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> query <span class="op">=</span> PrologParser<span class="op">.</span><span class="fu">ParseQuery</span><span class="op">(</span><span class="st">&quot;dinner(Food)&quot;</span><span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> result <span class="op">=</span> engine<span class="op">.</span><span class="fu">Query</span><span class="op">(</span>query<span class="op">);</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="kw">if</span> <span class="op">(</span>result <span class="op">==</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span><span class="st">&quot;no solution&quot;</span><span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="kw">else</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span><span class="fu">Write</span><span class="op">(</span>result<span class="op">));</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>it replies <code>no solution</code>, even though there is a clear solution (<code>Food := pizza</code>). What did we do wrong?</p>
<p>Let’s think about how our engine is going to execute this query.</p>
<ol>
<li>Find a rule whose head unifies with the goal. There’s only one option: the <code>dinner(Food)</code> line.
</li>
<li>Query for the first predicate in the rule’s body, namely <code>likes(benjamin, Food)</code>.
</li>
<li>Find a rule whose head unifies with the predicate. There are two options, <code>likes(benjamin, asparagus)</code> and <code>likes(benjamin, pizza)</code>. The engine chooses the first one, so <code>Food := asparagus</code>.
</li>
<li>Now query for the second predicate in the rule’s body, which is <code>likes(clio, Food)</code>. Since <code>Food := asparagus</code>, we’re looking for <code>likes(clio, asparagus)</code>
</li>
<li>Since there are no rules matching <code>likes(clio, asparagus)</code> the query fails.
</li>
</ol>
<p>The bug was in step 3, when the engine committed to the first rule which matched. It later realised that <code>Food</code> couldn’t be <code>asparagus</code>, so it needs to be able to <em>backtrack</em> and undo that decision. (This is very similar to the backtracking which parsers do, as detailed in an earlier post.)</p>
<p>The reality is that each goal may have multiple substitutions which satisfy it. <code>likes(benjamin, Food)</code> has two solutions, <code>Food := asparagus</code> and <code>Food := pizza</code>, but we threw away the second one. So our <code>Query</code> signature really should’ve looked like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> <span class="fu">Query</span><span class="op">(</span>Term goal<span class="op">)</span></span></code></pre></div><p>When there’s no solution, <code>Query</code> will return an empty list (rather than <code>null</code> as before). I’ll update the implementation to work with a collection of substitutions.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> <span class="fu">Query</span><span class="op">(</span>Term goal<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> _database<span class="op">.</span><span class="fu">SelectMany</span><span class="op">(</span>rule <span class="op">=&gt;</span> <span class="fu">Query</span><span class="op">(</span>rule<span class="op">,</span> goal<span class="op">));</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> <span class="fu">Query</span><span class="op">(</span>Rule rule<span class="op">,</span> Term goal<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> substs<span class="op">;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        substs <span class="op">=</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> rule<span class="op">.</span><span class="fu">Head</span><span class="op">.</span><span class="fu">Unify</span><span class="op">(</span>goal<span class="op">)</span> <span class="op">};</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">catch</span> <span class="op">(</span>UnificationError<span class="op">)</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">new</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;[]</span> <span class="op">{</span> <span class="op">};</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        </span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> predicate <span class="kw">in</span> rule<span class="op">.</span><span class="fu">Body</span><span class="op">)</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        substs <span class="op">=</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>            from subst <span class="kw">in</span> substs</span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>            from subst2 <span class="kw">in</span> <span class="fu">Query</span><span class="op">(</span>subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>predicate<span class="op">))</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            select subst<span class="op">.</span><span class="fu">Compose</span><span class="op">(</span>subst2<span class="op">);</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> substs<span class="op">;</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><code>SelectMany</code> (and <code>from...select</code>, which is the same thing under the hood) coming in clutch here. Each predicate in the body of a rule has potentially many solutions, so each recursive call to <code>Query</code> introduces potentially many possible branches to choose from. <code>SelectMany</code> lets us take all of them — but because <code>IEnumerable</code> is lazy, at runtime it doesn’t actually explore more branches than necessary to find a single solution. It also handles the “no solutions” case gracefully: if <code>substs</code> is empty then the body of the <code>foreach</code> loop does nothing. (<code>SelectMany</code> always returns an empty collection when its input collection is empty.)</p>
<p>Working with immutable data is of utmost importance here. Combining lazy <code>IEnumerable</code>s with mutable data can have catastrophic consequences because it’s hard to predict when your code will be run. The body of my loop computes a <em>new</em> <code>substs</code> to be used for the next iteration; it doesn’t update a single collection of solutions. I don’t know what would happen if you did write it like that but I know it would be wrong!</p>
<p>Feeding the <code>dinner(Food)</code> query into this version of the code correctly outputs <code>Food := pizza</code>.</p>
<h2 id="scope-management"><a href="#scope-management">Scope Management</a></h2>
<h3 id="discharging"><a href="#discharging">Discharging</a></h3>
<p>Here’s another example program which reveals a bug in <code>Query</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>foo(<span class="dt">X</span>)<span class="kw">.</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>bar(baz)<span class="kw">.</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>test() <span class="kw">:-</span> foo(wibble)<span class="kw">,</span> bar(<span class="dt">X</span>)<span class="kw">.</span></span></code></pre></div><p><code>test()</code> is straightforwardly true, but our interpreter again prints out <code>no solution</code>. Once again, let’s walk through the steps the engine will take.</p>
<ol>
<li>Query <code>foo(wibble)</code>. The only rule matching this goal is <code>foo(X).</code>, which matches when <code>X := wibble</code>. So the recursive call to <code>Query</code> returns the substitution <code>X := wibble</code>.
</li>
<li>Apply that substitution to the rest of the <code>test</code> rule.
</li>
<li>Query the second predicate in <code>test</code>, which is <code>bar(wibble)</code>. This goal fails because the only <code>bar</code>-related fact in the database is <code>bar(baz)</code>.
</li>
</ol>
<p>The bug is in step 1, when we returned the <code>X := wibble</code> substitution. <code>foo</code>’s <code>X</code> escaped its scope and collided with the <code>X</code> in <code>test</code>’s body. We need to adjust our code so that variables can’t escape their scope by being returned in a substitution.</p>
<p>The fix is to <em>discharge</em> some of the equalities in a substitution at the end of running a rule (that is, on the last line of <code>Query</code>). We want to throw out equalities related to variables which were local to the rule, keeping only the ones which tell you something about the variables in the goal.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> <span class="fu">Query</span><span class="op">(</span>Rule rule<span class="op">,</span> Term goal<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> substs<span class="op">.</span><span class="fu">Select</span><span class="op">(</span>s <span class="op">=&gt;</span> <span class="fu">Discharge</span><span class="op">(</span>s<span class="op">,</span> goal<span class="op">));</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;</span> <span class="fu">Discharge</span><span class="op">(</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;</span> subst<span class="op">,</span> Term goal<span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> subst</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Where</span><span class="op">(</span>kvp <span class="op">=&gt;</span> goal<span class="op">.</span><span class="fu">Variables</span><span class="op">().</span><span class="fu">Contains</span><span class="op">(</span>kvp<span class="op">.</span><span class="fu">Key</span><span class="op">))</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">ToImmutableDictionary</span><span class="op">();</span></span></code></pre></div><p>This fixes the bug. <code>test()</code> now correctly returns an empty substitution.</p>
<h3 id="freshening"><a href="#freshening">Freshening</a></h3>
<p>There’s one final bug to fix in the engine.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>foo(a<span class="kw">,</span> <span class="dt">X</span>)<span class="kw">.</span></span></code></pre></div><p>Running the query <code>foo(X, b)</code> should return <code>X := a</code>, but the interpreter prints <code>no solution</code>. This is of course another name collision issue. When unifying the goal with the left hand side, the interpreter has mistaken the two <code>X</code>s for being the <em>same</em> <code>X</code>. The <code>X</code> in <code>foo</code>’s left hand side should be local to <code>foo</code>.</p>
<p>To avoid unintentional collisions we need to <em>freshen</em> local variables. Whenever the interpreter enters a rule, it should rename the rule’s local variables to new variables which aren’t being used anywhere in the goal. An easy way to guarantee that a name isn’t being used anywhere in the goal is to stick a number on the end of it, and increase that number by 1 each time. (I’m also going to put an <code>?</code> on the front of the auto-generated variable names, because variables beginning with <code>?</code> is not valid Prolog so it’s guaranteed not to collide with a name typed by a programmer.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="dt">int</span> _freshenCounter <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> Rule <span class="fu">Freshen</span><span class="op">(</span>Rule rule<span class="op">)</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// find all of the rule&#39;s local variables.</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// NB: local variables may appear in the rule&#39;s body but not the head.</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> variables <span class="op">=</span> rule<span class="op">.</span><span class="fu">Body</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>x <span class="op">=&gt;</span> <span class="op">((</span>Term<span class="op">)</span>x<span class="op">).</span><span class="fu">Variables</span><span class="op">())</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Aggregate</span><span class="op">(((</span>Term<span class="op">)</span>rule<span class="op">.</span><span class="fu">Head</span><span class="op">).</span><span class="fu">Variables</span><span class="op">(),</span> <span class="op">(</span>xs<span class="op">,</span> ys<span class="op">)</span> <span class="op">=&gt;</span> xs<span class="op">.</span><span class="fu">Union</span><span class="op">(</span>ys<span class="op">));</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    </span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// build a substitution which maps each variable to a fresh version of that variable</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> subst <span class="op">=</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;.</span><span class="fu">Empty</span><span class="op">;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> variable <span class="kw">in</span> variables<span class="op">)</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        subst <span class="op">=</span> subst<span class="op">.</span><span class="fu">Add</span><span class="op">(</span>variable<span class="op">,</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;?&quot;</span> <span class="op">+</span> variable <span class="op">+</span> _freshenCounter<span class="op">));</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        _freshenCounter<span class="op">++;</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="co">// apply the substitution everywhere in the rule</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> <span class="kw">new</span> <span class="fu">Rule</span><span class="op">(</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="op">(</span>Predicate<span class="op">)</span>subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>rule<span class="op">.</span><span class="fu">Head</span><span class="op">),</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>        rule<span class="op">.</span><span class="fu">Body</span><span class="op">.</span><span class="fu">Select</span><span class="op">(</span>subst<span class="op">.</span><span class="fu">Apply</span><span class="op">).</span><span class="fu">Cast</span><span class="op">&lt;</span>Predicate<span class="op">&gt;().</span><span class="fu">ToImmutableArray</span><span class="op">()</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Then at the start of <code>Query</code> we need to <code>Freshen</code> the rule we’re about to enter.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> <span class="fu">Query</span><span class="op">(</span>Rule rule<span class="op">,</span> Term goal<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    rule <span class="op">=</span> <span class="fu">Freshen</span><span class="op">(</span>rule<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>The <code>foo(X, b)</code> query now correctly returns <code>X := a</code>.</p>
<p>Here’s the final implementation of <code>Query</code> in full.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> <span class="fu">Query</span><span class="op">(</span>Term goal<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> _database<span class="op">.</span><span class="fu">SelectMany</span><span class="op">(</span>rule <span class="op">=&gt;</span> <span class="fu">Query</span><span class="op">(</span>rule<span class="op">,</span> goal<span class="op">));</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> <span class="fu">Query</span><span class="op">(</span>Rule rule<span class="op">,</span> Term goal<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    rule <span class="op">=</span> <span class="fu">Freshen</span><span class="op">(</span>rule<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;&gt;</span> substs<span class="op">;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">try</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        substs <span class="op">=</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> rule<span class="op">.</span><span class="fu">Head</span><span class="op">.</span><span class="fu">Unify</span><span class="op">(</span>goal<span class="op">)</span> <span class="op">};</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">catch</span> <span class="op">(</span>UnificationError<span class="op">)</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">new</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> Term<span class="op">&gt;[]</span> <span class="op">{</span> <span class="op">};</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    </span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> predicate <span class="kw">in</span> rule<span class="op">.</span><span class="fu">Body</span><span class="op">)</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        substs <span class="op">=</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            from subst <span class="kw">in</span> substs</span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>            from subst2 <span class="kw">in</span> <span class="fu">Query</span><span class="op">(</span>subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>predicate<span class="op">))</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>            select subst<span class="op">.</span><span class="fu">Compose</span><span class="op">(</span>subst2<span class="op">);</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> substs<span class="op">.</span><span class="fu">Select</span><span class="op">(</span>s <span class="op">=&gt;</span> <span class="fu">Discharge</span><span class="op">(</span>s<span class="op">,</span> goal<span class="op">));</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Here are some exercises you could try:</p>
<ul>
<li>Because we implemented <code>_database</code> as an array, finding a matching rule is linear in the size of the program. Try optimising the <code>_database</code> data structure.
</li>
<li>Try optimising <code>Freshen</code> so that it doesn’t rename more variables than it needs to.
<ul>
<li>It’s actually possible to avoid freshening altogether by changing the way variables are represented.
</li>
</ul>
</li>
<li>Backtracking is enabled by default in Prolog (unlike in Pidgin where it’s disabled by default). The full Prolog language includes the <code>!</code> operator (pronounced <em>cut</em>) to disable backtracking when necessary. When Prolog encounters <code>!</code> in the right-hand side of a rule, it commits to all of the choices it’s made since (and including) selecting that rule from the database. Try implementing cut as an exercise. (You’ll need to change the parser, the AST, and the rules engine.)
</li>
</ul>
<p>Today’s code is available in <a href="https://github.com/benjamin-hodgson/Amateurlog">the example repo</a>, in the <a href="https://github.com/benjamin-hodgson/Amateurlog/blob/80a4ac12303d007295059ac4d9e36ce935a904c2/Engine.cs"><code>Engine.cs</code></a> file.</p>

]]></summary>
</entry>
<entry>
    <title>Generic Unification with Sawmill</title>
    <link href="http://www.benjamin.pizza/posts/2019-12-15-generic-unification-with-sawmill.html" />
    <id>http://www.benjamin.pizza/posts/2019-12-15-generic-unification-with-sawmill.html</id>
    <published>2019-12-15T00:00:00Z</published>
    <updated>2019-12-15T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>This is part of a series of posts about implementing a miniature Prolog interpreter in C#.</p>
<nav>
    <ol>
        <li><a href="/posts/2019-12-01-write-you-a-prolog.html">Introduction &amp; Syntax</a></li>
        <li><a href="/posts/2019-12-08-parsing-prolog-with-pidgin.html">Parsing</a></li>
        <li><b>Unification</b></li>
        <li><a href="/posts/2019-12-22-building-prologs-rules-engine.html">The rules engine</a></li>
    </ol>
</nav>
<p>We’re getting on to the fun part of writing an interpreter: actually <em>interpreting</em> the input code. In this post we’re going to implement a <em>unification</em> algorithm using my generic programming library <a href="https://github.com/benjamin-hodgson/Sawmill">Sawmill</a>. Unification slots somewhere in the middle or bottom-right of this diagram:</p>
<img src="/images/2017-11-13-recursion-without-recursion/compiler.jpg" alt="Compiler overview" />
<h2 id="unification"><a href="#unification">Unification</a></h2>
<p>Unification is a process for solving equations, much like the equations you’d solve in algebra at school. It’s all about plugging holes — given a pair of terms with variables inside them, what subterms can I plug in for the variables to make the terms equal? Unifying two terms produces a <em>substitution</em> — a mapping from variables to terms. If you plug the terms in for the variables (on both sides of the equation), then the equation should be satisfied.</p>
<p>The algorithm works by examining the syntactic structure of the two terms. It tries to match up each node in one term’s syntax tree with a corresponding node in the other. When you find yourself matching a term against a variable, you know that the variable must equal the term. Unification is a purely syntactic process — you can’t apply domain-specific rules such as “add a number to both sides” like you can in algebra.</p>
<p>Let’s work through some examples to get a feel for it.</p>
<ul>
<li>
<p>Unify <code>f(a, X, Y)</code> with <code>f(a, b, g(x))</code>.</p>
<ul>
<li>Starting at the outermost part of the two terms’ syntax, we see <code>f</code> applied to three arguments in each of them — a match. Now we can match up the arguments and try to unify each of them.
</li>
<li>The first argument in each is the atom <code>a</code> — so they match.
</li>
<li>Unifying the second arguments gives us <code>X ~ b</code>. <code>X</code> is a variable, and we now know it must be equal to <code>b</code>, so that gets added to the output substitution.
</li>
<li>Unifying the third arguments, we find <code>Y ~ g(x)</code>, so that also goes in the output. It’s OK to match a variable to a composite term.
</li>
<li>The resulting substitution is <strong><code>X := b; Y := g(x)</code></strong>. You can try plugging this substitution back in to the two terms to verify that it does indeed make them equal.
<div style="display:flex; align-items:center"><img src="/images/2019-12-15-generic-unification-with-sawmill/example1-1.png" width="47%" style="margin-right:3%" /><img src="/images/2019-12-15-generic-unification-with-sawmill/example1-2.png" width="47%" style="margin-left:3%" /></div>
</li>
</ul>
</li>
<li>
<p>Unify <code>f(X, g(X))</code> with <code>f(m(b), g(m(b)))</code>. In this example, the <code>X</code> variable appears twice in the left hand argument; these are the <strong>same</strong> <code>X</code> and at the end of unification they have to agree.</p>
<ul>
<li>The outermost <code>f</code>s match, so we descend to the arguments.
</li>
<li>The first argument gives us <code>X ~ m(b)</code>.
</li>
<li>Looking at the second argument, you see <code>g</code> applied to one argument in both cases. This is a match, so we can once more continue to compare the arguments.
</li>
<li>Comparing the arguments gives us <code>X ~ m(b)</code>. This is the same constraint as the one we got from the first argument.
</li>
<li>The resulting substitution is <strong><code>X := m(b)</code></strong>.
<div style="display:flex; align-items:center"><img src="/images/2019-12-15-generic-unification-with-sawmill/example2-1.png" width="47%" style="margin-right:3%" /><img src="/images/2019-12-15-generic-unification-with-sawmill/example2-2.png" width="47%" style="margin-left:3%" /></div>
</li>
</ul>
</li>
<li>
<p>Unify <code>f(g(X), a)</code> with <code>f(g(Y), X)</code>. In this example we see variables appearing on both sides. We have to come up with a value for all of the variables in both terms; once again the <code>X</code> appearing on both sides is the same <code>X</code>.</p>
<ul>
<li>Once more, the outermost <code>f</code>s match.
</li>
<li>Matching up the first arguments, we get <code>g(X) ~ g(Y)</code>, so <code>X ~ Y</code>. It’s OK to match variables to each other.
</li>
<li>Matching up the first arguments gives us <code>a ~ X</code>.
</li>
<li>The resulting substitution is <strong><code>X := a; Y := X</code></strong> (or, equivalently, <strong><code>X := a; Y := a</code></strong>).
<div style="display:flex; align-items:center"><img src="/images/2019-12-15-generic-unification-with-sawmill/example3-1.png" width="47%" style="margin-right:3%" /><img src="/images/2019-12-15-generic-unification-with-sawmill/example3-2.png" width="47%" style="margin-left:3%" /></div>
</li>
</ul>
</li>
<li>
<p>A couple of exercises:</p>
<ul>
<li>Does <code>f(g(X), a)</code> unify with <code>f(g(b), X)</code>?
</li>
<li>Does <code>f(X, Y)</code> unify with <code>f(g(Y), Z)</code>?
</li>
<li>Does <code>f(X, Y)</code> unify with <code>f(Y, g(X))</code>?
</li>
<li>Try coming up with some interesting examples of terms which don’t unify.
</li>
</ul>
</li>
</ul>
<p>Let’s sketch out an algorithm for unification.</p>
<ol>
<li>Look at the outermost node in the two terms’ ASTs.
</li>
<li>If either one of them is a variable, bind the variable to the term in the output substitution. If it’s already bound in the output substitution, make sure that this binding doesn’t conflict.
</li>
<li>If both are leaf nodes, check that they match.
</li>
<li>If both are composite terms, check that they match and that they have the same number of children. If so, repeat steps 1-3 for each pair of children.
</li>
<li>Otherwise, the terms don’t match and we should abort unification.
</li>
</ol>
<p>Hopefully you can see how I’ve applied these steps in the examples above. I’ve glossed over some important details here (particularly regarding what happens in step 2 when a variable is already in the substitution) but I’ll be sure to fill them in when we get to writing code. (In fact we’re going to design our code so that a variable will never already be in the substitution.)</p>
<h2 id="iunifiable"><a href="#iunifiable"><code>IUnifiable</code></a></h2>
<p>Unification is a central part of Prolog’s programming model, but it has applications outside of Prolog as well (type inference, for example). Any time you have a syntactic structure with placeholder variables, the question “what can I plug in for these variables?” makes sense.</p>
<p>Let’s quantify that. Reading back over the description of the algorithm, it seems to build on a few core concepts:</p>
<ul>
<li>Terms
</li>
<li>Terms which are variables
</li>
<li>Composite terms with children
</li>
<li>Leaf nodes with no children
</li>
<li>Matching a pair of terms
</li>
</ul>
<p>Abstracting over these concepts should allow us to implement unification once and for all, without depending on the specifics of Prolog’s terms. Don’t solve one problem. Solve them all!</p>
<p>Sawmill’s core <code>IRewritable</code> interface is a generic way of looking at tree-shaped terms with children. The only concepts we need to add on top of <code>IRewritable</code> are <em>variables</em> and <em>matching</em>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">bool</span> <span class="fu">Match</span><span class="op">(</span>T other<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">string</span> <span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><code>Match</code> tells you whether the current node matches another node. In Prolog’s case, it tests whether the two nodes have the same name and number of children. <code>AsVariable</code> checks whether the current node is a variable, returning its name as a string (or <code>null</code> if it’s not). Here’s what it looks like implemented on <a href="/posts/2019-12-01-write-you-a-prolog.html">the <code>Term</code> syntax tree</a>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> Term <span class="op">:</span> IUnifiable<span class="op">&lt;</span>Term<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">abstract</span> <span class="dt">bool</span> <span class="fu">Match</span><span class="op">(</span>Term other<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">abstract</span> <span class="dt">string</span> <span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Predicate <span class="op">:</span> Term</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">bool</span> <span class="fu">Match</span><span class="op">(</span>Term other<span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> other <span class="kw">is</span> Predicate p</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="op">&amp;&amp;</span> p<span class="op">.</span><span class="fu">Name</span> <span class="op">==</span> Name</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="op">&amp;&amp;</span> p<span class="op">.</span><span class="fu">Args</span><span class="op">.</span><span class="fu">Length</span> <span class="op">==</span> Args<span class="op">.</span><span class="fu">Length</span><span class="op">;</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">string</span> <span class="fu">AsVariable</span><span class="op">()</span> <span class="op">=&gt;</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Variable <span class="op">:</span> Term</span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">bool</span> <span class="fu">Match</span><span class="op">(</span>Term other<span class="op">)</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> other <span class="kw">is</span> Variable v</span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>        <span class="op">&amp;&amp;</span> v<span class="op">.</span><span class="fu">Name</span> <span class="op">==</span> Name<span class="op">;</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">string</span> <span class="fu">AsVariable</span><span class="op">()</span> <span class="op">=&gt;</span> Name<span class="op">;</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Atom <span class="op">:</span> Term</span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">bool</span> <span class="fu">Match</span><span class="op">(</span>Term other<span class="op">)</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> other <span class="kw">is</span> Atom a</span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>        <span class="op">&amp;&amp;</span> a<span class="op">.</span><span class="fu">Value</span> <span class="op">==</span> Value<span class="op">;</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">string</span> <span class="fu">AsVariable</span><span class="op">()</span> <span class="op">=&gt;</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>For example, here’s a LINQ query which finds all of the variables mentioned anywhere in a term. It uses <code>SelfAndDescendants</code> together with <code>AsVariable</code> to find the nodes which were in fact variables.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableHashSet<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> Variables<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T value<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> value</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">SelfAndDescendants</span><span class="op">()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>x <span class="op">=&gt;</span> x<span class="op">.</span><span class="fu">AsVariable</span><span class="op">())</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Where</span><span class="op">(</span>name <span class="op">=&gt;</span> name <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Distinct</span><span class="op">()</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">ToImmutableHashSet</span><span class="op">();</span></span></code></pre></div><h2 id="substitutions"><a href="#substitutions">Substitutions</a></h2>
<p>I mentioned that the output of unification is a <em>substitution</em> — a mapping from variable names to terms. We’ll model that using an ordinary dictionary of strings and <code>T</code>s. Our signature for <code>Unify</code> is going to look like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Unify<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T left<span class="op">,</span> T right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span></code></pre></div><p>The main thing you can do with a substitution is <em>apply</em> it to a term. That means replacing all the variables in the term with the sub-terms they’re mapped to by the substitution. This should eliminate any variables in the term which are bound by the substitution.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> T Apply<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> subst<span class="op">,</span> T value<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> value<span class="op">.</span><span class="fu">Rewrite</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        x <span class="op">=&gt;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            <span class="dt">var</span> name <span class="op">=</span> x<span class="op">.</span><span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> <span class="op">(</span>name <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> subst<span class="op">.</span><span class="fu">GetValueOrDefault</span><span class="op">(</span>name<span class="op">,</span> x<span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> x<span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>We’re going to maintain the invariant that the terms in a substitution are never going to contain any variables which are bound by the substitution. (It’s possible, and indeed desirable for efficiency, to relax this invariant, but today we’re going to focus on simplicity.)</p>
<h2 id="binding-single-variables--the-occurs-check"><a href="#binding-single-variables--the-occurs-check">Binding Single Variables &amp; the Occurs Check</a></h2>
<p>Time to fill in the body of <code>Unify</code>. Let’s start with step 2 of the algorithm: what to do when either of the input terms is a variable.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Unify<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T left<span class="op">,</span> T right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> leftName <span class="op">=</span> left<span class="op">.</span><span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>leftName <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span>  <span class="co">// then the left term was a variable</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="fu">Bind</span><span class="op">(</span>leftName<span class="op">,</span> right<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> rightName <span class="op">=</span> right<span class="op">.</span><span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>rightName <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span>  <span class="co">// then the right term was a variable</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="fu">Bind</span><span class="op">(</span>rightName<span class="op">,</span> left<span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><code>Bind(name, value)</code> returns a substitution with the variable <code>name</code> bound to the term <code>value</code>. However! There are some important edge cases to watch out for which could result in breaking the invariant I mentioned above.</p>
<ol>
<li>The term <code>value</code> could be the <em>same</em> variable as <code>name</code>. This would produce a substitution like <code>X := X</code> (that is, a do-nothing substitution), so we’ll just return an empty substitution in that case.
</li>
<li>The term <code>value</code> could mention the variable <code>name</code> somewhere inside it. This would produce a substitution like <code>X := foo(X)</code>. If you try and find a concrete value for <code>X</code> you’d end up with an infinitely long chain of <code>foo</code>s! Some systems allow infinite terms like this, but others disallow it by checking whether a variable occurs in the term it’s being bound to. This check is suitably called the <em>occurs check</em>.
</li>
</ol>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Bind<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="dt">string</span> name<span class="op">,</span> T value<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> valueName <span class="op">=</span> value<span class="op">.</span><span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>valueName <span class="op">!=</span> <span class="kw">null</span> <span class="op">&amp;&amp;</span> name <span class="op">==</span> valueName<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;.</span><span class="fu">Empty</span><span class="op">;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>value<span class="op">.</span><span class="fu">Variables</span><span class="op">().</span><span class="fu">Contains</span><span class="op">(</span>name<span class="op">))</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">UnificationError</span><span class="op">(</span><span class="st">&quot;occurs check&quot;</span><span class="op">);</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;.</span><span class="fu">Empty</span><span class="op">.</span><span class="fu">Add</span><span class="op">(</span>name<span class="op">,</span> value<span class="op">);</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="handling-non-variables"><a href="#handling-non-variables">Handling Non-Variables</a></h2>
<p>Let’s continue implementing <code>Unify</code>. At this point we know that neither <code>left</code> nor <code>right</code> are variables, so they must be either composite terms or leaf nodes. In either case, we need to check whether they match.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Unify<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T left<span class="op">,</span> T right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(!</span>left<span class="op">.</span><span class="fu">Match</span><span class="op">(</span>right<span class="op">))</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">UnificationError</span><span class="op">(</span><span class="st">&quot;values didn&#39;t match&quot;</span><span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>If they did match, it’s time to try matching up their children. (If the two nodes were leaf nodes, their list of children is empty, so the following code does nothing.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Unify<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T left<span class="op">,</span> T right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> leftChildren <span class="op">=</span> left<span class="op">.</span><span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> rightChildren <span class="op">=</span> right<span class="op">.</span><span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> <span class="fu">Solve</span><span class="op">(</span>leftChildren<span class="op">,</span> rightChildren<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="unifying-children--systems-of-equations"><a href="#unifying-children--systems-of-equations">Unifying Children — Systems of Equations</a></h2>
<p>Unifying the children means solving a <em>system</em> of equations. If more than one equation mentions the same variable, they have to agree on what that variable should be.</p>
<p>The plain is to pair up the children in the two lists and try to unify each with their partner, building up a substitution as we go.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Solve<span class="op">&lt;</span>T<span class="op">&gt;(</span>T<span class="op">[]</span> left<span class="op">,</span> T<span class="op">[]</span> right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>left<span class="op">.</span><span class="fu">Length</span> <span class="op">!=</span> right<span class="op">.</span><span class="fu">Length</span><span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">UnificationError</span><span class="op">(</span><span class="st">&quot;values didn&#39;t match&quot;</span><span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> subst <span class="op">=</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;.</span><span class="fu">Empty</span><span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="fu">var</span> <span class="op">(</span>l<span class="op">,</span> r<span class="op">)</span> <span class="kw">in</span> left<span class="op">.</span><span class="fu">Zip</span><span class="op">(</span>right<span class="op">))</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="co">// ...</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> subst<span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>This loop requires some thinking. As you unify each pair of children, you learn something about the variables in the system of equations. These learnings need to be propagated to the other equations. So as we build our substitution we need to make sure to apply it to the remaining equations in the system. This propagates information from left to right, ensuring that you don’t encounter variables which have already been bound by earlier equations.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Solve<span class="op">&lt;</span>T<span class="op">&gt;(</span>T<span class="op">[]</span> left<span class="op">,</span> T<span class="op">[]</span> right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="fu">var</span> <span class="op">(</span>l<span class="op">,</span> r<span class="op">)</span> <span class="kw">in</span> left<span class="op">.</span><span class="fu">Zip</span><span class="op">(</span>right<span class="op">))</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> newL <span class="op">=</span> subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>l<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> newR <span class="op">=</span> subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>r<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> newSubst <span class="op">=</span> newL<span class="op">.</span><span class="fu">Unify</span><span class="op">(</span>newR<span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="co">// ...</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>But we also need to propagate information from right to left. When you unify <code>f(X, Y)</code> with <code>f(Y, a)</code>, the first argument sets <code>X := Y</code>, but the second argument sets <code>Y := a</code>. Simply combining the two substitutions results in <code>X := Y; Y := a</code> which breaks our invariant that bound variables don’t appear inside a substitution. When you combine two substitutions, you need to <code>Apply</code> the second substitution to the terms inside the first one.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Solve<span class="op">&lt;</span>T<span class="op">&gt;(</span>T<span class="op">[]</span> left<span class="op">,</span> T<span class="op">[]</span> right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="fu">var</span> <span class="op">(</span>l<span class="op">,</span> r<span class="op">)</span> <span class="kw">in</span> left<span class="op">.</span><span class="fu">Zip</span><span class="op">(</span>right<span class="op">))</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="co">// ...</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        subst <span class="op">=</span> subst<span class="op">.</span><span class="fu">Compose</span><span class="op">(</span>newSubst<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Compose<span class="op">&lt;</span>T<span class="op">&gt;(</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> left<span class="op">,</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> right</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> left</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>kvp <span class="op">=&gt;</span> <span class="kw">new</span> KeyValuePair<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;(</span>kvp<span class="op">.</span><span class="fu">Key</span><span class="op">,</span> right<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>kvp<span class="op">.</span><span class="fu">Value</span><span class="op">)))</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Where</span><span class="op">(</span>kvp <span class="op">=&gt;</span> <span class="op">!(</span>kvp<span class="op">.</span><span class="fu">Value</span> <span class="kw">is</span> Variable v <span class="op">&amp;&amp;</span> v<span class="op">.</span><span class="fu">Name</span> <span class="op">==</span> kvp<span class="op">.</span><span class="fu">Key</span><span class="op">))</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Concat</span><span class="op">(</span>right<span class="op">)</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">ToImmutableDictionary</span><span class="op">();</span></span></code></pre></div><p>Note <code>right.Apply(kvp.Value)</code> inside the <code>Select</code>. This can sometimes result in substitution entries of the form <code>X := X</code> (for example when unifying <code>f(X, Y)</code> with <code>f(Y, X)</code>), so I’m just filtering them out with <code>Where</code>.</p>
<p>That’s the whole algorithm! I’ll repeat <code>Unify</code> and <code>Solve</code> in full:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Unify<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T left<span class="op">,</span> T right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> leftName <span class="op">=</span> left<span class="op">.</span><span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>leftName <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="fu">Bind</span><span class="op">(</span>leftName<span class="op">,</span> right<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> rightName <span class="op">=</span> right<span class="op">.</span><span class="fu">AsVariable</span><span class="op">();</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>rightName <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="fu">Bind</span><span class="op">(</span>rightName<span class="op">,</span> left<span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(!</span>left<span class="op">.</span><span class="fu">Match</span><span class="op">(</span>right<span class="op">))</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">UnificationError</span><span class="op">(</span><span class="st">&quot;values didn&#39;t match&quot;</span><span class="op">);</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> leftChildren <span class="op">=</span> left<span class="op">.</span><span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> rightChildren <span class="op">=</span> right<span class="op">.</span><span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> <span class="fu">Solve</span><span class="op">(</span>leftChildren<span class="op">,</span> rightChildren<span class="op">);</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;</span> Solve<span class="op">&lt;</span>T<span class="op">&gt;(</span>T<span class="op">[]</span> left<span class="op">,</span> T<span class="op">[]</span> right<span class="op">)</span> where T <span class="op">:</span> IUnifiable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>left<span class="op">.</span><span class="fu">Length</span> <span class="op">!=</span> right<span class="op">.</span><span class="fu">Length</span><span class="op">)</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>        <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">UnificationError</span><span class="op">(</span><span class="st">&quot;values didn&#39;t match&quot;</span><span class="op">);</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> subst <span class="op">=</span> ImmutableDictionary<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> T<span class="op">&gt;.</span><span class="fu">Empty</span><span class="op">;</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="fu">var</span> <span class="op">(</span>l<span class="op">,</span> r<span class="op">)</span> <span class="kw">in</span> left<span class="op">.</span><span class="fu">Zip</span><span class="op">(</span>right<span class="op">))</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> newL <span class="op">=</span> subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>l<span class="op">);</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> newR <span class="op">=</span> subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>r<span class="op">);</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> newSubst <span class="op">=</span> newL<span class="op">.</span><span class="fu">Unify</span><span class="op">(</span>newR<span class="op">);</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a>        subst <span class="op">=</span> subst<span class="op">.</span><span class="fu">Compose</span><span class="op">(</span>newSubst<span class="op">);</span></span>
<span id="34"><a href="#34" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="35"><a href="#35" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> subst<span class="op">;</span></span>
<span id="36"><a href="#36" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>A quick test of one of our examples:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="dt">void</span> <span class="fu">Main</span><span class="op">(</span><span class="dt">string</span><span class="op">[]</span> args<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Term left <span class="op">=</span> PrologParser<span class="op">.</span><span class="fu">ParseQuery</span><span class="op">(</span><span class="st">&quot;f(g(X), a)&quot;</span><span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    Term right <span class="op">=</span> PrologParser<span class="op">.</span><span class="fu">ParseQuery</span><span class="op">(</span><span class="st">&quot;f(g(Y), X)&quot;</span><span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> subst <span class="op">=</span> left<span class="op">.</span><span class="fu">Unify</span><span class="op">(</span>right<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span><span class="dt">string</span><span class="op">.</span><span class="fu">Join</span><span class="op">(</span><span class="st">&quot;</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">,</span> subst<span class="op">.</span><span class="fu">Select</span><span class="op">(</span>kvp <span class="op">=&gt;</span> kvp<span class="op">.</span><span class="fu">Key</span> <span class="op">+</span> <span class="st">&quot; := &quot;</span> <span class="op">+</span> kvp<span class="op">.</span><span class="fu">Value</span><span class="op">)));</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// prints out:</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// X := a</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Y := a</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> newLeft <span class="op">=</span> subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>left<span class="op">);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> newRight <span class="op">=</span> subst<span class="op">.</span><span class="fu">Apply</span><span class="op">(</span>right<span class="op">);</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span>newLeft<span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span>newRight<span class="op">);</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="co">// both print out f(g(a), a)</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Some exercises you could try:</p>
<ul>
<li>This implementation does a lot of <code>Apply</code>ing substitutions to terms, specifically in <code>Solve</code> and <code>Compose</code>.
<ul>
<li>Since <code>Rewrite</code> is linear in the size of the tree (it visits every node), what’s the complexity of <code>Unify</code>?
</li>
<li>Can you make it more efficient?
<ul>
<li>Hint 1: you need to relax the invariant that substitutions can’t contain bound variables.
</li>
<li>Hint 2: you’ll need to tweak <code>Bind</code> to avoid <a href="https://norvig.com/unify-bug.pdf">a common bug</a>.
</li>
<li>Hint 3: <code>Apply</code>ing a substitution to a term will no longer eliminate all the bound variables inside the term. Try using <a href="https://www.benjamin.pizza/Sawmill/v3.1.0/api/Sawmill.Rewritable.html#Sawmill_Rewritable_RewriteIter__1___0_System_Func___0___0__"><code>RewriteIter</code></a> to reestablish that invariant.
</li>
</ul>
</li>
</ul>
</li>
<li><code>IUnifiable</code> assumes that variables can always be represented by strings. Many practical programming language implementations use richer data structures than strings (such as variables tagged with their scope) to represent variables. Can you change this design to break the dependency on strings? What API usability issues do you encounter?
</li>
</ul>
<p>All of this code can be found in <a href="https://github.com/benjamin-hodgson/Amateurlog">the example repo</a>, in the <a href="https://github.com/benjamin-hodgson/Amateurlog/blob/master/Unification.cs"><code>Unification.cs</code></a> and <a href="https://github.com/benjamin-hodgson/Amateurlog/blob/master/Syntax.Unification.cs"><code>Syntax.Unification.cs</code></a> files. In the final part of this series, we’ll apply unification to build Prolog’s rules engine.</p>

]]></summary>
</entry>
<entry>
    <title>Parsing Prolog with Pidgin</title>
    <link href="http://www.benjamin.pizza/posts/2019-12-08-parsing-prolog-with-pidgin.html" />
    <id>http://www.benjamin.pizza/posts/2019-12-08-parsing-prolog-with-pidgin.html</id>
    <published>2019-12-08T00:00:00Z</published>
    <updated>2019-12-08T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>Happy birthday to my sister! This is part of a series of posts about implementing a miniature Prolog interpreter in C#.</p>
<nav>
    <ol>
        <li><a href="/posts/2019-12-01-write-you-a-prolog.html">Introduction &amp; Syntax</a></li>
        <li><b>Parsing</b></li>
        <li><a href="/posts/2019-12-15-generic-unification-with-sawmill.html">Unification</a></li>
        <li><a href="/posts/2019-12-22-building-prologs-rules-engine.html">The rules engine</a></li>
    </ol>
</nav>
<img src="/images/2017-11-13-recursion-without-recursion/compiler.jpg" alt="Compiler overview" />
<p>In this post I’m going to focus on the left-hand part of that diagram. We’ll use my parsing library <a href="https://github.com/benjamin-hodgson/Pidgin">Pidgin</a> to convert Prolog source code into the abstract syntax classes I outlined in the previous post.</p>
<h2 id="about-pidgin"><a href="#about-pidgin">About Pidgin</a></h2>
<p>Pidgin is a <em>parser combinator library</em>, meaning it consists of three things:</p>
<ol>
<li>A type <code>Parser&lt;TToken, T&gt;</code>, representing a process which consumes a sequence of <code>TToken</code>s and produces a <code>T</code>. (In our case, <code>TToken</code> will be <code>char</code> because we’re parsing textual data from a string.)
</li>
<li>Methods to create simple <code>Parser</code>s, such as “consume a single character”.
</li>
<li>Methods to combine <code>Parser</code>s into more complex and interesting ones, such as “run two parsers sequentially”.
</li>
</ol>
<p>The power of parser combinators comes from the fact that parsers are treated as ordinary values. You can pass them around as parameters, return them, store them in fields… Programming with parser combinators is <em>just programming</em>. Contrast this with “language workbench” tools like Antlr, which are often more powerful than parser combinators but have a separate syntax, toolchain, etc. Parser combinators are great for medium-sized parsing tasks like this one.</p>
<p>It’s worth elaborating a bit on what I mean by “consume a sequence”. A parser walks left to right along an input sequence, keeping track of its location in the input. Consuming a token means moving the “current location” pointer along to the next token. This is much like how the <code>Stream</code> classes work in .NET — calling a stream’s <code>Read</code> method moves the stream’s current position, so that successive calls to <code>Read</code> return different results. (Pidgin indeed lets you feed a <code>Stream</code> to a <code>Parser</code>.)</p>
<p>When a parser makes a decision about what to do next, that decision is based only on the current character and not on what comes next. If the parser moves further along the string and then realises that decision was wrong, it has to <em>backtrack</em> to the position where it made the decision before it can proceed with a different choice. Backtracking can be catastrophically costly (as described in <a href="https://vimeo.com/112065252">a short talk by my esteemed ex-colleague Balpha</a>), so you want to code your parser to minimise the amount of backtracking it might have to do. With Pidgin, backtracking is disabled by default; it’s enabled by the <code>Try</code> function.</p>
<h2 id="handling-tokens-and-whitespace"><a href="#handling-tokens-and-whitespace">Handling Tokens and Whitespace</a></h2>
<p>Let’s start with the basics and build upwards. Prolog is a <em>whitespace-insensitive</em> language, so we need a way to skip over the whitespace in the source code. We’ll use a convention where each component <code>Parser</code> will consume any whitespace <em>after</em> parsing any relevant non-whitespace characters.</p>
<p>Here’s a method which creates a <code>Parser</code> which consumes a specific character, skips over any whitespace, and then returns the original character.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">char</span><span class="op">&gt;</span> <span class="fu">Tok</span><span class="op">(</span><span class="dt">char</span> value<span class="op">)</span>  <span class="co">// for &quot;token&quot;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">Char</span><span class="op">(</span>value<span class="op">).</span><span class="fu">Before</span><span class="op">(</span>SkipWhitespaces<span class="op">);</span></span></code></pre></div><p>(<code>Char</code> comes from the <code>Pidgin.Parser</code> static class; all of today’s code is in a file with <code>using static Pidgin.Parser</code> and <code>using static Pidgin.Parser&lt;char&gt;</code> at the top.) <code>Char</code> is a parser which matches a specific character; <code>SkipWhitespaces</code> greedily consumes and discards a sequence of whitespace characters; and <code>Before</code> glues two parsers together sequentially, keeping only the result of the first one. So <code>Tok('(')</code> will match the input strings <code>&quot;(&quot;</code> and <code>&quot;(    &quot;</code> but not <code>&quot; (&quot;</code> or <code>&quot;)&quot;</code>.</p>
<p>Here’s an equivalent parser for a specific string:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> <span class="fu">Tok</span><span class="op">(</span><span class="dt">string</span> value<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">Try</span><span class="op">(</span><span class="fu">String</span><span class="op">(</span>value<span class="op">)).</span><span class="fu">Before</span><span class="op">(</span>SkipWhitespaces<span class="op">);</span></span></code></pre></div><p>Why am I using the <em>backtracking</em> function <code>Try</code> here? Remember, a parser consumes its input one character at a time, and makes decisions based only on the current character. If the first character of the input looks like it matches <code>value</code>, Pidgin will commit to running the <code>String(value)</code> parser; if matching the string fails after the first character then the parser needs to return to where it was so that it can try any alternative ways to parse from that location.</p>
<p>For an example of why we need <code>Try</code>, consider the parser <code>String(&quot;prolog&quot;).Or(String(&quot;programming&quot;))</code>. <code>Or</code> is Pidgin’s <em>choice</em> function — it attempts to run one parser, and falls back on the other one if the first parser failed without consuming any input. Here’s our parser represented pictorally:</p>
<pre><code>             +--Or--+
             |      |
String(&quot;prolog&quot;)  String(&quot;programming&quot;)
</code></pre>
<p>Let’s think about how this parser behaves when you feed it the string <code>&quot;programming&quot;</code>. Naïvely we might expect this to succeed, because <code>String(&quot;programming&quot;)</code> is one of <code>Or</code>’s options. But in fact this parser will fail to parse the string <code>&quot;programming&quot;</code>. Looking at it step by step reveals why:</p>
<p>At the start of the parsing process, the current character is the first letter, namely <code>p</code>.</p>
<pre>
<b>p</b> r o g r a m m i n g
</pre>
<p>Our <code>Or</code> parser will try to apply the <code>prolog</code> parser first. The <code>prolog</code> parser looks at the current character and says “This looks like the start of <code>prolog</code> to me. I’ll consume it.”</p>
<pre>
p <b>r</b> o g r a m m i n g
</pre>
<p>This continues for a couple more characters.</p>
<pre>
p r <b>o</b> g r a m m i n g
p r o <b>g</b> r a m m i n g
</pre>
<p>Now that we’re looking at a <code>g</code>, it’s clear that the input doesn’t match the string <code>prolog</code>. The <code>prolog</code> parser fails and yields control back to <code>Or</code>. Because the <code>prolog</code> parser consumed input and did not backtrack, <code>Or</code> will not attempt to apply the <code>programming</code> parser. (If it did try, it would fail anyway because we’re no longer looking at a <code>p</code>.) If the <code>prolog</code> parser were wrapped in a <code>Try</code>, it would have backtracked to the <code>p</code> upon failing, allowing <code>Or</code> to fall back on the <code>programming</code> parser.</p>
<p>It’s common to use <code>Try</code> for each word and symbol in your language’s grammar; I’m going to use <code>Tok</code> for each of my low level component parsers.</p>
<p>Finally, we can generalise these <code>Tok</code> methods to run an arbitrary <code>Parser</code> with backtracking and whitespace.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> T<span class="op">&gt;</span> Tok<span class="op">&lt;</span>T<span class="op">&gt;(</span>Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> T<span class="op">&gt;</span> p<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">Try</span><span class="op">(</span>p<span class="op">).</span><span class="fu">Before</span><span class="op">(</span>SkipWhitespaces<span class="op">);</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">char</span><span class="op">&gt;</span> <span class="fu">Tok</span><span class="op">(</span><span class="dt">char</span> value<span class="op">)</span> <span class="op">=&gt;</span> <span class="fu">Tok</span><span class="op">(</span><span class="fu">Char</span><span class="op">(</span>value<span class="op">));</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> <span class="fu">Tok</span><span class="op">(</span><span class="dt">string</span> value<span class="op">)</span> <span class="op">=&gt;</span> <span class="fu">Tok</span><span class="op">(</span><span class="fu">String</span><span class="op">(</span>value<span class="op">));</span></span></code></pre></div><p>I have a half-baked plan to add this <code>Tok</code> parser, along with some other tools for handling whitespace, to the Pidgin library itself, so you don’t have to write it yourself every time you write a parser.</p>
<p>Some useful token parsers for Prolog:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">char</span><span class="op">&gt;</span> _comma <span class="op">=</span> <span class="fu">Tok</span><span class="op">(</span><span class="ch">&#39;,&#39;</span><span class="op">);</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">char</span><span class="op">&gt;</span> _openParen <span class="op">=</span> <span class="fu">Tok</span><span class="op">(</span><span class="ch">&#39;(&#39;</span><span class="op">);</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">char</span><span class="op">&gt;</span> _closeParen <span class="op">=</span> <span class="fu">Tok</span><span class="op">(</span><span class="ch">&#39;)&#39;</span><span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">char</span><span class="op">&gt;</span> _dot <span class="op">=</span> <span class="fu">Tok</span><span class="op">(</span><span class="ch">&#39;.&#39;</span><span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> _colonDash <span class="op">=</span> <span class="fu">Tok</span><span class="op">(</span><span class="st">&quot;:-&quot;</span><span class="op">);</span></span></code></pre></div><h2 id="names"><a href="#names">Names</a></h2>
<p>Prolog has two types of names — <em>atoms</em> start with a lowercase letter and <em>variables</em> start with an uppercase letter or an underscore.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> _atomName <span class="op">=</span> <span class="fu">Tok</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    from first <span class="kw">in</span> Lowercase</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// OneOf is like Or, but it works with more than two parsers</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    from rest <span class="kw">in</span> <span class="fu">OneOf</span><span class="op">(</span>Letter<span class="op">,</span> Digit<span class="op">,</span> <span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;_&#39;</span><span class="op">)).</span><span class="fu">ManyString</span><span class="op">()</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    select first <span class="op">+</span> rest</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> _variableName <span class="op">=</span> <span class="fu">Tok</span><span class="op">(</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    from first <span class="kw">in</span> Uppercase<span class="op">.</span><span class="fu">Or</span><span class="op">(</span><span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;_&#39;</span><span class="op">))</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    from rest <span class="kw">in</span> <span class="fu">OneOf</span><span class="op">(</span>Letter<span class="op">,</span> Digit<span class="op">,</span> <span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;_&#39;</span><span class="op">)).</span><span class="fu">ManyString</span><span class="op">()</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    select first <span class="op">+</span> rest</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">);</span></span></code></pre></div><p>One of the fun things about C#’s <code>from...select</code> syntax is that it’s <a href="https://en.wikipedia.org/wiki/Duck_typing"><em>duck-typed</em></a>. The C# compiler allows you to use <code>from...select</code> with any object which has eligible <code>Select</code> and <code>SelectMany</code> methods, not just <code>IEnumerable</code>. Pidgin allows you to (ab)use this notation to sequence parsers — <code>from x in p1 from y in p2 select f(x, y)</code> is equivalent to <code>p1.Then(p2, (x,y) =&gt; f(x,y))</code>. So when you see a parser defined using <code>from...select</code> you should read it from top to bottom as a script.</p>
<p><code>ManyString</code> takes a parser and greedily runs it in a loop, then packs all of that parser’s results into a string. <code>Uppercase</code>, <code>Lowercase</code>, <code>Letter</code> and <code>Digit</code> all consume and return a single character of their respective types.</p>
<p>So, taken as a whole, <code>_atomName</code> consumes and returns a string as long as it’s a valid Prolog atom. Here’s how it works:</p>
<ol>
<li>Consume a lowercase character and name it <code>first</code>
</li>
<li>Consume as many letters, digits and underscores as possible, naming the resulting string <code>rest</code>
</li>
<li>Skip any whitespace coming after the name (that’s what <code>Tok</code> does)
</li>
<li>Return the string <code>first + rest</code>
</li>
</ol>
<p><code>_variableName</code> works just the same, except in step 1 it consumes an uppercase letter or an underscore. Let’s de-duplicate them:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> <span class="fu">Name</span><span class="op">(</span>Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">char</span><span class="op">&gt;</span> firstLetter<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">Tok</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        from first <span class="kw">in</span> firstLetter</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        from rest <span class="kw">in</span> <span class="fu">OneOf</span><span class="op">(</span>Letter<span class="op">,</span> Digit<span class="op">,</span> <span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;_&#39;</span><span class="op">)).</span><span class="fu">ManyString</span><span class="op">()</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        select first <span class="op">+</span> rest</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><h2 id="terms"><a href="#terms">Terms</a></h2>
<p>Terms in Prolog have a recursive structure, as <a href="/posts/2019-12-01-write-you-a-prolog.html">discussed previously</a>. A predicate’s arguments can be any term, including another predicate. This circularity poses a problem for our parser code — the <code>_predicate</code> parser needs to call <code>_term</code>, but <code>_term</code> needs to call <code>_predicate</code>, so what order can you put the declarations in?</p>
<p>Pidgin’s built-in <code>Rec</code> function enables forward references like this. The idea is to use a lambda to delay the access to the field until after it’s been initialised.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> Term<span class="op">&gt;</span> _term <span class="op">=</span> <span class="fu">Rec</span><span class="op">(()</span> <span class="op">=&gt;</span> <span class="fu">OneOf</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    _variable<span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// upcast the Parser&lt;char, Predicate&gt; into a Parser&lt;char, Term&gt;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    _predicate<span class="op">.</span><span class="fu">Cast</span><span class="op">&lt;</span>Term<span class="op">&gt;(),</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    _atom</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">)).</span><span class="fu">Labelled</span><span class="op">(</span><span class="st">&quot;term&quot;</span><span class="op">);</span></span></code></pre></div><p><code>_predicate</code> is textually below <code>_term</code>, so when <code>_term</code> is initialised <code>_predicate</code> will be <code>null</code>. By putting the <code>_predicate</code> reference inside a lambda and passing it to <code>Rec</code>, we can prevent <code>_predicate</code> from being accessed until after it’s been initialised. (<code>Rec</code> returns a parser which calls the lambda the first time it’s run.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> Term<span class="op">&gt;</span> _atom</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=</span> <span class="fu">Name</span><span class="op">(</span>Lowercase<span class="op">)</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>name <span class="op">=&gt;</span> <span class="op">(</span>Term<span class="op">)</span><span class="kw">new</span> <span class="fu">Atom</span><span class="op">(</span>name<span class="op">))</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Labelled</span><span class="op">(</span><span class="st">&quot;atom&quot;</span><span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> Term<span class="op">&gt;</span> _variable</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">=</span> <span class="fu">Name</span><span class="op">(</span>Uppercase<span class="op">.</span><span class="fu">Or</span><span class="op">(</span><span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;_&#39;</span><span class="op">)))</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>name <span class="op">=&gt;</span> <span class="op">(</span>Term<span class="op">)</span><span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span>name<span class="op">))</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Labelled</span><span class="op">(</span><span class="st">&quot;variable&quot;</span><span class="op">);</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> Predicate<span class="op">&gt;</span> _predicate <span class="op">=</span> <span class="op">(</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    from name <span class="kw">in</span> <span class="fu">Try</span><span class="op">(</span><span class="fu">Name</span><span class="op">(</span>Lowercase<span class="op">).</span><span class="fu">Before</span><span class="op">(</span>_openParen<span class="op">))</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    from args <span class="kw">in</span> <span class="fu">CommaSeparated</span><span class="op">(</span>_term<span class="op">).</span><span class="fu">Before</span><span class="op">(</span>_closeParen<span class="op">)</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    select <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span>name<span class="op">,</span> args<span class="op">)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">).</span><span class="fu">Labelled</span><span class="op">(</span><span class="st">&quot;predicate&quot;</span><span class="op">);</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> ImmutableArray<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span> CommaSeparated<span class="op">&lt;</span>T<span class="op">&gt;(</span>Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> T<span class="op">&gt;</span> p<span class="op">)</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> p<span class="op">.</span><span class="fu">Separated</span><span class="op">(</span>_comma<span class="op">).</span><span class="fu">Select</span><span class="op">(</span>x <span class="op">=&gt;</span> x<span class="op">.</span><span class="fu">ToImmutableArray</span><span class="op">());</span></span></code></pre></div><p>I’m using <code>Try</code> again in the <code>_predicate</code> parser. This is to disambiguate predicates from atoms. Both start in the same way (a lowercase letter) and you can’t be sure you’re parsing a predicate until you see a parenthesis. So our <code>_term</code> parser first attempts to read a predicate, but if it doesn’t see a parenthesis then it backtracks and reads the name as an atom instead. The order of <code>OneOf</code>’s arguments matters!</p>
<h2 id="rules-queries-and-whole-programs"><a href="#rules-queries-and-whole-programs">Rules, Queries and Whole Programs</a></h2>
<p>We’re on the home straight. A Prolog program consists of a collection of top-level <em>rules</em> and <em>facts</em>. A rule consists of a predicate followed by the symbol <code>:-</code> and a comma-separated list of predicates, and ends with a <code>.</code> symbol. A fact is just a rule with no right-hand side.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> Rule<span class="op">&gt;</span> _rule</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=</span> <span class="fu">Map</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="op">(</span>head<span class="op">,</span> body<span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">Rule</span><span class="op">(</span>head<span class="op">,</span> body<span class="op">),</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        _predicate<span class="op">,</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        _colonDash</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Then</span><span class="op">(</span><span class="fu">CommaSeparatedAtLeastOnce</span><span class="op">(</span>_predicate<span class="op">))</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Or</span><span class="op">(</span><span class="fu">Return</span><span class="op">(</span>ImmutableArray<span class="op">&lt;</span>Predicate<span class="op">&gt;.</span><span class="fu">Empty</span><span class="op">))</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">Before</span><span class="op">(</span>_dot<span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span><span class="fu">Labelled</span><span class="op">(</span><span class="st">&quot;rule&quot;</span><span class="op">);</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> ImmutableArray<span class="op">&lt;</span>T<span class="op">&gt;&gt;</span> CommaSeparatedAtLeastOnce<span class="op">&lt;</span>T<span class="op">&gt;(</span>Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> T<span class="op">&gt;</span> p<span class="op">)</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> p<span class="op">.</span><span class="fu">SeparatedAtLeastOnce</span><span class="op">(</span>_comma<span class="op">).</span><span class="fu">Select</span><span class="op">(</span>x <span class="op">=&gt;</span> x<span class="op">.</span><span class="fu">ToImmutableArray</span><span class="op">());</span></span></code></pre></div><p>(<code>Map</code> is another way of writing <code>Then</code>; <code>Return</code> is a parser which always returns the given value without touching the input string.) Note that <code>.Or(Return(...))</code> is applied to the result of <code>_colonDash.Then(...)</code>. If the parser encounters the <code>:-</code> symbol then it commits to reading at least one item in the rule’s body. <code>name(args) :- .</code> is not valid Prolog; if a programmer wants a rule with no body then they have to omit the <code>:-</code>.</p>
<p>Finally, a Prolog program consists of a sequence of rules. We’re also going to need a parser for individual queries typed at the interactive prompt.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> ImmutableArray<span class="op">&lt;</span>Rule<span class="op">&gt;&gt;</span> _program <span class="op">=</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    from _ <span class="kw">in</span> SkipWhitespaces</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    from rules <span class="kw">in</span> _rule<span class="op">.</span><span class="fu">Many</span><span class="op">()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    select rules<span class="op">.</span><span class="fu">ToImmutableArray</span><span class="op">();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> Predicate<span class="op">&gt;</span> _query <span class="op">=</span> SkipWhitespaces<span class="op">.</span><span class="fu">Then</span><span class="op">(</span>_predicate<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> ImmutableArray<span class="op">&lt;</span>Rule<span class="op">&gt;</span> <span class="fu">ParseProgram</span><span class="op">(</span><span class="dt">string</span> input<span class="op">)</span> <span class="op">=</span> _program<span class="op">.</span><span class="fu">ParseOrThrow</span><span class="op">(</span>input<span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> Predicate <span class="fu">ParseQuery</span><span class="op">(</span><span class="dt">string</span> input<span class="op">)</span> <span class="op">=</span> _query<span class="op">.</span><span class="fu">ParseOrThrow</span><span class="op">(</span>input<span class="op">);</span></span></code></pre></div><p>Since by convention each of our component parsers has been consuming whitespaces <em>after</em> the text they match, we need to remember to <code>SkipWhitespaces</code> at the start of the file.</p>
<p>That’s our whole parser! Less than 80 lines of code is not bad, I think. A quick test of our <code>last</code> example from the previous post:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="dt">void</span> <span class="fu">Main</span><span class="op">(</span><span class="dt">string</span><span class="op">[]</span> args<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> program <span class="op">=</span> PrologParser<span class="op">.</span><span class="fu">ParseProgram</span><span class="op">(</span>@<span class="st">&quot;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="fu">last</span><span class="op">(</span><span class="fu">cons</span><span class="op">(</span>X<span class="op">,</span> nil<span class="op">),</span> X<span class="op">).</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="fu">last</span><span class="op">(</span><span class="fu">cons</span><span class="op">(</span>X<span class="op">,</span> Xs<span class="op">),</span> Y<span class="op">)</span> <span class="op">:-</span> <span class="fu">last</span><span class="op">(</span>Xs<span class="op">,</span> Y<span class="op">).</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span><span class="dt">string</span><span class="op">.</span><span class="fu">Join</span><span class="op">(</span><span class="st">&quot;</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">,</span> program<span class="op">));</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// prints out:</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// last(cons(X, nil), X).</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// last(cons(X, Xs), Y) :- last(Xs, Y).</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Here are a couple of exercises you might try:</p>
<ul>
<li>Extend this code to support numbers, building on the exercise from the end of the <a href="/posts/2019-12-01-write-you-a-prolog.html">last post</a>.
</li>
<li>Extend this code to support lists.
<ul>
<li>Prolog’s lists are linked lists; <code>[]</code> is an empty list and cons cells look like <code>[head | tail]</code>. (<code>head</code> and <code>tail</code> are both arbitrary terms; though at runtime <code>tail</code> should be a list.)
</li>
<li>At first you can try pretending that lists are syntactic sugar — desugar <code>[]</code> to a <code>nil</code> atom and <code>[head | tail]</code> to a <code>cons(head, tail)</code> predicate.
</li>
<li>How can you avoid clashing with mentions of those names in user code?
<ul>
<li>You could try mangling the names to something which can’t be typed by a user.
</li>
<li>You could try making them reserved words (adjust the parser to reject user-defined mentions of <code>cons</code> and <code>nil</code>).
</li>
<li>You could try adding lists directly to the <code>Term</code> AST.
</li>
</ul>
</li>
</ul>
</li>
<li>Try using <a href="https://www.benjamin.pizza/Pidgin/v2.2.0/api/Pidgin.Comment.CommentParser.html">Pidgin’s <code>CommentParser</code> class</a> to handle Prolog code with comments in.
</li>
</ul>
<p>You can find this code in <a href="https://github.com/benjamin-hodgson/Amateurlog">the example repo</a>, in the file <a href="https://github.com/benjamin-hodgson/Prolog/blob/master/Parser.cs"><code>Parser.cs</code></a>. Next time we’ll talk about <em>unification</em>, the core of Prolog’s bi-directional programming model. We’ll be using <a href="https://github.com/benjamin-hodgson/Sawmill">Sawmill</a> to implement unification <em>generically</em>, without making any assumptions about Prolog’s syntax.</p>

]]></summary>
</entry>
<entry>
    <title>Write You a Prolog</title>
    <link href="http://www.benjamin.pizza/posts/2019-12-01-write-you-a-prolog.html" />
    <id>http://www.benjamin.pizza/posts/2019-12-01-write-you-a-prolog.html</id>
    <published>2019-12-01T00:00:00Z</published>
    <updated>2019-12-01T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>I figured it’d be useful to have some examples of my language tooling libraries <a href="https://github.com/benjamin-hodgson/Sawmill">Sawmill</a> and <a href="https://github.com/benjamin-hodgson/Pidgin">Pidgin</a> in action. I thought it could be fun to use them to write a miniature <a href="https://en.wikipedia.org/wiki/Prolog">Prolog</a> interpreter!</p>
<nav>
    <ol>
        <li><b>Introduction &amp; Syntax</b></li>
        <li><a href="/posts/2019-12-08-parsing-prolog-with-pidgin.html">Parsing</a></li>
        <li><a href="/posts/2019-12-15-generic-unification-with-sawmill.html">Unification</a></li>
        <li><a href="/posts/2019-12-22-building-prologs-rules-engine.html">The rules engine</a></li>
    </ol>
</nav>
<p>You’ll find all the code for this series <a href="https://github.com/benjamin-hodgson/Amateurlog">on GitHub</a>.</p>
<h2 id="whistle-stop-introduction-to-prolog"><a href="#whistle-stop-introduction-to-prolog">Whistle-Stop Introduction to Prolog</a></h2>
<p>Prolog is a <em>logic programming</em> language. Prolog code consists of a collection of <em>rules</em>. Each rule says “X is true if Y (and Z and…) is true”. A rule is a logical axiom, with a set of premises (on the right) and a conclusion you can draw from those premises (on the left).</p>
<p>As an example, you might say that a <code>Person</code> wants a certain <code>Food</code> if they’re hungry and they like that food. And — I don’t know about you — but I’ll eat something I really love even if I’m not hungry.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>wants(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>) <span class="kw">:-</span> hungry(<span class="dt">Person</span>)<span class="kw">,</span> likes(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">.</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>wants(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>) <span class="kw">:-</span> loves(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">.</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="co">% If someone loves a given food, then they also like it.</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>likes(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>) <span class="kw">:-</span> loves(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">.</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="co">% If we&#39;re going to have dinner, we&#39;d better agree on what to eat.</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>dinner(<span class="dt">Person1</span><span class="kw">,</span> <span class="dt">Person2</span><span class="kw">,</span> <span class="dt">Food</span>) <span class="kw">:-</span> wants(<span class="dt">Person1</span><span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">,</span> wants(<span class="dt">Person2</span><span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">.</span></span></code></pre></div><p>Variables in Prolog start with a capital letter. <code>:-</code> means “if” and <code>,</code> means “and”. You can give multiple alternative ways of satisfying the same predicate by just declaring it more than once. In other words, multiple declarations of the same predicate means “or”.</p>
<p>Next, we’ll prime Prolog’s database with a couple of <em>facts</em> about people and foods.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>loves(benjamin<span class="kw">,</span> pizza)<span class="kw">.</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>loves(benjamin<span class="kw">,</span> asparagus)<span class="kw">.</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>likes(benjamin<span class="kw">,</span> soup)<span class="kw">.</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>loves(clio<span class="kw">,</span> salad)<span class="kw">.</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>likes(clio<span class="kw">,</span> pizza)<span class="kw">.</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>likes(clio<span class="kw">,</span> soup)<span class="kw">.</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>hungry(clio)<span class="kw">.</span></span></code></pre></div><p><em>Atoms</em> in Prolog are somewhat like strings. They begin with a lower case letter.</p>
<p>Finally, we can issue a <em>query</em> to the interactive Prolog interpreter to find out whether we can have soup for dinner.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="fu">?-</span> dinner(benjamin<span class="kw">,</span> clio<span class="kw">,</span> soup)<span class="kw">.</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">false</span></span></code></pre></div><p>No soup for you. What <em>can</em> we eat for dinner? If we replace the atom <code>soup</code> — a specific food — with a variable <code>Food</code> (note the capital letter) — standing in for any food — Prolog will try to find a value for <code>Food</code> which satisfies the <code>dinner</code> predicate. (You can use as many variables as you like in a query. Prolog will try to find a value for all of them.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="fu">?-</span> dinner(benjamin<span class="kw">,</span> clio<span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">.</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="dt">Food</span> <span class="kw">=</span> pizza</span></code></pre></div><p>Even though predicates don’t return anything per se — they either succeed or fail — you can use variables in this way to get information out of a predicate. Prolog’s constraint solving system is <strong>bi-directional</strong> — a predicate’s parameters can serve as both inputs and outputs.</p>
<h3 id="pattern-matching-and-recursion"><a href="#pattern-matching-and-recursion">Pattern Matching and Recursion</a></h3>
<p>As well as putting <em>conditions</em> on the right-hand side of a rule, you can put <em>patterns</em> on the left. This is somewhat like pattern matching in functional languages — the right-hand side of a rule is only entered if its arguments match the pattern on the left.</p>
<p>Here’s a recursive predicate <code>last(List, Item)</code> which succeeds when <code>Item</code> is the last element of <code>List</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>last(cons(<span class="dt">X</span><span class="kw">,</span> nil)<span class="kw">,</span> <span class="dt">X</span>)<span class="kw">.</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>last(cons(<span class="dt">X</span><span class="kw">,</span> <span class="dt">Xs</span>)<span class="kw">,</span> <span class="dt">Y</span>) <span class="kw">:-</span> last(<span class="dt">Xs</span><span class="kw">,</span> <span class="dt">Y</span>)<span class="kw">.</span></span></code></pre></div><p><code>last</code> is another example of bi-directionality. You can use the second parameter as an input by passing in a value (in which case <code>last</code> will test whether <code>Item</code> is the last element of <code>List</code>), or you can use it as an output by passing in a variable (in which case Prolog will find the last element of <code>List</code> and set <code>Item</code> equal to it).</p>
<p>When running a predicate, Prolog tries each of its clauses from top to bottom to see if any of them succeed. So let’s review this code line by line.</p>
<p>The first rule has no right hand side, which means it succeeds as long as the predicate’s arguments match the pattern on the left. (Rules with no right-hand side are called <em>facts</em>.) The first argument on the left hand side is the pattern <code>cons(X, nil)</code>. <code>cons</code> is a predicate whose two arguments are the head and tail of a list (<a href="https://en.wikipedia.org/wiki/Cons">the <code>cons</code> nomenclature</a> comes from Lisp); in this instance its second argument is the atom <code>nil</code> (representing an empty list) and its first argument is left indeterminate — <code>X</code> can stand in for any element. The second argument of <code>last</code> is <code>X</code>. This is the <em>same</em> <code>X</code> as appeared in <code>cons(X, nil)</code>. So, taken all together, this first line succeeds when its first argument is a single-element list and its second argument is that element.</p>
<p>The second line of this code is only entered when the first line fails — that is, when <code>Xs</code> is not <code>nil</code>. In the pattern on the left, we’ve replaced the concrete empty list <code>nil</code> with a variable <code>Xs</code> which can stand in for any list. The right-hand side of the rule recursively calls <code>last</code>. So this line says the last item of the list <code>cons(X, Xs)</code> is <code>Y</code> when the last item of <code>Xs</code> is <code>Y</code>.</p>
<p>Prolog’s bi-directional pattern matching system works by <em>unification</em>. Unification is a process of making two terms equal by filling in their variables. When matching a goal like <code>last(cons(oranges, nil), Y)</code> to a rule head like <code>last(cons(X, nil), X)</code>, Prolog tries to find values to plug in for all the variables in scope so that the goal matches the rule. In this case, it’d determine that <code>X</code> and <code>Y</code> should both be <code>oranges</code>. I’ll talk about unification in much more detail in a later post.</p>
<p>It’s instructive to work through an example query: <code>last(cons(apples, cons(oranges, nil)), oranges)</code>.</p>
<ol>
<li>Prolog first tries the top clause. It tries to unify the goal with <code>last(cons(X, nil), X)</code>. This fails because there’s no value for <code>X</code> which makes this match the goal. In other words, there’s one too many elements in the list for this clause to match.
</li>
<li>Now it tries the second rule. Prolog tries to unify the goal with <code>last(cons(X, Xs), Y)</code>. This succeeds — the terms match when <code>X = apples</code>, <code>Xs = cons(oranges, nil)</code>, and <code>Y = oranges</code>. So now Prolog creates a sub-goal for each clause on the right, of which there’s only one (<code>last(Xs, Y)</code>). Since <code>Xs = cons(oranges, nil)</code> and <code>Y = oranges</code>, the goal is <code>last(cons(oranges, nil), oranges)</code>. So now the code has to recursively call <code>last</code>.
</li>
<li>With this new goal we try the first clause again. Prolog tries to unify <code>last(cons(oranges, nil), oranges)</code> with <code>last(cons(X, nil), X)</code>. This succeeds when <code>X = oranges</code>. Since there are no conditions on the right hand side (this clause is the base case of the recursive function), we’re done! The query succeeded; <code>oranges</code> is indeed the last element of the list.
</li>
</ol>
<h2 id="representing-prolog-syntax"><a href="#representing-prolog-syntax">Representing Prolog Syntax</a></h2>
<p>Hopefully blasting through Prolog’s core in only a few paragraphs was enough to get you excited about implementing it! The first step in interpreting a programming lanugage is to come up with a way to represent programs in that language. That means writing down some types representing the language’s <em>abstract syntax tree</em>. The middle part of the diagram I drew for <a href="https://www.benjamin.pizza/posts/2017-11-13-recursion-without-recursion.html">my post announcing Sawmill</a>:</p>
<img src="/images/2017-11-13-recursion-without-recursion/compiler.jpg" alt="Compiler overview" />
<p>As the name suggests, the exercise is to come up with an abstract representation of Prolog’s syntax. Think beyond the specifics of how the language is presented as text (such as where parentheses go and so on); we want to talk about the high-level grammatical constructs and how they relate to one another. This mode of thinking is akin to thinking about English at the level of sentence structure — subordinate clauses and so on — rather than spelling and punctuation.</p>
<p>I said a Prolog program was a collection of <em>rules</em>, so let’s start there.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Rule</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ?</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>What constitutes a rule? Looking at our example from earlier,</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>wants(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>) <span class="kw">:-</span> hungry(<span class="dt">Person</span>)<span class="kw">,</span> likes(<span class="dt">Person</span><span class="kw">,</span> <span class="dt">Food</span>)<span class="kw">.</span></span></code></pre></div><p>you can see that a rule has two main parts, separated by the <code>:-</code> symbol. On the left is the <em>conclusion</em> of the logical statement, in the form of a pattern which the rule can match. On the right are the <em>premises</em> of the logical statement, in the form of a comma-separated list of calls to other predicates. We’ll call these the <code>Head</code> and the <code>Body</code> of the rule. (A fact is just a rule with no predicates in the body.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Rule</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="op">?</span> Head <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableArray<span class="op">&lt;?&gt;</span> Body <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>(I’m omitting constructors for brevity.) What should the types of these properties be? A rule’s head is always a name, followed by a comma-separated list of expressions inside parentheses. We’ll call this a <code>Predicate</code>. A rule’s body is also list of predicates.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Rule</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Predicate Head <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableArray<span class="op">&lt;</span>Predicate<span class="op">&gt;</span> Body <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Predicate</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Name <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableArray<span class="op">&lt;?&gt;</span> Args <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Now to fill in the type of <code>Args</code>. Looking at the example <code>last(cons(X, nil), X)</code>, each argument to a predicate can be one of:</p>
<ol>
<li>Another predicate applied to some arguments (<code>cons</code> in this example).
</li>
<li>A variable (<code>X</code>).
</li>
<li>An atom (<code>nil</code>).
</li>
</ol>
<p>We’ll refer to all three of these syntactic forms as <em>terms</em>. We’ll use subtyping to represent the fact that each argument could be any one of the three. <code>Predicate</code>, <code>Variable</code> and <code>Atom</code> are all subclasses of the <code>Term</code> base class; a <code>Predicate</code>’s arguments are a collection of <code>Term</code>s (but you don’t know statically what kind of <code>Term</code> to expect).</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> Term <span class="op">{}</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Predicate <span class="op">:</span> Term</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Name <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableArray<span class="op">&lt;</span>Term<span class="op">&gt;</span> Args <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Variable <span class="op">:</span> Term</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Name <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Atom <span class="op">:</span> Term</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Value <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>That’s our whole abstract syntax! Here’s how our <code>last(cons(X, Xs), Y) :- last(Xs, Y)</code> example would be represented:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">new</span> <span class="fu">Rule</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    head<span class="op">:</span> <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        name<span class="op">:</span> <span class="st">&quot;last&quot;</span><span class="op">,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        args<span class="op">:</span> <span class="kw">new</span><span class="op">[]</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span><span class="st">&quot;cons&quot;</span><span class="op">,</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;X&quot;</span><span class="op">),</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Xs&quot;</span><span class="op">)</span> <span class="op">}),</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Y&quot;</span><span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">),</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    body<span class="op">:</span> <span class="kw">new</span><span class="op">[]</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span><span class="st">&quot;last&quot;</span><span class="op">,</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Xs&quot;</span><span class="op">),</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Y&quot;</span><span class="op">)</span> <span class="op">})</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div><img src="/images/2019-12-01-write-you-a-prolog/anatomy.png" alt="Anatomy of a Rule" />
<p>Prolog’s rules engine is based entirely on manipulating terms, so these three classes will turn out to be quite important in our little interpreter.</p>
<h2 id="implementing-irewritable"><a href="#implementing-irewritable">Implementing <code>IRewritable</code></a></h2>
<p><code>Term</code> is an immutable type with a recursive tree-shaped structure — a predicate’s arguments can be any <code>Term</code>, including more predicates. My generic programming library <a href="https://github.com/benjamin-hodgson/Sawmill">Sawmill</a> is filled with tools for working with immutable trees! As a Sawmill user, you implement its core <code>IRewritable</code> interface on your tree structure, and Sawmill takes care of much of the boilerplate of traversing the tree for you. (See <a href="https://www.benjamin.pizza/posts/2017-11-13-recursion-without-recursion.html">my earlier post</a> for an introduction to Sawmill.)</p>
<p><code>IRewritable</code> is all about addressing the immediate children of the current node in a tree. It has three methods, <code>CountChildren</code>, <code>GetChildren</code>, and <code>SetChildren</code>, which we have to implement for each subclass of our <code>Term</code> tree. Variables and atoms don’t have child terms — only predicates.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> Term <span class="op">:</span> IRewritable<span class="op">&lt;</span>Term<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">abstract</span> <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">abstract</span> <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>Span<span class="op">&lt;</span>Term<span class="op">&gt;</span> childrenReceiver<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">abstract</span> Term <span class="fu">SetChildren</span><span class="op">(</span>ReadOnlySpan<span class="op">&lt;</span>Term<span class="op">&gt;</span> newChildren<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Predicate <span class="op">:</span> Term</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">()</span> <span class="op">=&gt;</span> Args<span class="op">.</span><span class="fu">Length</span><span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>Span<span class="op">&lt;</span>Term<span class="op">&gt;</span> childrenReceiver<span class="op">)</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        Args<span class="op">.</span><span class="fu">CopyTo</span><span class="op">(</span>childrenReceiver<span class="op">);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> Term <span class="fu">SetChildren</span><span class="op">(</span>ReadOnlySpan<span class="op">&lt;</span>Term<span class="op">&gt;</span> newChildren<span class="op">)</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span>Name<span class="op">,</span> newChildren<span class="op">.</span><span class="fu">ToImmutableArray</span><span class="op">());</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Variable <span class="op">:</span> Term</span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">()</span> <span class="op">=&gt;</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>Span<span class="op">&lt;</span>Term<span class="op">&gt;</span> childrenReceiver<span class="op">)</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> Term <span class="fu">SetChildren</span><span class="op">(</span>ReadOnlySpan<span class="op">&lt;</span>Term<span class="op">&gt;</span> newChildren<span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">this</span><span class="op">;</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Atom <span class="op">:</span> Term</span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">()</span> <span class="op">=&gt;</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>Span<span class="op">&lt;</span>Term<span class="op">&gt;</span> childrenReceiver<span class="op">)</span> <span class="op">{</span> <span class="op">}</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> Term <span class="fu">SetChildren</span><span class="op">(</span>ReadOnlySpan<span class="op">&lt;</span>Term<span class="op">&gt;</span> newChildren<span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">this</span><span class="op">;</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>We can now use Sawmill’s stock traversals like <code>SelfAndDescendants</code> and <code>Rewrite</code> to work with terms. For example, here’s a method which finds all of the variables mentioned in a term.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> IEnumerable<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> <span class="fu">Variables</span><span class="op">(</span><span class="kw">this</span> Term term<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> term</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">SelfAndDescendants</span><span class="op">()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">OfType</span><span class="op">&lt;</span>Variable<span class="op">&gt;()</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>v <span class="op">=&gt;</span> v<span class="op">.</span><span class="fu">Name</span><span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Distinct</span><span class="op">();</span></span></code></pre></div><p>Here’s a method which writes out a term as a string (and a corresponding one for <code>Rule</code>s).</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> Term</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">string</span> <span class="fu">ToString</span><span class="op">()</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">this</span><span class="op">.</span><span class="fu">Fold</span><span class="op">&lt;</span>Term<span class="op">,</span> <span class="dt">string</span><span class="op">&gt;((</span>childStrings<span class="op">,</span> x<span class="op">)</span> <span class="op">=&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">switch</span> <span class="op">(</span>x<span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> Predicate p<span class="op">:</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> p<span class="op">.</span><span class="fu">Name</span> <span class="op">+</span> <span class="st">&quot;(&quot;</span> <span class="op">+</span> <span class="dt">string</span><span class="op">.</span><span class="fu">Join</span><span class="op">(</span><span class="st">&quot;, &quot;</span><span class="op">,</span> childStrings<span class="op">.</span><span class="fu">ToArray</span><span class="op">())</span> <span class="op">+</span> <span class="st">&quot;)&quot;</span><span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> Variable v<span class="op">:</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> v<span class="op">.</span><span class="fu">Name</span><span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> Atom a<span class="op">:</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> a<span class="op">.</span><span class="fu">Value</span><span class="op">;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                <span class="kw">default</span><span class="op">:</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">Exception</span><span class="op">(</span><span class="st">&quot;unknown term&quot;</span><span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        <span class="op">});</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Rule</span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> <span class="dt">string</span> <span class="fu">ToString</span><span class="op">()</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> Head <span class="op">+</span> <span class="op">(</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>            Body<span class="op">.</span><span class="fu">Length</span> <span class="op">==</span> <span class="dv">0</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>                <span class="op">?</span> <span class="st">&quot;&quot;</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>                <span class="op">:</span> <span class="st">&quot; :- &quot;</span> <span class="op">+</span> <span class="dt">string</span><span class="op">.</span><span class="fu">Join</span><span class="op">(</span><span class="st">&quot;, &quot;</span><span class="op">,</span> Body<span class="op">.</span><span class="fu">Select</span><span class="op">(</span>x <span class="op">=&gt;</span> x<span class="op">.</span><span class="fu">ToString</span><span class="op">()))</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>        <span class="op">)</span> <span class="op">+</span> <span class="st">&quot;.&quot;</span><span class="op">;</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>As an exercise, you could try extending this abstract syntax (and <code>ToString</code>) to support numbers.</p>
<p>And a quick test of our <code>last</code> example:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="dt">void</span> <span class="fu">Main</span><span class="op">(</span><span class="dt">string</span><span class="op">[]</span> args<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> rule <span class="op">=</span> <span class="kw">new</span> <span class="fu">Rule</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        head<span class="op">:</span> <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            name<span class="op">:</span> <span class="st">&quot;last&quot;</span><span class="op">,</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            args<span class="op">:</span> <span class="kw">new</span><span class="op">[]</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span><span class="st">&quot;cons&quot;</span><span class="op">,</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;X&quot;</span><span class="op">),</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Xs&quot;</span><span class="op">)</span> <span class="op">}),</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>                <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Y&quot;</span><span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">),</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        body<span class="op">:</span> <span class="kw">new</span><span class="op">[]</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span> <span class="fu">Predicate</span><span class="op">(</span><span class="st">&quot;last&quot;</span><span class="op">,</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Xs&quot;</span><span class="op">),</span> <span class="kw">new</span> <span class="fu">Variable</span><span class="op">(</span><span class="st">&quot;Y&quot;</span><span class="op">)</span> <span class="op">})</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span>rule<span class="op">.</span><span class="fu">ToString</span><span class="op">());</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="co">// prints out last(cons(X, Xs), Y) :- last(Xs, Y).</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>You can find these AST classes in <a href="https://github.com/benjamin-hodgson/Amateurlog">the example repo</a>, in the file <a href="https://github.com/benjamin-hodgson/Prolog/blob/master/Syntax.cs"><code>Syntax.cs</code></a>. <a href="/posts/2019-12-08-parsing-prolog-with-pidgin.html">Next time</a> we’ll write a parser!</p>

]]></summary>
</entry>
<entry>
    <title>Rewriting IRewritable</title>
    <link href="http://www.benjamin.pizza/posts/2019-10-05-rewriting-irewritable.html" />
    <id>http://www.benjamin.pizza/posts/2019-10-05-rewriting-irewritable.html</id>
    <published>2019-10-05T00:00:00Z</published>
    <updated>2019-10-05T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<blockquote>
<p><em>I got married yesterday! This post is about my C# generic programming library <a href="https://github.com/benjamin-hodgson/Sawmill">Sawmill</a>. Have a read of <a href="/posts/2017-11-13-recursion-without-recursion.html">my earlier post</a> for an introduction.</em></p>
</blockquote>
<h2 id="how-things-were"><a href="#how-things-were">How things were</a></h2>
<p>I recently made a substantial change to Sawmill’s core <code>IRewritable</code> interface. Here’s what it used to look like:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Children<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">SetChildren</span><span class="op">(</span>Children<span class="op">&lt;</span>T<span class="op">&gt;</span> newChildren<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">RewriteChildren</span><span class="op">(</span>Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>It’s a pleasingly simple interface with two core operations — <code>GetChildren</code> returns the current object’s immediate children and <code>SetChildren</code> replaces them. But there are also some warts.</p>
<h3 id="wart-1-childrent"><a href="#wart-1-childrent">Wart 1: <code>Children&lt;T&gt;</code></a></h3>
<p><code>Children&lt;T&gt;</code> is a custom struct, not a standard collection type:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Children<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> NumberOfChildren NumberOfChildren <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T First <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Second <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableList<span class="op">&lt;</span>T<span class="op">&gt;</span> Many <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="kw">enum</span> NumberOfChildren</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    None<span class="op">,</span> One<span class="op">,</span> Two<span class="op">,</span> Many</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>I wanted to avoid boxing when the object has a small number of children (which is fairly common in practice). So <code>GetChildren</code> returns a <code>Children&lt;T&gt;</code>, passing up to two children on the stack and the rest in an <code>ImmutableList</code>. The <code>NumberOfChildren</code> property tells the library how many of the struct’s fields are filled in.</p>
<p>This custom collection type is an extra hurdle to understanding <code>IRewritable</code>’s API. It also makes certain parts of Sawmill’s implementation more complex — many internal methods have to <code>switch</code> on the <code>NumberOfChildren</code> they’re working with and do the same work in four different ways. It’s also relatively large for a <code>struct</code> (at least 16 bytes and probably more, depending on your processor architecture) so there is a marginal performance cost associated with copying it around.</p>
<h3 id="wart-2-collections"><a href="#wart-2-collections">Wart 2: Collections</a></h3>
<p>In fact, having <code>GetChildren</code> return a collection at all is problematic, because it forces implementations to allocate memory. If your object has three or more children (and they’re not already stored in an <code>ImmutableList</code>) then you have to create a new <code>ImmutableList</code> whenever <code>GetChildren</code> is called:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> ThreeChildren <span class="op">:</span> IRewritable<span class="op">&lt;</span>ThreeChildren<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> ThreeChildren _child1<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> ThreeChildren _child2<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> ThreeChildren _child3<span class="op">;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Children<span class="op">&lt;</span>ThreeChildren<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">()</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> Children<span class="op">&lt;</span>ThreeChildren<span class="op">&gt;(</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            Children<span class="op">.</span><span class="fu">Many</span><span class="op">,</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            ImmutableList<span class="op">.</span><span class="fu">Create</span><span class="op">(</span>_child1<span class="op">,</span> _child2<span class="op">,</span> _child3<span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ThreeChildren <span class="fu">SetChildren</span><span class="op">(</span>Children<span class="op">&lt;</span>ThreeChildren<span class="op">&gt;</span> newChildren<span class="op">)</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">ThreeChildren</span><span class="op">(</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            newChildren<span class="op">.</span><span class="fu">Many</span><span class="op">[</span><span class="dv">0</span><span class="op">],</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            newChildren<span class="op">.</span><span class="fu">Many</span><span class="op">[</span><span class="dv">1</span><span class="op">],</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            newChildren<span class="op">.</span><span class="fu">Many</span><span class="op">[</span><span class="dv">2</span><span class="op">]</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="op">);</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>When Sawmill traverses a tree it typically calls <code>GetChildren()</code> for every node in the tree. That’s a lot of throwaway <code>ImmutableList</code>s!</p>
<p>One way to avoid creating all this garbage might be to redesign <code>IRewritable</code> to be buffer-oriented.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>T<span class="op">[]</span> buffer<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">SetChildren</span><span class="op">(</span>T<span class="op">[]</span> newChildren<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>With this design, Sawmill passes an array into <code>GetChildren</code> (after calling <code>CountChildren</code> to find out how big the array needs to be) and asks the object to copy its children into the array. Implementations of <code>IRewritable</code> no longer have to allocate memory for their return value. The memory is allocated (and hopefully reused) by the library. But this API is less safe — if an <code>IRewritable</code> implementation stores a reference to the buffer then it could get unexpectedly mutated.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Bad <span class="op">:</span> IRewritable<span class="op">&lt;</span>Bad<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> Bad<span class="op">[]</span> _children<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">()</span> <span class="op">=&gt;</span> _children<span class="op">.</span><span class="fu">Length</span><span class="op">;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>Bad<span class="op">[]</span> buffer<span class="op">)</span> <span class="op">=&gt;</span> _children<span class="op">.</span><span class="fu">CopyTo</span><span class="op">(</span>buffer<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Bad <span class="fu">SetChildren</span><span class="op">(</span>Bad<span class="op">[]</span> newChildren<span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">Bad</span><span class="op">(</span>newChildren<span class="op">);</span>  <span class="co">// </span><span class="al">BUG</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>This is not a “pit of success” API — <code>SetChildren</code> looks sensible but could go wrong if anyone else has a reference to the array. Sawmill would have to allocate a new array for each <code>GetChildren</code>/<code>SetChildren</code> call in order to be safe. So this design would end up allocating just as much as the <code>ImmutableList</code> version.</p>
<p>(Keep the buffer idea in your head, though, because we’ll be coming back to it in a minute.)</p>
<h3 id="wart-3-rewritechildren"><a href="#wart-3-rewritechildren">Wart 3: <code>RewriteChildren</code></a></h3>
<p><code>RewriteChildren</code>, which applies a transformation function to the object’s immediate children (in other words, a one-level <code>Rewrite</code>), has a sensible implementation in terms of the other two methods: get the children, transform them, and put them back.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> T DefaultRewriteChildren<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T value<span class="op">,</span> Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> children <span class="op">=</span> value<span class="op">.</span><span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> newChildren <span class="op">=</span> children<span class="op">.</span><span class="fu">Select</span><span class="op">(</span>transformer<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> value<span class="op">.</span><span class="fu">SetChildren</span><span class="op">(</span>newChildren<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>(<a href="https://github.com/benjamin-hodgson/Sawmill/blob/87aea1e5757360b99457c8e2e6a7993fc2176f23/Sawmill/Rewriter.DefaultRewriteChildren.cs">The real <code>DefaultRewriteChildren</code></a> was a bit more complex than this, because it tried to avoid calling <code>SetChildren</code> if <code>transformer</code> didn’t actually change anything.)</p>
<p>In fact, I expect that most <code>IRewritable</code>s would just delegate <code>RewriteChildren</code> to <code>DefaultRewriteChildren</code>. So why did I put <code>RewriteChildren</code> on the interface? It’s because of Wart 2 — <code>GetChildren</code> can be expensive because it might have to create an <code>ImmutableList</code>. (And applying <code>transformer</code> to that <code>ImmutableList</code> using eg <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablelist-1.convertall?view=netcore-3.0"><code>ConvertAll</code></a> would have to create another one.) So <code>DefaultRewriteChildren</code> is slow; the idea of <code>RewriteChildren</code> was for objects to transform their children directly, without going via an <code>ImmutableList</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> ThreeChildren <span class="op">:</span> IRewritable<span class="op">&lt;</span>ThreeChildren<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ThreeChildren <span class="fu">RewriteChildren</span><span class="op">(</span>Func<span class="op">&lt;</span>ThreeChildren<span class="op">,</span> ThreeChildren<span class="op">&gt;</span> f<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">ThreeChildren</span><span class="op">(</span><span class="fu">f</span><span class="op">(</span>_child1<span class="op">),</span> <span class="fu">f</span><span class="op">(</span>_child2<span class="op">),</span> <span class="fu">f</span><span class="op">(</span>_child3<span class="op">));</span>  <span class="co">// no ImmutableList</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>The extra method makes <code>IRewritable</code> harder to understand and harder to implement. Implementing <code>RewriteChildren</code> (without using <code>DefaultRewriteChildren</code>) can be tricky; if the transformer function doesn’t change anything you should avoid recreating the object.</p>
<h2 id="the-new-way"><a href="#the-new-way">The new way</a></h2>
<p>I’m pleased to say that <code>IRewritable</code>’s new design addresses all three of these warts. Remember the “buffer” idea from earlier?</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="fu">CountChildren</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">GetChildren</span><span class="op">(</span>Span<span class="op">&lt;</span>T<span class="op">&gt;</span> buffer<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">SetChildren</span><span class="op">(</span>ReadOnlySpan<span class="op">&lt;</span>T<span class="op">&gt;</span> newChildren<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>This design is almost identical to the one I outlined earlier — it uses <a href="https://docs.microsoft.com/en-us/dotnet/api/system.span-1?view=netcore-3.0"><code>Span</code></a>s instead of arrays. (For the uninitiated, a <code>Span</code> is basically a “slice” of an array. It can also be backed by <em>unmanaged</em> memory, though, making it more flexible than <code>ArraySegment</code>.)</p>
<ul>
<li><code>CountChildren</code> tells Sawmill how much space is needed to copy the children.
</li>
<li><code>GetChildren</code> copies the current object’s immediate children into <code>buffer</code>.
</li>
<li><code>SetChildren</code> creates a copy of the current object with its immediate children replaced.
</li>
</ul>
<p>Here’s the important difference. Unlike an array, a <code>Span</code> <em>can’t be stored on the heap</em>. <code>Span</code> is defined using <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref?view=netcore-3.0#ref-struct-types">the <code>ref</code> keyword</a>, which tells the compiler to check that <code>Span</code>s are confined to the stack. If you pass a <code>Span</code> into a method as an argument, you can be confident that the <code>Span</code> won’t leave the scope of that method’s stack frame (just like <code>ref</code>).</p>
<p>So <code>Span</code> thoroughly solves the safety issue with the array-oriented API. I don’t have to worry about mutating a <code>Span</code> which got stored inside a client object, because the <code>Span</code> can’t be stored! This allows Sawmill to safely reuse the memory behind a <code>Span</code>, rather than allocating a new array for each <code>GetChildren</code>/<code>SetChildren</code> call.</p>
<p>So Sawmill’s methods like <code>RewriteChildren</code> can be implemented without allocating memory. In this example I’m using <a href="https://docs.microsoft.com/en-us/dotnet/api/system.buffers.arraypool-1?view=netcore-3.0"><code>ArrayPool</code></a> to avoid creating a new array for every <code>RewriteChildren</code> call.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> T RewriteChildren<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T value<span class="op">,</span> Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> count <span class="op">=</span> value<span class="op">.</span><span class="fu">CountChildren</span><span class="op">();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> array <span class="op">=</span> ArrayPool<span class="op">&lt;</span>T<span class="op">&gt;.</span><span class="fu">Shared</span><span class="op">.</span><span class="fu">Rent</span><span class="op">(</span>count<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ArrayPool can return arrays bigger than you asked for</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> span <span class="op">=</span> array<span class="op">.</span><span class="fu">AsSpan</span><span class="op">().</span><span class="fu">Slice</span><span class="op">(</span>count<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    value<span class="op">.</span><span class="fu">GetChildren</span><span class="op">(</span>span<span class="op">);</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">for</span> <span class="op">(</span><span class="dt">var</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> span<span class="op">.</span><span class="fu">Length</span><span class="op">;</span> i<span class="op">++)</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        span<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> <span class="fu">transformer</span><span class="op">(</span>span<span class="op">[</span>i<span class="op">]);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> result <span class="op">=</span> value<span class="op">.</span><span class="fu">SetChildren</span><span class="op">(</span>newChildren<span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    ArrayPool<span class="op">&lt;</span>T<span class="op">&gt;.</span><span class="fu">Shared</span><span class="op">.</span><span class="fu">Return</span><span class="op">(</span>array<span class="op">);</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> result<span class="op">;</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>The main reason for having <code>RewriteChildren</code> be a method on the interface was to avoid allocating memory (for the <code>GetChildren</code> calls). So we don’t need it on the interface any more — this extension method serves as a single universal implementation. Likewise, <code>Children&lt;T&gt;</code>’s purpose was also to avoid allocating memory, so we can do away with it too.</p>
<h2 id="relieving-arraypool-pressure"><a href="#relieving-arraypool-pressure">Relieving <code>ArrayPool</code> pressure</a></h2>
<p>There’s one operational problem with this implementation: it can end up renting a large number of arrays from the pool. <code>Rewrite</code>, which applies a transformation function to every node in a tree (not just one layer), is implemented something like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> T <span class="fu">Rewrite</span><span class="op">(</span><span class="kw">this</span> T value<span class="op">,</span> Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">transformer</span><span class="op">(</span>t<span class="op">.</span><span class="fu">RewriteChildren</span><span class="op">(</span>child <span class="op">=&gt;</span> child<span class="op">.</span><span class="fu">Rewrite</span><span class="op">(</span>transformer<span class="op">)));</span></span></code></pre></div><p>The lambda which is passed to <code>RewriteChildren</code> contains a recursive call to <code>Rewrite</code>. Let’s think through the operational behaviour of <code>Rewrite</code>:</p>
<ol>
<li><code>Rewrite</code> calls <code>RewriteChildren</code>
</li>
<li><code>RewriteChildren</code> rents an array from the array pool and calls <code>GetChildren</code>
</li>
<li><code>RewriteChildren</code> calls the <code>child =&gt; child.Rewrite(transformer)</code> lambda function for each child
</li>
<li>The lambda function recursively calls <code>Rewrite</code>; steps 1-3 are repeated until you encounter a node with no children
</li>
<li><code>RewriteChildren</code> calls <code>SetChildren</code> and returns its array to the array pool
</li>
<li><code>RewriteChildren</code> returns and step 5 is repeated as you return up the call stack
</li>
</ol>
<p>Since steps 1-3 are repeated before step 5 happens, you can end up renting many arrays (a number equal to the height of the tree) before returning any of them to the pool. So the array pool could run out of arrays!</p>
<p>To fix this problem, we want to rent a small number of large arrays from the array pool, rather than a large number of small ones. We can lean on the fact that each array only lives as long as a single method — the array is <code>Rent</code>ed at the start of <code>RewriteChildren</code> and then <code>Return</code>ed at the end. The memory usage is stack-shaped.</p>
<p>So here’s the plan. We’re going to rent a large array from the pool at <code>Rewrite</code>’s beginning, and <code>RewriteChildren</code> will take a chunk from that array each time it’s called. Each chunk will be freed up before any previously-allocated chunks are freed.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> T Rewrite<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T value<span class="op">,</span> Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="op">(</span><span class="dt">var</span> chunks <span class="op">=</span> <span class="kw">new</span> ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;())</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        T <span class="fu">Go</span><span class="op">(</span>T x<span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="op">=&gt;</span> <span class="fu">transformer</span><span class="op">(</span>t<span class="op">.</span><span class="fu">RewriteChildrenInternal</span><span class="op">(</span>Go<span class="op">,</span> chunks<span class="op">));</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="fu">Go</span><span class="op">(</span>value<span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> T RewriteChildren<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T value<span class="op">,</span> Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="op">(</span><span class="dt">var</span> chunks <span class="op">=</span> <span class="kw">new</span> ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;())</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="fu">RewriteChildrenInternal</span><span class="op">(</span>t<span class="op">,</span> transformer<span class="op">,</span> chunks<span class="op">);</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> T RewriteChildrenInternal<span class="op">&lt;</span>T<span class="op">&gt;(</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> T value<span class="op">,</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">,</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;</span> chunks</span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> count <span class="op">=</span> value<span class="op">.</span><span class="fu">CountChildren</span><span class="op">();</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> span <span class="op">=</span> chunks<span class="op">.</span><span class="fu">Allocate</span><span class="op">(</span>count<span class="op">);</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>    value<span class="op">.</span><span class="fu">GetChildren</span><span class="op">(</span>span<span class="op">);</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>    <span class="kw">for</span> <span class="op">(</span><span class="dt">var</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> span<span class="op">.</span><span class="fu">Length</span><span class="op">;</span> i<span class="op">++)</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="34"><a href="#34" aria-hidden="true" tabindex="-1"></a>        span<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> <span class="fu">transformer</span><span class="op">(</span>span<span class="op">[</span>i<span class="op">]);</span></span>
<span id="35"><a href="#35" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="36"><a href="#36" aria-hidden="true" tabindex="-1"></a></span>
<span id="37"><a href="#37" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> result <span class="op">=</span> value<span class="op">.</span><span class="fu">SetChildren</span><span class="op">(</span>newChildren<span class="op">);</span></span>
<span id="38"><a href="#38" aria-hidden="true" tabindex="-1"></a>    chunks<span class="op">.</span><span class="fu">Free</span><span class="op">(</span>span<span class="op">);</span></span>
<span id="39"><a href="#39" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> result<span class="op">;</span></span>
<span id="40"><a href="#40" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><code>ChunkStack</code> contains an array and a count of how much of that array is in use. <code>Allocate</code> and <code>Free</code> increase and decrease that count.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> IDisposable</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> T<span class="op">[]</span> _array <span class="op">=</span> ArrayPool<span class="op">&lt;</span>T<span class="op">&gt;.</span><span class="fu">Shared</span><span class="op">.</span><span class="fu">Rent</span><span class="op">(</span><span class="dv">512</span><span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> _used <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Span<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">Allocate</span><span class="op">(</span><span class="dt">int</span> count<span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> span <span class="op">=</span> _array<span class="op">.</span><span class="fu">Slice</span><span class="op">(</span>_used<span class="op">,</span> count<span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        _used <span class="op">+=</span> count<span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> span<span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">Free</span><span class="op">(</span>Span<span class="op">&lt;</span>T<span class="op">&gt;</span> span<span class="op">)</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        _used <span class="op">-=</span> span<span class="op">.</span><span class="fu">Length</span><span class="op">;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">Dispose</span><span class="op">()</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(</span>_array <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>            ArrayPool<span class="op">&lt;</span>T<span class="op">&gt;.</span><span class="fu">Shared</span><span class="op">.</span><span class="fu">Return</span><span class="op">(</span>_array<span class="op">);</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            _array <span class="op">=</span> <span class="kw">null</span><span class="op">;</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>I’ve glossed over an important part of <code>ChunkStack</code>’s implementation: what happens when the array fills up? The <a href="https://github.com/benjamin-hodgson/Sawmill/blob/bf652359023a76d3ea395d7d743db1a8d6559ec2/Sawmill/ChunkStack.cs">real implementation</a> manages a collection of “regions”, taking a new region from the array pool when existing regions fill up.</p>
<p>In the pathological case of a <em>very</em> large tree, this version of <code>Rewrite</code> can still exhaust the array pool, but it’ll happen much less quickly.</p>
<h2 id="hackalloc"><a href="#hackalloc">Hackalloc</a></h2>
<p>I mentioned earlier that a <code>Span</code> is not necessarily backed by an array. <code>Span</code> represents <em>a contiguous block of memory</em>, with no assumptions about where that memory is or how it’s managed. A <code>Span</code> could be a slice of an array, or it could be a chunk of unmanaged memory, or it could be an area of the stack. Under the hood it’s <em>just a pointer</em>; <code>Span</code> doesn’t care exactly where the pointer points.</p>
<p>In fact, C# has built in support for that last case. The <code>stackalloc</code> keyword works like C’s <code>alloca</code>: it carves out a chunk of memory directly in the current stack frame, which becomes invalid when the current method returns. Until recently, <code>stackalloc</code> was only available in an <code>unsafe</code> context, but today it’s available in safe code thanks to <code>Span</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="dt">void</span> <span class="fu">StackallocExample</span><span class="op">()</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// allocate space for three ints in the current stack frame</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    Span<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> myInts <span class="op">=</span> <span class="kw">stackalloc</span> <span class="dt">int</span><span class="op">[</span><span class="dv">3</span><span class="op">];</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    myInts<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">=</span> <span class="dv">123</span><span class="op">;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    myInts<span class="op">[</span><span class="dv">1</span><span class="op">]</span> <span class="op">=</span> <span class="dv">456</span><span class="op">;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    myInts<span class="op">[</span><span class="dv">2</span><span class="op">]</span> <span class="op">=</span> myInts<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">+</span> myInts<span class="op">[</span><span class="dv">1</span><span class="op">];</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    Console<span class="op">.</span><span class="fu">WriteLine</span><span class="op">(</span>myInts<span class="op">[</span><span class="dv">2</span><span class="op">]);</span>  <span class="co">// prints 579</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>I want to use <code>stackalloc</code> to avoid taking memory from the <code>ChunkStack</code> when an object has a small number (say, 4) of children. This is fairly common in practice. Stack memory tends to be marginally faster than heap memory because it’s more likely to be in the processor cache, so this may have a modest performance benefit as well as relieving pressure on the array pool. If there are more than 4 children we can just fall back on the <code>ChunkStack</code>.</p>
<p>Here’s the new <code>RewriteChildrenInternal</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> T RewriteChildrenInternal<span class="op">&lt;</span>T<span class="op">&gt;(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> T value<span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;</span> chunks</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> count <span class="op">=</span> value<span class="op">.</span><span class="fu">CountChildren</span><span class="op">();</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    Span<span class="op">&lt;</span>T<span class="op">&gt;</span> span <span class="op">=</span> <span class="kw">stackalloc</span> T<span class="op">[</span><span class="dv">4</span><span class="op">];</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>count <span class="op">&gt;</span> <span class="dv">4</span><span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        span <span class="op">=</span> chunks<span class="op">.</span><span class="fu">Allocate</span><span class="op">(</span>count<span class="op">);</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    value<span class="op">.</span><span class="fu">GetChildren</span><span class="op">(</span>span<span class="op">);</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">for</span> <span class="op">(</span><span class="dt">var</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> span<span class="op">.</span><span class="fu">Length</span><span class="op">;</span> i<span class="op">++)</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        span<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> <span class="fu">transformer</span><span class="op">(</span>span<span class="op">[</span>i<span class="op">]);</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> result <span class="op">=</span> value<span class="op">.</span><span class="fu">SetChildren</span><span class="op">(</span>newChildren<span class="op">);</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>count <span class="op">&gt;</span> <span class="dv">4</span><span class="op">)</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>        chunks<span class="op">.</span><span class="fu">Free</span><span class="op">(</span>span<span class="op">);</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> result<span class="op">;</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Sadly this doesn’t work. The compiler complains about the <code>stackalloc T</code> line: “Cannot take the address of, get the size of, or declare a pointer to a managed type (‘T’)”. Basically, the CLR doesn’t support <code>stackalloc</code> with reference types — you can only use <code>stackalloc</code> with primitives or structs containing primitives. (A type parameter <code>T</code> <em>might</em> be a reference type, so you still can’t use it with <code>stackalloc</code>.) Under the hood, <code>stackalloc</code> is untyped; the garbage collector doesn’t know how to follow pointers that are stored in <code>stackalloc</code>ed memory because it doesn’t even know there are pointers there.</p>
<p>I still think the idea’s a good one, though. Can we unsafely hack it up?</p>
<p>I’m going to use the following <code>struct</code> as a “poor man’s <code>stackalloc[4]</code>”:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Four<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T First<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Second<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Third<span class="op">;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Fourth<span class="op">;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>A variable of type <code>Four&lt;T&gt;</code> has enough room for four <code>T</code>s — so when the variable is a local variable (in an ordinary method) it’s functionally equivalent to a <code>stackalloc T[4]</code>. We won’t be using the <code>First</code>, <code>Second</code>, <code>Third</code> and <code>Fourth</code> properties directly — we’ll be (unsafely) addressing them relative to the start of the struct. In this example I’m using <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unsafe?view=netcore-3.0"><code>System.Runtime.CompilerServices.Unsafe</code></a> to address <code>Third</code> by looking 2 elements beyond <code>First</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> four <span class="op">=</span> <span class="kw">new</span> Four<span class="op">&lt;</span>T<span class="op">&gt;();</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">ref</span> T third <span class="op">=</span> <span class="kw">ref</span> Unsafe<span class="op">.</span><span class="fu">Add</span><span class="op">(</span><span class="kw">ref</span> four<span class="op">.</span><span class="fu">First</span><span class="op">,</span> <span class="dv">2</span><span class="op">);</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>Assert<span class="op">.</span><span class="fu">True</span><span class="op">(</span>Unsafe<span class="op">.</span><span class="fu">AreSame</span><span class="op">(</span><span class="kw">ref</span> four<span class="op">.</span><span class="fu">Third</span><span class="op">,</span> <span class="kw">ref</span> third<span class="op">));</span></span></code></pre></div><p>The plan is to create a <code>Span</code> whose pointer refers to the start of a <code>Four&lt;T&gt;</code> on the stack. <code>span[0]</code> will address <code>four.First</code>, <code>span[1]</code> will address <code>Second</code>, and so on. My first idea to implement this was to use <code>System.Runtime.CompilerServices.Unsafe</code> to coerce a <code>ref Four&lt;T&gt;</code> to an unmanaged pointer, and then put that in a <code>Span</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">unsafe</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> four <span class="op">=</span> <span class="kw">new</span> Four<span class="op">&lt;</span>T<span class="op">&gt;();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span><span class="op">*</span> ptr <span class="op">=</span> Unsafe<span class="op">.</span><span class="fu">AsPointer</span><span class="op">(</span><span class="kw">ref</span> four<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> span <span class="op">=</span> <span class="kw">new</span> Span<span class="op">&lt;</span>T<span class="op">&gt;(</span>ptr<span class="op">,</span> <span class="dv">4</span><span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Sadly the <code>Span</code> constructor throws an exception when <code>T</code> is a reference type. At this point I went for a poke around in the .NET source code. I wanted to know how <code>array.AsSpan()</code> works. I found <a href="https://github.com/dotnet/corefx/blob/7e9a177824cbefaee8985a9b517ebb0ea2e17a81/src/Common/src/CoreLib/System/Span.Fast.cs#L123">an internal constructor</a> which takes a <code>ref T</code>. We can illictly call that constructor using reflection, although of course we want to avoid the performance costs of reflection. So the actual plan is to use runtime code generation to call the internal <code>Span</code> constructor. Ordinarily I’d use <code>Expression</code> to do this runtime code generation, but <code>Expression</code> doesn’t support <code>ref</code> parameters, so we have to write the IL by hand.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> <span class="kw">class</span> SpanFactory<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">delegate</span> Span<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">SpanCtor</span><span class="op">(</span><span class="kw">ref</span> T value<span class="op">,</span> <span class="dt">int</span> length<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">static</span> <span class="kw">readonly</span> SpanCtor _spanCtor<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">static</span> <span class="fu">SpanFactory</span><span class="op">()</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> ctor <span class="op">=</span> <span class="kw">typeof</span><span class="op">(</span>Span<span class="op">&lt;</span>T<span class="op">&gt;)</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">GetConstructors</span><span class="op">(</span>BindingFlags<span class="op">.</span><span class="fu">NonPublic</span> <span class="op">|</span> BindingFlags<span class="op">.</span><span class="fu">Instance</span><span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Single</span><span class="op">(</span>c <span class="op">=&gt;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>                c<span class="op">.</span><span class="fu">GetParameters</span><span class="op">().</span><span class="fu">Length</span> <span class="op">==</span> <span class="dv">2</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                <span class="op">&amp;&amp;</span> c<span class="op">.</span><span class="fu">GetParameters</span><span class="op">()[</span><span class="dv">0</span><span class="op">].</span><span class="fu">ParameterType</span><span class="op">.</span><span class="fu">IsByRef</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="op">);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> method <span class="op">=</span> <span class="kw">new</span> <span class="fu">DynamicMethod</span><span class="op">(</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            <span class="st">&quot;&quot;</span><span class="op">,</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>            <span class="kw">typeof</span><span class="op">(</span>Span<span class="op">&lt;</span>T<span class="op">&gt;),</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> <span class="kw">typeof</span><span class="op">(</span>T<span class="op">).</span><span class="fu">MakeByRefType</span><span class="op">(),</span> <span class="kw">typeof</span><span class="op">(</span><span class="dt">int</span><span class="op">)</span> <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="op">);</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> il <span class="op">=</span> method<span class="op">.</span><span class="fu">GetILGenerator</span><span class="op">();</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        il<span class="op">.</span><span class="fu">Emit</span><span class="op">(</span>OpCodes<span class="op">.</span><span class="fu">Ldarg_0</span><span class="op">);</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        il<span class="op">.</span><span class="fu">Emit</span><span class="op">(</span>OpCodes<span class="op">.</span><span class="fu">Ldarg_1</span><span class="op">);</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>        il<span class="op">.</span><span class="fu">Emit</span><span class="op">(</span>OpCodes<span class="op">.</span><span class="fu">Newobj</span><span class="op">,</span> ctor<span class="op">);</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>        il<span class="op">.</span><span class="fu">Emit</span><span class="op">(</span>OpCodes<span class="op">.</span><span class="fu">Ret</span><span class="op">);</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>        _spanCtor <span class="op">=</span> <span class="op">(</span>SpanCtor<span class="op">)</span>method<span class="op">.</span><span class="fu">CreateDelegate</span><span class="op">(</span><span class="kw">typeof</span><span class="op">(</span>SpanCtor<span class="op">));</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>    <span class="op">[</span><span class="fu">MethodImpl</span><span class="op">(</span>MethodImplOptions<span class="op">.</span><span class="fu">AggressiveInlining</span><span class="op">)]</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> Span<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">Create</span><span class="op">(</span><span class="kw">ref</span> T value<span class="op">,</span> <span class="dt">int</span> length<span class="op">)</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="fu">_spanCtor</span><span class="op">(</span><span class="kw">ref</span> value<span class="op">,</span> length<span class="op">);</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Obviously relying on BCL internals like this is risky. The internal constructor could be removed, or changed to work differently, in which case my code could stop working or even segfault. That said, I think the likelihood of the internal constructor changing is quite low in this case.</p>
<blockquote class="callout callout-note">
<h3>Update</h3>
<p>On .NET Core, there is an officially-supported API to do this: <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.memorymarshal.createspan?view=netcore-3.0"><code>MemoryMarshal.CreateSpan</code></a>. I didn’t know it existed at the time that I wrote this.</p>
</blockquote>
<p>There are also risks associated with mixing pointers and references like this. You have to be very careful that the <code>Span</code> doesn’t live longer than the <code>Four</code> it points to. That means the <code>Four</code> has to be discarded at the end of the method along with the <code>Span</code>, and it has to be stored in a “real” local variable, not in temporary storage on the evaluation stack. I’ll address that by mentioning the variable (as a parameter to a non-inlined “keep-alive” method) at the end of the method.</p>
<p>You also need to be certain that the <code>Four</code> is stored on the stack and not the heap. Data stored on the heap is liable to get moved by the garbage collector, which would invalidate the pointer inside the <code>Span</code>. Beware that local variables are not always safe from being moved! Methods containing <code>await</code>s, <code>yield</code>s, and lambdas are liable to store their local variables on the heap, so if <code>RewriteChildrenInternal</code> were not an ordinary method this hack would not be safe.</p>
<p>Here’s the final implementation of <code>RewriteChildrenInternal</code>. <code>var four = new Four&lt;T&gt;();</code> allocates space for four <code>T</code>s in <code>RewriteChildrenInternal</code>’s stack frame. Then, when I call <code>GetSpan</code>, I’m passing in the address of the start of that <code>Four</code> using the <code>ref</code> keyword. <code>GetSpan</code> returns a <code>Span</code> which either points at the start of <code>four</code> or at a chunk taken from the <code>ChunkStack</code>, depending on how many children we need to store. <code>ReleaseSpan</code> returns the <code>Span</code> to the <code>ChunkStack</code> if it came from there, and the <code>KeepAlive</code> call ensures the <code>four</code> isn’t deallocated too early.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> T RewriteChildrenInternal<span class="op">&lt;</span>T<span class="op">&gt;(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> T value<span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;</span> chunks</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> count <span class="op">=</span> value<span class="op">.</span><span class="fu">CountChildren</span><span class="op">();</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> four <span class="op">=</span> <span class="kw">new</span> Four<span class="op">&lt;</span>T<span class="op">&gt;();</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> span <span class="op">=</span> <span class="fu">GetSpan</span><span class="op">(</span>count<span class="op">,</span> chunks<span class="op">,</span> <span class="kw">ref</span> four<span class="op">);</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    value<span class="op">.</span><span class="fu">GetChildren</span><span class="op">(</span>span<span class="op">);</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">for</span> <span class="op">(</span><span class="dt">var</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> span<span class="op">.</span><span class="fu">Length</span><span class="op">;</span> i<span class="op">++)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        span<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> <span class="fu">transformer</span><span class="op">(</span>span<span class="op">[</span>i<span class="op">]);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> result <span class="op">=</span> value<span class="op">.</span><span class="fu">SetChildren</span><span class="op">(</span>newChildren<span class="op">);</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="fu">ReleaseSpan</span><span class="op">(</span>span<span class="op">,</span> chunks<span class="op">);</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="fu">KeepAlive</span><span class="op">(</span><span class="kw">ref</span> four<span class="op">);</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> result<span class="op">;</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> Span<span class="op">&lt;</span>T<span class="op">&gt;</span> GetSpan<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="dt">int</span> count<span class="op">,</span> ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;</span> chunks<span class="op">,</span> <span class="kw">ref</span> Four<span class="op">&lt;</span>T<span class="op">&gt;</span> four<span class="op">)</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>count <span class="op">==</span> <span class="dv">0</span><span class="op">)</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> <span class="kw">new</span> Span<span class="op">&lt;</span>T<span class="op">&gt;();</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> <span class="kw">if</span> <span class="op">(</span>count <span class="op">&lt;=</span> <span class="dv">4</span><span class="op">)</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> SpanFactory<span class="op">&lt;</span>T<span class="op">&gt;.</span><span class="fu">Create</span><span class="op">(</span><span class="kw">ref</span> four<span class="op">.</span><span class="fu">First</span><span class="op">,</span> count<span class="op">);</span></span>
<span id="34"><a href="#34" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="35"><a href="#35" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span></span>
<span id="36"><a href="#36" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="37"><a href="#37" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> chunks<span class="op">.</span><span class="fu">Allocate</span><span class="op">(</span>count<span class="op">);</span></span>
<span id="38"><a href="#38" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="39"><a href="#39" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="40"><a href="#40" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> <span class="dt">void</span> ReleaseSpan<span class="op">&lt;</span>T<span class="op">&gt;(</span>Span<span class="op">&lt;</span>T<span class="op">&gt;</span> span<span class="op">,</span> ChunkStack<span class="op">&lt;</span>T<span class="op">&gt;</span> chunks<span class="op">)</span></span>
<span id="41"><a href="#41" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="42"><a href="#42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>span<span class="op">.</span><span class="fu">Length</span> <span class="op">&gt;</span> <span class="dv">4</span><span class="op">)</span></span>
<span id="43"><a href="#43" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="44"><a href="#44" aria-hidden="true" tabindex="-1"></a>        chunks<span class="op">.</span><span class="fu">Free</span><span class="op">(</span>span<span class="op">);</span></span>
<span id="45"><a href="#45" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="46"><a href="#46" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="47"><a href="#47" aria-hidden="true" tabindex="-1"></a><span class="op">[</span><span class="fu">MethodImpl</span><span class="op">(</span>MethodImplOptions<span class="op">.</span><span class="fu">NoInlining</span><span class="op">)]</span></span>
<span id="48"><a href="#48" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> <span class="dt">void</span> KeepAlive<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">ref</span> Four<span class="op">&lt;</span>T<span class="op">&gt;</span> four<span class="op">)</span></span>
<span id="49"><a href="#49" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="50"><a href="#50" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>As far as I know, the designers of <code>Span</code> were thinking primarily about applications such as serialisation and parsing — the sort of low-level code you’d find in a <a href="https://github.com/aspnet/AspNetCore">high performance web server</a>. But <code>Span</code> also really shines in this high-level library of recursion patterns. Its guarantees about storage proved crucial to the safety of my <code>IRewritable</code> abstraction, but I’m also leaning on its flexibility to implement that abstraction as efficiently as possible.</p>
<p>Sawmill version 3.0 is now available <a href="https://www.nuget.org/packages/Sawmill">on Nuget</a>, and you can read all of this code in <a href="https://github.com/benjamin-hodgson/Sawmill">the GitHub repo</a>.</p>

]]></summary>
</entry>
<entry>
    <title>Announcing Pidgin v2.0</title>
    <link href="http://www.benjamin.pizza/posts/2019-01-26-announcing-pidgin-v2.0.html" />
    <id>http://www.benjamin.pizza/posts/2019-01-26-announcing-pidgin-v2.0.html</id>
    <published>2019-01-26T00:00:00Z</published>
    <updated>2019-01-26T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>Happy birthday to me! I’m pleased to announce that version 2.0 of my functional parsing library, <a href="https://github.com/benjamin-hodgson/Pidgin">Pidgin</a>, is now available <a href="https://www.nuget.org/packages/Pidgin">on Nuget</a>. In this release I’ve focused on error messages, performance, and <code>Span</code> support.</p>
<h2 id="parser-combinators"><a href="#parser-combinators">Parser Combinators</a></h2>
<p>I haven’t written about Pidgin before, so allow me to briefly introduce it. Pidgin is a <a href="https://en.wikipedia.org/wiki/Parser_combinator"><em>parser combinator</em></a> library, meaning that it consists of three main concepts:</p>
<ul>
<li>A type <code>Parser</code> which models a <em>parsing process</em>
</li>
<li>A collection of <em>primitive</em> <code>Parser</code> objects which perform some simple individual parsing task
</li>
<li>A collection of <em>combinator</em> functions which can build complex <code>Parser</code>s out of simpler ones
</li>
</ul>
<p>Taken together, we have an object model allowing you to write code resembling a high-level description of a parsing process. As a brief taste, here is a simple example parser which parses an identifier in a typical programming language.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> Identifier <span class="op">=</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    Letter<span class="op">.</span><span class="fu">Then</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        LetterOrDigit<span class="op">.</span><span class="fu">ManyString</span><span class="op">(),</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">(</span>first<span class="op">,</span> rest<span class="op">)</span> <span class="op">=&gt;</span> first <span class="op">+</span> rest</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>Assert<span class="op">.</span><span class="fu">Equal</span><span class="op">(</span><span class="st">&quot;abc1&quot;</span><span class="op">,</span> Identifier<span class="op">.</span><span class="fu">ParseOrThrow</span><span class="op">(</span><span class="st">&quot;abc1&quot;</span><span class="op">));</span></span></code></pre></div><ul>
<li><code>Identifier</code> is a <code>Parser&lt;char, string&gt;</code>, meaning it’s a process which consumes a sequence of <code>char</code>s and produces a <code>string</code>.
</li>
<li><code>Letter</code> is a primitive parser which consumes and returns a single character from the input stream, moving it on to the next character. (If the character is not a letter, the parser fails and doesn’t change the state of the input stream.)
</li>
<li><code>LetterOrDigit</code> is like <code>Letter</code> but for alphanumeric characters.
</li>
<li><code>ManyString</code> is a combinator method which runs a parser in a loop until it fails. It takes all of the smaller parser’s results from the loop and packs them into a <code>string</code>. So <code>LetterOrDigit.ManyString()</code> is a parser which consumes and returns a sequence of alphanumeric characters.
</li>
<li><code>Then</code> is another combinator which runs two parsers in sequence and applies a function to the result. So, reading the parser as a whole, we can see that an <code>Identifier</code> consists of a single letter followed by a sequence of letters or digits.
</li>
</ul>
<p>Parser combinators’ power comes from their composability. The library comprises a small number of building blocks, which you can put together in rich and varied ways to build a parser which does what you need. The library’s level of abstraction is a good fit for small-to-medium sized parsing tasks: it’s not as high-level as a full-blown parser generator like Antlr, but it’s much simpler to integrate. Rewriting our hand-written <a href="https://www.benjamin.pizza/posts/2017-11-13-recursion-without-recursion.html">JQL</a> parser in Pidgin took around four times less code.</p>
<p>That’s the overview — I won’t dive into a full tutorial on parser combinators because there are already <a href="http://www.lihaoyi.com/post/EasyParsingwithParserCombinators.html">plenty</a> <a href="http://webdoc.sub.gwdg.de/ebook/serien/ah/UU-CS/2008-044.pdf">of</a> <a href="https://news.ycombinator.com/item?id=14600079">those</a> a mere Google away.</p>
<h3 id="how-it-works"><a href="#how-it-works">How it works</a></h3>
<p>Pidgin’s <code>Parser&lt;TToken, T&gt;</code> type represents a process which pulls <code>TToken</code>s one at a time from a (stateful) input stream, and either successfully returns a <code>T</code> or fails with an error message.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">abstract</span> <span class="kw">class</span> Parser<span class="op">&lt;</span>TToken<span class="op">,</span> T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">internal</span> <span class="kw">abstract</span> Result<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">Parse</span><span class="op">(</span>IParseState<span class="op">&lt;</span>TToken<span class="op">&gt;</span> input<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">internal</span> <span class="kw">interface</span> IParseState<span class="op">&lt;</span>TToken<span class="op">&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    TToken<span class="op">?</span> <span class="fu">Peek</span><span class="op">();</span>  <span class="co">// null if at end of file</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">Advance</span><span class="op">();</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ... plus a few methods to facilitate backtracking etc</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="kw">internal</span> <span class="kw">struct</span> Result<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="co">// if Success is true, Value contains the parsed value and Error is null</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// if Success is false, Value is null and Error contains error info</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">bool</span> Success <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> T Value <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ParseError Error <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><code>IParseState</code> represents an iterator over the parser’s input (a sequence of <code>TToken</code>s). <code>Peek</code> returns the token at the current location in the input (or <code>null</code> if the parser has reached the end of the input) and <code>Advance</code> moves the stream on to the next token.</p>
<p>Primitive parsers typically manipulate the <code>IParseState</code> directly. This parser matches a specific string:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> StringParser <span class="op">:</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> <span class="dt">string</span> _expected<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">internal</span> <span class="kw">override</span> Result<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> <span class="fu">Parse</span><span class="op">(</span>IParseState<span class="op">&lt;</span><span class="dt">char</span><span class="op">&gt;</span> input<span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> c <span class="kw">in</span> _expected<span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="dt">var</span> token <span class="op">=</span> input<span class="op">.</span><span class="fu">Peek</span><span class="op">();</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> <span class="op">(!</span>token<span class="op">.</span><span class="fu">HasValue</span><span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Error</span><span class="op">(</span>ParseError<span class="op">.</span><span class="fu">EndOfFile</span><span class="op">);</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> <span class="op">(</span>token<span class="op">.</span><span class="fu">Value</span> <span class="op">!=</span> c<span class="op">)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Error</span><span class="op">(</span>ParseError<span class="op">.</span><span class="fu">UnexpectedToken</span><span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            input<span class="op">.</span><span class="fu">Advance</span><span class="op">();</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Success</span><span class="op">(</span>_expected<span class="op">);</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Higher-order parsers typically compose one or more smaller parsers, delegating to their <code>Parse</code> methods in some useful way. <code>Then</code> returns a parser which sequences two parsers and applies a mapping function to their results:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> ThenParser<span class="op">&lt;</span>TToken<span class="op">,</span> T<span class="op">,</span> U<span class="op">,</span> R<span class="op">&gt;</span> <span class="op">:</span> Parser<span class="op">&lt;</span>TToken<span class="op">,</span> R<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span>TToken<span class="op">,</span> T<span class="op">&gt;</span> _first<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> Parser<span class="op">&lt;</span>TToken<span class="op">,</span> U<span class="op">&gt;</span> _second<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> Func<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">,</span> R<span class="op">&gt;</span> _resultSelector<span class="op">;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">internal</span> <span class="kw">override</span> Result<span class="op">&lt;</span>R<span class="op">&gt;</span> <span class="fu">Parse</span><span class="op">(</span>IParseState<span class="op">&lt;</span>TToken<span class="op">&gt;</span> input<span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> result1 <span class="op">=</span> _first<span class="op">.</span><span class="fu">Parse</span><span class="op">(</span>input<span class="op">);</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(!</span>result1<span class="op">.</span><span class="fu">Success</span><span class="op">)</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Error</span><span class="op">(</span>result1<span class="op">.</span><span class="fu">Error</span><span class="op">);</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> result2 <span class="op">=</span> _second<span class="op">.</span><span class="fu">Parse</span><span class="op">(</span>input<span class="op">);</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(!</span>result2<span class="op">.</span><span class="fu">Success</span><span class="op">)</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Error</span><span class="op">(</span>result2<span class="op">.</span><span class="fu">Error</span><span class="op">);</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Success</span><span class="op">(</span><span class="fu">_resultSelector</span><span class="op">(</span>result1<span class="op">.</span><span class="fu">Value</span><span class="op">,</span> result2<span class="op">.</span><span class="fu">Value</span><span class="op">));</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="error-messages"><a href="#error-messages">Error messages</a></h2>
<p>Part of Pidgin’s job is to report when you gave a parser bad input. For example, the top level of a C# file must contain <code>class</code>es and <code>namespace</code>s, so feeding a C# parser the text <code>Console.WriteLine(&quot;foo&quot;);</code> (without an enclosing <code>class</code>) should fail with some information about the problem:</p>
<pre><code>Parse error.
    unexpected 'C'
    expected &quot;class&quot; or &quot;namespace&quot;
    at line 1, col 1
</code></pre>
<p>A mistake I made early on in Pidgin’s development nearly two years ago(!) was trying to pre-compute the content of these error messages. Under the assumption that parsers are typically built once and then run repeatedly, I wrote some code to examine your parser upon construction and try to predict the ways it could fail on unexpected input, in order to avoid constructing error messages at runtime. This code calculated a set of “expected” input strings, accounting for <code>Then</code>s and <code>Or</code>s by concatenating the strings in the set and by unioning the sets respectively. (The idea was that a parser like <code>Keyword(&quot;public&quot;).Optional().Then(Keyword(&quot;class&quot;))</code> would report that it expected <code>&quot;class&quot; or &quot;public class&quot;</code>.)</p>
<p>This went catastrophically wrong for complex parsers. Here’s a sketch of some code which parses left-associative mathematical operators with precedence, so <code>3^2 + 4 * 3^5 * 5</code> is parsed as <code>(3^2) + ((4 * (3^5)) * 5)</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> topPrecedence <span class="op">=</span> Number<span class="op">.</span><span class="fu">Then</span><span class="op">(</span><span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;^&#39;</span><span class="op">).</span><span class="fu">Then</span><span class="op">(</span>Number<span class="op">).</span><span class="fu">Many</span><span class="op">());</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> midPrecedence <span class="op">=</span> topPrecedence<span class="op">.</span><span class="fu">Then</span><span class="op">(</span><span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;*&#39;</span><span class="op">).</span><span class="fu">Then</span><span class="op">(</span>topPrecedence<span class="op">).</span><span class="fu">Many</span><span class="op">());</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> lowPrecedence <span class="op">=</span> midPrecedence<span class="op">.</span><span class="fu">Then</span><span class="op">(</span><span class="fu">Char</span><span class="op">(</span><span class="ch">&#39;+&#39;</span><span class="op">).</span><span class="fu">Then</span><span class="op">(</span>midPrecedence<span class="op">).</span><span class="fu">Many</span><span class="op">());</span></span></code></pre></div><p><code>topPrecedence</code> expects a number, or a number followed by a sequence of exponents — two possibilities. <code>midPrecedence</code> therefore expects a number, or a number followed by a sequence of exponents, or a number followed by a sequence of multiplications, or a number followed by a sequence of exponents followed by a sequence of multiplications — four possibilities. <code>lowPrecedence</code> has eight possible expected inputs. The set of expected inputs blows up exponentially! Calculating the error messages in advance means you need to explore all of the (exponentially large number of) expected inputs in advance, which led to cosmologically long parser build times. And in any case, reporting a huge number of expected inputs does not make for a very good error message.</p>
<p>I made some attempts to optimise this by using more efficient data structures, but I realised this was a losing proposition and decided to throw it out altogether in v2.0. Error messages are now computed at runtime, when the error actually occurs. This means I can be more precise about what the parser was expecting at that particular point in the input: once a parsing process has committed to a branch I can report expected inputs <em>from that branch</em>, rather than reporting all possible expected inputs.</p>
<p>Implementing this efficiently was a challenge. Parse errors actually occur quite frequently in a parser combinator library, even in the happy path, because of the way the <em>prioritised choice</em> operator <code>Or</code> works — <code>String(&quot;foo&quot;).Or(String(&quot;bar&quot;))</code> only tries <code>bar</code> if an attempt to parse <code>foo</code> failed. So I tried to implement this change without allocating heap memory every time a parser fails. When a parser fails, it saves its expected inputs in a stack implemented on top of pooled memory (using <code>ArrayPool</code>), which are then popped if the error gets discarded. (The way that certain parsers manipulate their children’s error messages adds some interesting complications here, which I’ve described in a <a href="https://github.com/benjamin-hodgson/Pidgin/blob/60c7734393719d11714158b201c99976ec48ffb9/Pidgin/ParseState.Error.cs#L36-L74">long comment</a>.)</p>
<h2 id="span"><a href="#span"><code>Span</code></a></h2>
<blockquote class="callout callout-note">
<h3>Note</h3>
<p>You can watch <a href="https://twitter.com/g3rv4">my esteemed colleague Gervasio</a> and me carrying out the work I describe here in <a href="https://www.youtube.com/watch?v=O23OLkQtiS4">a live-stream on YouTube</a>. It was pretty fun!</p>
</blockquote>
<p>I wanted to add support for parsing input stored in a <code>Span</code>. (<code>Span</code> is a new part of the BCL representing a reference to a contiguous block of memory such as a chunk of an array.) I already had functions which applied a <code>Parser</code> to a <code>string</code>, a <code>T[]</code>, a <code>Stream</code>, etc; I’d abstracted over these various input types using the aforementioned <code>IParseState</code> interface.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">internal</span> <span class="kw">interface</span> IParseState<span class="op">&lt;</span>TToken<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    TToken<span class="op">?</span> <span class="fu">Peek</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">Advance</span><span class="op">();</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>So adding <code>Span</code> support basically means implementing <code>IParseState</code> on top of a <code>Span</code>. In theory this should be quite straightforward — a class which has a <code>Span</code> and keeps track of its current position:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> SpanTokenStream<span class="op">&lt;</span>TToken<span class="op">&gt;</span> <span class="op">:</span> ITokenStream<span class="op">&lt;</span>TToken<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> Span<span class="op">&lt;</span>TToken<span class="op">&gt;</span> _span<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> _current<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    TToken<span class="op">?</span> <span class="fu">Peek</span><span class="op">()</span> <span class="op">=&gt;</span> _current <span class="op">&gt;=</span> _span<span class="op">.</span><span class="fu">Length</span> <span class="op">?</span> <span class="kw">null</span> <span class="op">:</span> _span<span class="op">[</span>_current<span class="op">];</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">Advance</span><span class="op">()</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        _current<span class="op">++;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>But if you try and write this class, you’ll find that the compiler turns you away. <code>Span</code> is a <code>ref struct</code>, which means that it can only be stored on the stack. You can’t use a <code>Span</code> as a field of a <code>class</code>, or put it in an array, or box it (by upcasting it to an <code>interface</code> or <code>object</code>), or use it as a local variable in an <code>async</code> or <code>yield</code> method (because behind the scenes such methods copy their stack frame to the heap). (There are good reasons for this restriction, pertaining to memory safety.)</p>
<p>How to implement <code>IParseState</code> without storing a <code>Span</code> on the heap? Because <code>IParseState</code> is an internal interface, I can make certain guarantees about its usage. Instances of <code>IParseState</code> have a limited life-span — each <code>IParseState</code> instance becomes garbage before the call to <code>Parse</code> returns, and <code>IParseState</code> instances are never accessed from multiple threads. So I can store the <code>Span</code> in <code>Parse</code>’s stack frame and put a pointer to that stack frame in the <code>IParseState</code>.</p>
<p>This idea is complicated by the fact that <code>Span</code> is a <a href="https://stackoverflow.com/questions/42154908">managed type</a>, so you’re not allowed to declare a <code>Span&lt;T&gt;*</code>. (This restriction ensures that a managed object can’t accidentally become garbage while it’s still being referred to by an unmanaged pointer; this needn’t trouble us here as the <code>Span</code> is guaranteed to be reachable because it’s on the stack.)</p>
<p>Fortunately, <a href="https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/">the <code>System.Runtime.CompilerServices.Unsafe</code> package</a> contains some dangerous tools to get around this memory safety restriction: <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unsafe.aspointer"><code>Unsafe.AsPointer</code></a> coerces a <code>ref</code> to an untyped <code>void*</code> and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unsafe.asref"><code>Unsafe.AsRef</code></a> coerces it back. So my plan was to store a <code>ref Span&lt;T&gt;</code> as a <code>void*</code> on the heap, and coerce it back to a <code>ref Span&lt;T&gt;</code> using  when I need to address it as a <code>Span</code>. (This is a similar hack to one that I used in <a href="/posts/2018-03-16-eighty.html">my HTML generation library</a>.)</p>
<p>Unfortunately this doesn’t work either, because <code>Unsafe.AsPointer</code> is generic and you can’t use a <code>ref struct</code> as a type parameter! The compiler can’t be sure that <code>Unsafe.AsPointer</code> doesn’t box its argument, which of course is forbidden when the argument is a <code>Span</code>.</p>
<p>I wound up implementing a type-specialised copy of those two <code>Unsafe</code> methods:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">class</span> Unsafe</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> <span class="dt">void</span><span class="op">*</span> AsPointer<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">ref</span> Span<span class="op">&lt;</span>T<span class="op">&gt;</span> span<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> <span class="kw">ref</span> Span<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">AsRef</span><span class="op">(</span><span class="dt">void</span><span class="op">*</span> ptr<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><code>AsPointer</code> and <code>AsRef</code> are not expressible in C# (even <code>unsafe</code> C#); <code>System.Runtime.CompilerServices.Unsafe</code> is implemented in raw IL. My copies of those methods have stubs in C# which are filled in by rewriting the DLL’s IL in a post-compile step.</p>
<h2 id="assorted-performance-improvements"><a href="#assorted-performance-improvements">Assorted Performance Improvements</a></h2>
<p>Performance has always been one of Pidgin’s priorities — I’m proud that Pidgin is C#’s fastest parser combinator library (that I know of!) — but there’s always room for improvement. In my tests Pidgin still runs somewhat slower than F#’s FParsec library, for example. In this release I made some architectural changes to <code>IParseState</code> to help close that gap.</p>
<h3 id="buffering-uniformly"><a href="#buffering-uniformly">Buffering Uniformly</a></h3>
<p>As I mentioned earlier, Pidgin has several internal implementations of <code>IParseState</code>, each of which implements a streaming abstraction on top of a different type of input. Parsers may need to <em>backtrack</em> on failure (using the <code>Try</code> combinator), so you can’t always discard a token as soon as you’ve seen it. Some <code>IParseState</code> implementations — specifically the ones that are built on top of streaming storage (like <code>Stream</code>) — therefore <em>buffer</em> their input into an array. The ones that are backed by in-memory storage like <code>string</code> don’t need to buffer because their data is already in memory.</p>
<p>I decided to move the buffering logic to a shared part of the code. Now <em>all</em> <code>IParseState</code> implementations buffer their input, even the in-memory ones. On its own this should make the code slower (it’s more expensive to copy a <code>string</code> into an array than not to!), but it enables all of the optimisations I’m about to describe.</p>
<h3 id="de-virtualisation--inlining"><a href="#de-virtualisation--inlining">De-Virtualisation &amp; Inlining</a></h3>
<p>Virtual method calls are comparatively expensive in .NET, and they happen frequently in Pidgin’s implementation because of <code>IParseState</code>’s design: a parser which consumes <em>n</em> tokens makes a minimum of <em>n</em> virtual calls to <code>Advance</code>.</p>
<p>With the buffering code extracted into a single place, there was no longer any need to keep it behind an interface. I moved all the buffering and error handling code into a mutable struct which is stored on the stack and passed to the <code>Parser</code>s by reference. Now <code>Advance</code> and <code>Peek</code> are non-virtual.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> ParseState<span class="op">&lt;</span>TToken<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> TToken<span class="op">[]</span> _buffer<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> _currentPosition<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> ITokenStream<span class="op">&lt;</span>TToken<span class="op">&gt;</span> _stream<span class="op">;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> TToken<span class="op">?</span> <span class="fu">Peek</span><span class="op">()</span> <span class="op">=&gt;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        _currentPosition <span class="op">&lt;</span> <span class="dv">0</span> <span class="op">||</span> _currentPosition <span class="op">&gt;=</span> _buffer<span class="op">.</span><span class="fu">Length</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="op">?</span> <span class="kw">null</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="op">:</span> _buffer<span class="op">[</span>_currentPosition<span class="op">];</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">Advance</span><span class="op">()</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        _currentPosition<span class="op">++;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(</span>_currentPosition <span class="op">&gt;=</span> _buffer<span class="op">.</span><span class="fu">Length</span><span class="op">)</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="fu">ReadStreamIntoBuffer</span><span class="op">();</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">abstract</span> <span class="kw">class</span> Parser<span class="op">&lt;</span>TToken<span class="op">,</span> T<span class="op">&gt;</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">internal</span> <span class="kw">abstract</span> Result<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">Parse</span><span class="op">(</span><span class="kw">ref</span> ParseState<span class="op">&lt;</span>TToken<span class="op">&gt;</span> state<span class="op">);</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>That’s a fairly general C# performance trick: put shared state in a mutable struct, store it on the stack, and pass it around as a <code>ref</code> parameter. This both reduces GC pressure and improves the CPU cache’s hit rate, because the execution stack is likely to be in cache.</p>
<p>I also noticed that <code>Peek</code> was not <em>inlining</em> well. Inlining is an important optimisation carried out by the JIT compiler: if you call a method that’s short and simple enough, the compiler will just copy the method’s body into the current method instead of emitting code to call it. This can often enable further optimisations such as erasing array bounds checks.</p>
<p>I split <code>Peek</code> up into a pair of properties:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> ParseState<span class="op">&lt;</span>TToken<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> TToken<span class="op">[]</span> _buffer<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> _currentPosition<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">bool</span> HasCurrent <span class="op">=&gt;</span> _currentPos <span class="op">&gt;=</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> _currentPos <span class="op">&lt;</span> _buffer<span class="op">.</span><span class="fu">Length</span><span class="op">;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> TToken Current <span class="op">=&gt;</span> _buffer<span class="op">[</span>_currentPosition<span class="op">];</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>These properties are short and non-virtual, so they are good inlining candidates. After inlining them, the JIT sees simple array-manipulating code, which it can easily optimise in the context of the containing method. This simple change resulted in a 15-20% performance improvement across the board.</p>
<h3 id="chunking"><a href="#chunking">Chunking</a></h3>
<p>The <code>Stream</code> version of <code>Advance</code> called <code>stream.Read()</code>, which reads and returns a single byte from the stream. This is not as efficient as <code>stream.Read(byte[])</code>, which reads a chunk of bytes from the stream and copies them into an array. (The former requires <em>n</em> virtual method calls to read <em>n</em> bytes, whereas the latter requires only <em>n / <code>array.Length</code></em>.)</p>
<p>I replaced <code>ITokenStream</code>’s <code>Advance</code> and <code>Peek</code> methods with a method which reads a chunk of tokens into the <code>ParseState</code>’s buffer.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ITokenStream<span class="op">&lt;</span>TToken<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">void</span> <span class="fu">ReadInto</span><span class="op">(</span>TToken<span class="op">[]</span> buffer<span class="op">,</span> <span class="dt">int</span> start<span class="op">,</span> <span class="dt">int</span> count<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Why not design this signature as <code>void ReadInto(Span&lt;TToken&gt; span)</code>? I’d love to! Sadly that would preclude some implementations of <code>ITokenStream</code>. Methods like <code>stream.Read(Span&lt;byte&gt; span)</code> are available only on .NET Core, and as far as I’m aware Microsoft has no plans to backport them, so for compatibility with the desktop framework I’m stuck using arrays. This is irksome, as <a href="/posts/2018-12-06-zooming-in-on-field-accessors.html">I’ve said before</a> — what’s the point of designing a feature for library authors if you’re not going to support it properly?</p>
<p><code>ReadInto</code> allows the <code>ParseState</code> to fill its buffer in chunks. But <code>ParseState</code>’s interface can also be chunk-ified — some <code>Parser</code>s (like <code>String</code>) can predict how many characters they’ll pull from the input. I added a <code>Peek</code> method to <code>ParseState</code> which returns a view into the <code>ParseState</code>’s buffer. (This makes <code>Peek</code> a little tricky to use correctly — you have to be careful not to continue using the <code>Span</code> after a call to <code>Advance</code>, which may mutate the buffer.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> ReadOnlySpan<span class="op">&lt;</span>TToken<span class="op">&gt;</span> <span class="fu">Peek</span><span class="op">(</span><span class="dt">int</span> count<span class="op">);</span></span></code></pre></div><p>Using <code>Peek</code>, a parser like <code>String(&quot;foo&quot;)</code> can now look at three characters from the input to see if they match <code>foo</code>, rather than one at a time.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> StringParser <span class="op">:</span> Parser<span class="op">&lt;</span><span class="dt">char</span><span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">readonly</span> <span class="dt">string</span> _expected<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">internal</span> <span class="kw">override</span> Result<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> <span class="fu">Parse</span><span class="op">(</span><span class="kw">ref</span> ParseState<span class="op">&lt;</span><span class="dt">char</span><span class="op">&gt;</span> state<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> span <span class="op">=</span> state<span class="op">.</span><span class="fu">Peek</span><span class="op">(</span>_expected<span class="op">.</span><span class="fu">Length</span><span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> <span class="op">(!</span>_expected<span class="op">.</span><span class="fu">AsSpan</span><span class="op">().</span><span class="fu">SequenceEqual</span><span class="op">(</span>span<span class="op">))</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Failure</span><span class="op">();</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> Result<span class="op">.</span><span class="fu">Success</span><span class="op">(</span>_expected<span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>This runs about 20% faster for long strings.</p>
<h2 id="make-your-own-opportunities"><a href="#make-your-own-opportunities">Make Your Own Opportunities</a></h2>
<p>Indulge me for a moment while I dispense some unsolicited career advice. For a long time, performance engineering was something that <a href="https://twitter.com/marcgravell/">other</a>, <a href="https://twitter.com/davidfowl">cleverer</a> <a href="https://mattwarren.org/">people</a> did while I observed from a distance with awe. Why is ASP.NET fast? Because the guys that wrote it are Actual Wizards.</p>
<p>I’ve been lucky enough to work with some of those clever people for a few years now, and actually they’re not Actual Wizards. They just have more experience than me — they know how to use and interpret profiles and benchmarks, they’ve seen enough to know what does and doesn’t work, and they’ve had practice coming up with ideas to improve performance.</p>
<p>The good news is that performance optimisation usually doesn’t involve fiddly low-level programming like this — simply being aware of when your code performs IO makes a big difference — and it’s never too early or late to start building your experience level, no matter where you are in your career. For me, that meant setting myself the goal of making my open source libraries as fast as I could. For you, it could mean picking a slow part of your codebase at work and trying to make it faster, or pair-programming with a colleague, or thoroughly reading through some unfamiliar code. Making your own opportunities to learn new things is the best way to get better.</p>

]]></summary>
</entry>
<entry>
    <title>The Fourth Type of Variance</title>
    <link href="http://www.benjamin.pizza/posts/2019-01-11-the-fourth-type-of-variance.html" />
    <id>http://www.benjamin.pizza/posts/2019-01-11-the-fourth-type-of-variance.html</id>
    <published>2019-01-11T00:00:00Z</published>
    <updated>2019-01-11T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>Given a polymorphic type, like <code>List</code>, what can we say about the relationship between different usages of that type? If <code>A</code> and <code>B</code> are related, is <code>List[A]</code> related to <code>List[B]</code>? <em>Variance</em> is the word for this type of relationship, and it turns out there are a few different answers to that question, depending on the type you’re asking about.</p>
<h2 id="covariance"><a href="#covariance">Covariance</a></h2>
<p>Probably the most familiar situation is when the parameterised types are related in the same way as the parameter. This is the type of variance exhibited by most “container” types, like <code>List</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">sealed</span> <span class="kw">abstract</span> <span class="kw">class</span> <span class="ex">List</span><span class="op">[+</span>A<span class="op">]</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> cats <span class="op">:</span> <span class="ex">List</span><span class="op">[</span>Cat<span class="op">]</span> <span class="op">=</span> <span class="ex">List</span><span class="op">(</span><span class="fu">Cat</span><span class="op">(</span><span class="st">&quot;Tilly&quot;</span><span class="op">),</span> <span class="fu">Cat</span><span class="op">(</span><span class="st">&quot;Charlie&quot;</span><span class="op">),</span> <span class="fu">Cat</span><span class="op">(</span><span class="st">&quot;Izzy&quot;</span><span class="op">))</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> animals <span class="op">:</span> <span class="ex">List</span><span class="op">[</span>Animal<span class="op">]</span> <span class="op">=</span> cats</span></code></pre></div><p><code>List</code>’s parameter <code>A</code> is annotated with <code>+</code>, so it’ll be treated as covariant. This allows you to use a <code>List[Cat]</code> any time you need a <code>List[Animal]</code>. A list of <code>Cat</code>s is a list of <code>Animal</code>s, because every <code>Cat</code> is an <code>Animal</code>. The subtype relationship of the container goes in the same direction as the subtype relationship of the elements. (In C# <code>+</code> is pronounced <code>out</code>, as in <code>IEnumerable&lt;out T&gt;</code>.)</p>
<p>Variance is visible even in non-subtyping-based languages. Haskellers’ll be familiar with <em>covariant functors</em>. It’s the type of functor exhibited the the standard <code>Functor</code> class.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> [] <span class="kw">where</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f xs <span class="ot">=</span> [f x <span class="op">|</span> x <span class="ot">&lt;-</span> xs]</span></code></pre></div><p>This chimes with the intuition that a functor <code>f</code> is a container of sorts. If you can write a function to convert each <code>a</code> in the container into a <code>b</code>, then <code>fmap</code> can convert a container of <code>a</code>s into a container of <code>b</code>s by converting each item in the container.</p>
<p>In general, a type is covariant if its parameter is used as an output. An object which produces <code>Cat</code>s can be used to produce <code>Animal</code>s. All you have to do is ignore the cattiness of the animals you get out of the producer.</p>
<h2 id="contravariance"><a href="#contravariance">Contravariance</a></h2>
<p><em>Contravariance</em>, covariance’s evil twin, is the word for when the parameterised types are related in the opposite way as the parameters. Scala’s <code>Ordering</code>, which determines which way round to put two objects (like C#’s <code>IComparer</code>), is an example of a contravariant type.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> Ordering<span class="op">[-</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">apply</span><span class="op">(</span>x <span class="op">:</span> A<span class="op">,</span> y <span class="op">:</span> A<span class="op">)</span> <span class="op">:</span> <span class="bu">Int</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> animalOrdering <span class="op">:</span> Ordering<span class="op">[</span>Animal<span class="op">]</span> <span class="op">=</span> Ordering<span class="op">.</span>by<span class="op">[</span>Animal<span class="op">,</span> <span class="bu">Int</span><span class="op">](</span>x <span class="op">=&gt;</span> x<span class="op">.</span>cuteness<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> catOrdering <span class="op">:</span> Ordering<span class="op">[</span>Cat<span class="op">]</span> <span class="op">=</span> animalOrdering</span></code></pre></div><p>The <code>-</code> symbol denotes a contravariant parameter, allowing us to use an <code>Ordering[Animal]</code> as an <code>Ordering[Cat]</code>. (C#ers say <code>in</code>, as in <code>IComparer&lt;in T&gt;</code>.) If you know how to compare two <code>Animal</code>s (perhaps by comparing their cuteness), you can certainly compare two <code>Cat</code>s. The subtype relationship of the comparers goes in the opposite direction to that of the parameters.</p>
<p>The class of contravariant functors in Haskell is just like <code>Functor</code> but with the direction of one of the arrows flipped.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Contravariant</span> f <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    contramap ::</span> (b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Comparer</span> a <span class="ot">=</span> <span class="dt">Comparer</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Ord</span>)</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Contravariant</span> <span class="dt">Comparer</span> <span class="kw">where</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    contramap f (<span class="dt">Comparer</span> p) <span class="ot">=</span> <span class="dt">Comparer</span> (\x y <span class="ot">-&gt;</span> p (f x) (f y))</span></code></pre></div><p>If you can turn <code>b</code>s into <code>a</code>s, then you can turn a comparer of <code>a</code>s into a comparer of <code>b</code>s by converting the <code>b</code>s into <code>a</code>s before they go into the comparer. Note how <code>f</code> is applied to <code>p</code>’s inputs in the implementation of <code>contramap</code>.</p>
<p>In general, a type is contravariant if its parameter appears as an input. An object which consumes <code>Animals</code> can be used to consume <code>Cat</code>s. All you have to do is forget about the cattiness of the animals before you put them into the consumer.</p>
<p>Julie Moronuki has <a href="https://typeclasses.com/contravariance">the best explanation of contravariance</a> that I know of.</p>
<h2 id="invariance"><a href="#invariance">Invariance</a></h2>
<p><em>Invariance</em> is the word for when there’s no relationship at all between different usages of a parameterised type.</p>
<p>In Scala a type parameter unadorned with a sign is invariant. The following mutable set type is invariant:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> <span class="ex">Set</span><span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// A appears as both an input and an output</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">add</span><span class="op">(</span>item<span class="op">:</span> A<span class="op">):</span> <span class="bu">Unit</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">remove</span><span class="op">(</span>item<span class="op">:</span> A<span class="op">):</span> <span class="bu">Unit</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">contains</span><span class="op">(</span>item<span class="op">:</span> A<span class="op">):</span> <span class="ex">Boolean</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">items</span><span class="op">():</span> <span class="ex">Iterable</span><span class="op">[</span>A<span class="op">]</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>In general, a type is invariant if its parameter appears as both an input and an output. You can’t use <code>Set</code> covariantly, because <code>A</code> appears as an input to <code>contains</code>, and you can’t use it contravariantly because <code>A</code> appears in <code>items</code>’s output. There’s no subtyping relationship between the parameter and the type. A <code>Set[Cat]</code> is not a <code>Set[Animal]</code>. If it was, you’d be allowed to upcast it and then call <code>add</code> with a <code>Dog</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> catSet <span class="op">=</span> <span class="kw">new</span> <span class="ex">Set</span><span class="op">[</span>Cat<span class="op">](</span><span class="fu">Cat</span><span class="op">(</span><span class="st">&quot;Tilly&quot;</span><span class="op">))</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> animalSet<span class="op">:</span> <span class="ex">Set</span><span class="op">[</span>Animal<span class="op">]</span> <span class="op">=</span> catSet</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>animalSet<span class="op">.</span><span class="fu">add</span><span class="op">(</span><span class="fu">Dog</span><span class="op">(</span><span class="st">&quot;Richard&quot;</span><span class="op">))</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span>cat<span class="op">:</span> Cat <span class="op">&lt;-</span> catSet<span class="op">.</span><span class="fu">items</span><span class="op">())</span> <span class="op">{}</span>  <span class="co">// uh oh, one of the cats will actually be a dog!</span></span></code></pre></div><p>The same logic applies to the opposite situation. A <code>Set[Animal]</code> is not a <code>Set[Cat]</code>.</p>
<p>Here’s a Haskell class defining <code>Invariant</code> functors.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Invariant</span> f <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    invmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div><p>You have to be able to map <code>a</code>s and <code>b</code>s in both directions to convert an invariant functor. This implies that the functor both consumes and produces <code>a</code>s: you map items on the way out and on the way in.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Operation</span> a <span class="ot">=</span> <span class="dt">Operation</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a)</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Invariant</span> <span class="dt">Operation</span> <span class="kw">where</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    invmap f g (<span class="dt">Operation</span> op) <span class="ot">=</span> <span class="dt">Operation</span> (\x y <span class="ot">-&gt;</span> f (g x <span class="ot">`op`</span> g y))</span></code></pre></div><p>Note how we use <code>f</code> on the output of <code>op</code> and <code>g</code> on the inputs.</p>
<p>The only time I’ve actually seen this class used is in <a href="http://comonad.com/reader/2008/rotten-bananas/">Ed Kmett’s old article about attempting to represent higher-order abstract syntax generically</a>.</p>
<p>Let me spell out the similarity between <code>Invariant</code> functors and Scala’s subtype invariance. For <code>Operation a</code> to be convertible to <code>Operation b</code>, <code>a</code> must be convertible to <code>b</code> <em>and</em> <code>b</code> must be convertible to <code>a</code>. For <code>Set[A]</code> to be a subtype of <code>Set[B]</code>, <code>A</code> must be a subtype of <code>B</code> <em>and</em> <code>B</code> must be a subtype of <code>A</code> (that is, they must be the same type).</p>
<p>Note that variance is a property of the type parameter (<code>A</code>), not the type constructor (<code>List</code>/<code>Ordering</code>). A given type constructor may have multiple parameters with different variances. <code>Function1[-A, +B]</code>, for example.</p>
<img src="/images/2019-01-11-the-fourth-type-of-variance/hierarchy.png" />
<h2 id="combining-variances"><a href="#combining-variances">Combining Variances</a></h2>
<p>An object which produces a producer of <code>A</code>s effectively produces <code>A</code>s. A type with a covariant type as an output is itself covariant.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">// Container returns a covariant type, so Container is covariant</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> <span class="ex">Container</span><span class="op">[+</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">toList</span><span class="op">():</span> <span class="ex">List</span><span class="op">[</span>A<span class="op">]</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Consuming a producer of <code>A</code>s is basically the same as consuming <code>A</code>s. A type which has a covariant type as an input is contravariant.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">// Printer consumes a covariant type, so it&#39;s contravariant</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> Printer<span class="op">[-</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">printAll</span><span class="op">(</span>items<span class="op">:</span> <span class="ex">List</span><span class="op">[</span>A<span class="op">]):</span> <span class="bu">Unit</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Producing a consumer of <code>A</code>s is like consuming <code>A</code>s. A type with a contravariant type as an output is contravariant.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">// Produces a contravariant type, so contravariant</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> OrderingFactory<span class="op">[-</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">getOrdering</span><span class="op">():</span> Ordering<span class="op">[</span>A<span class="op">]</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>A consumer of consumers is itself a producer. (You have to be able to produce <code>A</code>s in order to feed them to the consumer.) A type with a contravariant type as an input is covariant.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">// Consumes a contravariant type, so covariant</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> Sortable<span class="op">[+</span>A<span class="op">]</span> <span class="op">{</span>  </span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">sortBy</span><span class="op">(</span>ordering<span class="op">:</span> Ordering<span class="op">[</span>A<span class="op">]):</span> <span class="bu">Unit</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Mnemonically, you can think of input parameters as meaning “times -1”. <code>Ordering</code> takes <code>A</code>s as its inputs, so <code>Ordering</code> is negative. <code>Sortable</code> takes a (negative) <code>Ordering</code> as an input, so it’s positive (-1 * -1 = 1). Printer takes a (positive) <code>List</code> as input, so it’s negative. This explains Scala’s choice of <code>+</code> and <code>-</code> as the syntax for its variance annotations.</p>
<h2 id="the-semilattice-of-variances"><a href="#the-semilattice-of-variances">The Semilattice of Variances</a></h2>
<p>Now, it turns out that these three types of variance have a relationship to each other. Invariance generalises both covariance and contravariance. Covariant things are also invariant, and contravariant things are also also invariant.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">defaultInvmapCo ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>defaultInvmapCo f _ x <span class="ot">=</span> <span class="fu">fmap</span> f x</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">defaultInvmapContra ::</span> <span class="dt">Contravariant</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>defaultInvmapContra _ g x <span class="ot">=</span> contramap g x</span></code></pre></div><p>If I was in the business of redesigning Haskell’s libraries, I’d even consider making <code>Invariant</code> a superclass of <code>Functor</code> and <code>Contravariant</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Invariant</span> f <span class="kw">where</span> <span class="co">{- ... -}</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Invariant</span> f <span class="ot">=&gt;</span> <span class="dt">Functor</span> f <span class="kw">where</span> <span class="co">{- ... -}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Invariant</span> f <span class="ot">=&gt;</span> <span class="dt">Contravariant</span> f <span class="kw">where</span> <span class="co">{- ... -}</span></span></code></pre></div><img src="/images/2019-01-11-the-fourth-type-of-variance/semilattice.jpg" />
<p>So there’s this interesting relationship between the three types of variance. They form a little semilattice, of which <code>Invariant</code> is the supremum.</p>
<p>But, hmm, the picture seems asymmetric. Is variance really only a semilattice? Or is there something lurking at the bottom of that picture?</p>
<h2 id="phantom-variance"><a href="#phantom-variance">Phantom Variance</a></h2>
<p>Looking at the code above, it appears that <code>Functor</code> and <code>Contravariant</code> both specialise <code>Invariant</code> by ignoring one of <code>Invariant</code>’s function parameters. What if we ignored both of them?</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (<span class="dt">Functor</span> f, <span class="dt">Contravariant</span> f) <span class="ot">=&gt;</span> <span class="dt">Phantom</span> f <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    pmap ::</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div><p>This strange class says that you can map an <code>f a</code> to an <code>f b</code> without needing to map <code>a</code>s or <code>b</code>s at all! Intuitively, you can only convert <code>f a</code> to <code>f b</code> for free when <code>f</code> doesn’t mention <code>a</code> anywhere in its body.</p>
<p>A functor is <code>Invariant</code> when it has <code>a</code>s both as inputs and outputs. <code>Functor</code> specialises <code>Invariant</code> by promising that <code>f</code> doesn’t have any input <code>a</code>s, so all you need to do is map the outputs. <code>Contravariant</code> specialises <code>Invariant</code> by promising that there are no output <code>a</code>s and all you need to do is map the inputs. <code>Phantom</code>, being a special case of both covariance and contravariance, guarantees that there are no <code>a</code>s at all in the <code>f</code>.</p>
<p>So the four types of variance form a nice lattice.</p>
<img src="/images/2019-01-11-the-fourth-type-of-variance/lattice.jpg" />
<p>For completeness, here’s the proof that the superclass constraints make sense:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">defaultFmap ::</span> <span class="dt">Phantom</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>defaultFmap _ <span class="ot">=</span> pmap</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">defaultContramap ::</span> <span class="dt">Phantom</span> f <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>defaultContramap _ <span class="ot">=</span> pmap</span></code></pre></div><p>Phantom types show up every now and then in Haskell. They’re used to decorate ordinary values with additional type-level information, either to layer on additional type safety or to give GHC a hint for type inference.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Proxy</span> a <span class="ot">=</span> <span class="dt">Proxy</span>  <span class="co">-- from Data.Proxy</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Phantom</span> <span class="dt">Proxy</span> <span class="kw">where</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    pmap _ <span class="ot">=</span> <span class="dt">Proxy</span></span></code></pre></div><p>Haskell is the only language I know of with proper support for phantom types, in its <a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#roles">role system</a>. (<code>Phantom</code> roughly means <code>forall a b. Coercible (f a) (f b)</code>.) Scala doesn’t support it, but it’d mean that a type is always a subtype of any other instantiation of that type, even if the type arguments have no relationship.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="kw">class</span> <span class="ex">Proxy</span><span class="op">[</span>±A<span class="op">]</span>  <span class="co">// fantasy syntax</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> catProxy <span class="op">=</span> <span class="ex">Proxy</span><span class="op">[</span>Cat<span class="op">]()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> dogProxy <span class="op">:</span> <span class="ex">Proxy</span><span class="op">[</span>Dog<span class="op">]</span> <span class="op">=</span> catProxy</span></code></pre></div><p><code>Proxy[A]</code> is always a subtype of <code>Proxy[B]</code> (and vice versa!), even when <code>A</code> and <code>B</code> are nothing to do with each other. To a certain extent this defeats the purpose of phantom types. It also breaks antisymmetry — two different types can both be a subtype of each other — so subtyping is no longer a partial order. As a language feature, phantom variance probably isn’t actually all that desirable.</p>

]]></summary>
</entry>
<entry>
    <title>Zooming In on Field Accessors</title>
    <link href="http://www.benjamin.pizza/posts/2018-12-06-zooming-in-on-field-accessors.html" />
    <id>http://www.benjamin.pizza/posts/2018-12-06-zooming-in-on-field-accessors.html</id>
    <published>2018-12-06T00:00:00Z</published>
    <updated>2018-12-06T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>It’s common in functional languages — and increasingly in hybrid languages like C# — to work with complex systems of immutable datatypes. For a contrived example, suppose you’re working on a billing application:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Order</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Customer Customer <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableList<span class="op">&lt;</span>Product<span class="op">&gt;</span> Products <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Customer</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Name <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Address Address <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Address</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Line1 <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Line2 <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Postcode <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Product</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Title <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">decimal</span> Price <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><img src="/images/2018-12-06-zooming-in-on-field-accessors/model.jpg" />
<p>(I’ve omitted the constructors; you can imagine your own.) These objects are immutable, meaning you can’t modify them directly. The way to update an immutable object is to make a copy of that object with the relevant properties changed. This turns out to be surprisingly tedious when you’re working inside a deeply nested structure:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>Order <span class="fu">UpdatePostcode</span><span class="op">(</span>Order order<span class="co">/*👨🏻‍⚖️*/</span><span class="op">,</span> <span class="dt">string</span> newPostcode<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">Order</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">Customer</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>            order<span class="op">.</span><span class="fu">Customer</span><span class="op">.</span><span class="fu">Name</span><span class="op">,</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span> <span class="fu">Address</span><span class="op">(</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>                order<span class="op">.</span><span class="fu">Customer</span><span class="op">.</span><span class="fu">Address</span><span class="op">.</span><span class="fu">Line1</span><span class="op">,</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>                order<span class="op">.</span><span class="fu">Customer</span><span class="op">.</span><span class="fu">Address</span><span class="op">.</span><span class="fu">Line2</span><span class="op">,</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                newPostcode</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">),</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        order<span class="op">.</span><span class="fu">Products</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>F#’s <code>with</code>-syntax helps a little, but not a lot. You still have to write each name multiple times.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> updatePostcode<span class="op">(</span>order : Order, newPostcode : <span class="dt">string</span><span class="op">)</span> : Order = <span class="op">{</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>  order <span class="kw">with</span> customer = <span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    order.customer <span class="kw">with</span> address = <span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>      order.customer.address <span class="kw">with</span> postcode = newPostcode</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>This pain is caused by immutability. In an imperative setting you can say <code>order.Customer.Address.Postcode = newPostcode;</code>, although of course mutable data is less reliable and harder to work with overall. Rather than give up on immutability, functional programmers have invented a remarkable family of composable tools called <em>optics</em> for poking around inside complex datatypes. Optics are a way of describing “paths” through structures: you can compose paths together, and read and write the values at the end of those paths. I’m here today to demonstrate that C#8’s upcoming <a href="https://github.com/dotnet/csharplang/issues/52"><em>default interface methods</em></a> are great at modelling optics.</p>
<p>Let’s start with <em>lenses</em>, the family member that gave the family its name.</p>
<h2 id="lenses"><a href="#lenses">Lenses</a></h2>
<p>A <em>lens</em> is a first-class property for an immutable object. It’s an object with a pair of methods, a <em>getter</em> which retrives the value of a property and a <em>setter</em> which updates it. Remember, we’re working with immutable data, so the setter returns a new copy of the object.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ILens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    TProp <span class="fu">Get</span><span class="op">(</span>T obj<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Set</span><span class="op">(</span>T oldObj<span class="op">,</span> TProp newVal<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>For example, here’s a lens which focuses on an <code>Order</code>’s <code>Customer</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> CustomerL <span class="op">:</span> ILens<span class="op">&lt;</span>Order<span class="op">,</span> Customer<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Customer <span class="fu">Get</span><span class="op">(</span>Order o<span class="op">)</span> <span class="op">=&gt;</span> o<span class="op">.</span><span class="fu">Customer</span><span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Order <span class="fu">Set</span><span class="op">(</span>Order o<span class="op">,</span> Customer c<span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">Order</span><span class="op">(</span>c<span class="op">,</span> o<span class="op">.</span><span class="fu">Products</span><span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><img src="/images/2018-12-06-zooming-in-on-field-accessors/customer.jpg" />
<p>So a lens picks out a single property inside a given object.</p>
<p>The power of lenses comes from their composability. Given a lens identifying a <code>T2</code> inside a <code>T1</code> (<code>ILens&lt;T1, T2&gt;</code>) and a lens identifying a <code>T3</code> inside a <code>T2</code> (<code>ILens&lt;T2, T3&gt;</code>), you can compose those lenses together to focus all the way from the <code>T1</code> to the <code>T3</code>.</p>
<p>You can traverse any relationship in your data model by composing together a small number of individual lenses. Composing lenses is so important that I’ve given it the shortest name I can think of: <code>_</code>. (Readers of <a href="2018-03-16-eighty.html">an earlier post of mine</a> will know of my fondness for <code>_</code>.)</p>
<img src="/images/2018-12-06-zooming-in-on-field-accessors/postcode.jpg" />
<p>Compare this terse, declarative code with the tedious version of <code>UpdatePostcode</code> from the beginning:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>Order <span class="fu">UpdatePostcode</span><span class="op">(</span>Order order<span class="co">/*👨🏻‍⚖️*/</span><span class="op">,</span> <span class="dt">string</span> newPostcode<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    ILens<span class="op">&lt;</span>Order<span class="op">,</span> <span class="dt">string</span><span class="op">&gt;</span> l <span class="op">=</span> <span class="kw">new</span> <span class="fu">CustomerL</span><span class="op">()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">_</span><span class="op">(</span><span class="kw">new</span> <span class="fu">AddressL</span><span class="op">())</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">_</span><span class="op">(</span><span class="kw">new</span> <span class="fu">PostcodeL</span><span class="op">());</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    </span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> l<span class="op">.</span><span class="fu">Set</span><span class="op">(</span>order<span class="op">,</span> newPostcode<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Lenses work without reference to any particular instance. (This is called <del><em>pointless</em></del> <a href="https://stackoverflow.com/questions/944446/what-is-point-free-style-in-functional-programming"><em>point-free</em></a> programming.) <code>order.Customer.Address.Postcode</code> becomes <code>new CustomerL()._(new AddressL())._(new PostcodeL())</code> — the path of properties is sort of detached from the object itself. Treating a path through a datatype as a first class value is the big idea behind lenses.</p>
<p>Here’s how <code>_</code> is implemented. It returns a new <code>ILens</code> (an instance of a private class) which delegates to the two smaller lenses.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">class</span> LensExtensions</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> ILens<span class="op">&lt;</span>T1<span class="op">,</span> T3<span class="op">&gt;</span> _<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">,</span> T3<span class="op">&gt;(</span><span class="kw">this</span> ILens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">&gt;</span> l1<span class="op">,</span> ILens<span class="op">&lt;</span>T2<span class="op">,</span> T3<span class="op">&gt;</span> l2<span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> ComposedLens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">,</span> T3<span class="op">&gt;(</span>l1<span class="op">,</span> l2<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">class</span> ComposedLens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">,</span> T3<span class="op">&gt;</span> <span class="op">:</span> ILens<span class="op">&lt;</span>T1<span class="op">,</span> T3<span class="op">&gt;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">private</span> <span class="kw">readonly</span> ILens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">&gt;</span> _l1<span class="op">;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">private</span> <span class="kw">readonly</span> ILens<span class="op">&lt;</span>T2<span class="op">,</span> T3<span class="op">&gt;</span> _l2<span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">public</span> T3 <span class="fu">Get</span><span class="op">(</span>T1 obj<span class="op">)</span> <span class="op">=&gt;</span> _l2<span class="op">.</span><span class="fu">Get</span><span class="op">(</span>_l1<span class="op">.</span><span class="fu">Get</span><span class="op">(</span>obj<span class="op">));</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">public</span> T1 <span class="fu">Set</span><span class="op">(</span>T1 oldObj<span class="op">,</span> T3 newVal<span class="op">)</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            <span class="op">=&gt;</span> _l1<span class="op">.</span><span class="fu">Set</span><span class="op">(</span>oldObj<span class="op">,</span> _l2<span class="op">.</span><span class="fu">Set</span><span class="op">(</span>_l1<span class="op">.</span><span class="fu">Get</span><span class="op">(</span>oldObj<span class="op">),</span> newVal<span class="op">));</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>To summarise, a lens is a way to focus on a small part of a big immutable structure. They’re like a first-class version of the <code>.</code> and <code>=</code> operators: you can compose lenses together to focus deeper, and upon focusing on a location you can get and set the value at that location.</p>
<h3 id="mapping-under-a-lens"><a href="#mapping-under-a-lens">Mapping under a lens</a></h3>
<p>A common pattern is to get a value from a lens, apply some sort of transformation to it, and then put it back where it was. The <code>Map</code> helper function wraps up this pattern:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ILens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    TProp <span class="fu">Get</span><span class="op">(</span>T obj<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Set</span><span class="op">(</span>T oldObj<span class="op">,</span> TProp newVal<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Map</span><span class="op">(</span>T oldObj<span class="op">,</span> Func<span class="op">&lt;</span>TProp<span class="op">,</span> TProp<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="fu">Set</span><span class="op">(</span>oldObj<span class="op">,</span> <span class="fu">transformer</span><span class="op">(</span><span class="fu">Get</span><span class="op">(</span>oldObj<span class="op">))).</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Here’s an early taste of a default interface implementation. The default, <em><code>Get</code>-then-<code>Set</code></em>, works correctly, but when you’re working with deeply stacked lenses it can be inefficient to walk the whole data structure twice. (This is especially true of <em>multi-lenses</em> — of which more later — which build and discard a large number of intermediate enumerables.) If <code>Map</code> were an extension method, it would be impossible for users to override it and provide a more efficient implementation.</p>
<hr />
<p>Powerful as they are, these lenses don’t quite scale up to cover all of the important ways to access data. Specifically, they don’t support computed properties or lists.</p>
<h2 id="getters"><a href="#getters">Getters</a></h2>
<p>How would you write a lens which focuses on a list’s <code>Count</code>? You can’t set <code>Count</code> directly - it measures the number of times you’ve added or removed something from the list. The only way to change the <code>Count</code> is to add or remove an item!</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> CountL<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> ILens<span class="op">&lt;</span>ImmutableList<span class="op">&lt;</span>T<span class="op">&gt;,</span> <span class="dt">int</span><span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> <span class="fu">Get</span><span class="op">(</span>ImmutableList<span class="op">&lt;</span>T<span class="op">&gt;</span> l<span class="op">)</span> <span class="op">=&gt;</span> l<span class="op">.</span><span class="fu">Count</span><span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> ImmutableList<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">Set</span><span class="op">(</span>ImmutableList<span class="op">&lt;</span>T<span class="op">&gt;</span> l<span class="op">,</span> <span class="dt">int</span> count<span class="op">)</span> <span class="op">=&gt;</span> <span class="co">/* ??? */</span><span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Clearly we need to separate the “getting” and “setting” reponsibilities of <code>ILens</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IGetter<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    TProp <span class="fu">Get</span><span class="op">(</span>T obj<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ILens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span> <span class="op">:</span> IGetter<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Set</span><span class="op">(</span>T oldObj<span class="op">,</span> TProp newVal<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>We don’t lose composability by doing this. You can still compose two getters to get a getter.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">class</span> LensExtensions</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> IGetter<span class="op">&lt;</span>T1<span class="op">,</span> T3<span class="op">&gt;</span> <span class="fu">_</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">this</span> IGetter<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">&gt;</span> g1<span class="op">,</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        IGetter<span class="op">&lt;</span>T2<span class="op">,</span> T3<span class="op">&gt;</span> g2</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">new</span> ComposedGetter<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">,</span> T3<span class="op">&gt;(</span>g1<span class="op">,</span> g2<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">class</span> ComposedGetter<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">,</span> T3<span class="op">&gt;</span> <span class="op">:</span> IGetter<span class="op">&lt;</span>T1<span class="op">,</span> T3<span class="op">&gt;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">private</span> <span class="kw">readonly</span> IGetter<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">&gt;</span> _g1<span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">private</span> <span class="kw">readonly</span> IGetter<span class="op">&lt;</span>T2<span class="op">,</span> T3<span class="op">&gt;</span> _g2<span class="op">;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">public</span> T3 <span class="fu">Get</span><span class="op">(</span>T1 obj<span class="op">)</span> <span class="op">=&gt;</span> _g2<span class="op">.</span><span class="fu">Get</span><span class="op">(</span>_g1<span class="op">.</span><span class="fu">Get</span><span class="op">(</span>obj<span class="op">));</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>If you compose a lens with a getter, you get a getter. This makes sense: if any part of a given path through a data structure is read-only, then the whole path must be read-only. It Just Works™ because <code>ILens</code> is a subtype of <code>IGetter</code>. Overload resolution takes care of it: you type <code>_</code> and the compiler picks the right return type based on the types of <code>_</code>’s arguments.</p>
<h2 id="multi-lenses"><a href="#multi-lenses">Multi-lenses</a></h2>
<p><code>ILens</code> focuses on a single part of a structure. Its <code>Get</code> method returns a single <code>TProp</code> and its <code>Set</code> method takes a single <code>TProp</code>. This means you can’t use lenses to, for example, update the price of all the products in an order.</p>
<p>Enter <em>multi-lenses</em>, also known as <em>traversals</em>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMultiLens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> <span class="fu">MultiGet</span><span class="op">(</span>T obj<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// newVals should be the same length as the list returned by MultiGet</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">MultiSet</span><span class="op">(</span>T oldObj<span class="op">,</span> IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> newVals<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Map</span><span class="op">(</span>T oldObj<span class="op">,</span> Func<span class="op">&lt;</span>TProp<span class="op">,</span> TProp<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="fu">MultiSet</span><span class="op">(</span>oldObj<span class="op">,</span> <span class="fu">MultiGet</span><span class="op">(</span>oldObj<span class="op">).</span><span class="fu">Select</span><span class="op">(</span>transformer<span class="op">)).</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>(Readers of <a href="2017-11-13-recursion-without-recursion.html">an earlier post</a> might recognise <code>IMultiLens</code> as a generalisation of <code>IRewriter</code>.) A multi-lens is like a lens which can hit more than one target. While a lens focuses on <em>exactly one</em> <code>TProp</code> inside a <code>T</code>, a multi-lens relaxes that restriction, focusing on <em>zero-or-many</em> <code>TProps</code> at once.</p>
<p>Here’s an example multi-lens which focuses on all of the <code>Product</code>s in an <code>Order</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> ProductsL <span class="op">:</span> IMultiLens<span class="op">&lt;</span>Order<span class="op">,</span> Product<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>Product<span class="op">&gt;</span> <span class="fu">MultiGet</span><span class="op">(</span>Order order<span class="op">)</span> <span class="op">=&gt;</span> order<span class="op">.</span><span class="fu">Products</span><span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    Order <span class="fu">MultiSet</span><span class="op">(</span>Order order<span class="op">,</span> IEnumerable<span class="op">&lt;</span>Product<span class="op">&gt;</span> newProducts<span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">Order</span><span class="op">(</span>order<span class="op">.</span><span class="fu">Customer</span><span class="op">,</span> newProducts<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><img src="/images/2018-12-06-zooming-in-on-field-accessors/products.jpg" />
<p>You can compose multi-lenses, too. If you have a multi-lens which finds $n$ <code>T2</code>s inside a <code>T1</code>, and a second multi-lens which finds $m$ <code>T3</code>s inside a <code>T2</code>, you can build a multi-lens which finds $nm$ <code>T3</code>s inside a <code>T1</code>. This works by looking through the second multi-lens at all $n$ of the first multi-lens’s targets.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> <span class="kw">class</span> LensExtensions</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">static</span> IMultiLens<span class="op">&lt;</span>T1<span class="op">,</span> T3<span class="op">&gt;</span> <span class="fu">_</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">this</span> IMultiLens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">&gt;</span> m1<span class="op">,</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        IMultiLens<span class="op">&lt;</span>T2<span class="op">,</span> T3<span class="op">&gt;</span> m2</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span> <span class="op">=&gt;</span> <span class="kw">new</span> ComposedMultiLens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">,</span> T3<span class="op">&gt;(</span>m1<span class="op">,</span> m2<span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="kw">class</span> ComposedMultiLens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">,</span> T3<span class="op">&gt;</span> <span class="op">:</span> IMultiLens<span class="op">&lt;</span>T1<span class="op">,</span> T3<span class="op">&gt;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">private</span> <span class="kw">readonly</span> IMultiLens<span class="op">&lt;</span>T1<span class="op">,</span> T2<span class="op">&gt;</span> _m1<span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">private</span> <span class="kw">readonly</span> IMultiLens<span class="op">&lt;</span>T2<span class="op">,</span> T3<span class="op">&gt;</span> _m2<span class="op">;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">public</span> IEnumerable<span class="op">&lt;</span>T3<span class="op">&gt;</span> <span class="fu">MultiGet</span><span class="op">(</span>T1 obj<span class="op">)</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            <span class="op">=&gt;</span> _m1<span class="op">.</span><span class="fu">MultiGet</span><span class="op">(</span>obj<span class="op">).</span><span class="fu">SelectMany</span><span class="op">(</span>_m2<span class="op">.</span><span class="fu">MultiGet</span><span class="op">);</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        <span class="kw">public</span> T1 <span class="fu">MultiSet</span><span class="op">(</span>T1 oldObj<span class="op">,</span> IEnumerable<span class="op">&lt;</span>T3<span class="op">&gt;</span> newVals<span class="op">)</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            IEnumerable<span class="op">&lt;</span>T2<span class="op">&gt;</span> <span class="fu">NewT2s</span><span class="op">()</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>                <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> x <span class="kw">in</span> _m1<span class="op">.</span><span class="fu">MultiGet</span><span class="op">(</span>oldObj<span class="op">))</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>                <span class="op">{</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>                    <span class="dt">var</span> chunkLength <span class="op">=</span> _m2<span class="op">.</span><span class="fu">MultiGet</span><span class="op">(</span>x<span class="op">).</span><span class="fu">Count</span><span class="op">();</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">yield</span> <span class="kw">return</span> _m2<span class="op">.</span><span class="fu">MultiSet</span><span class="op">(</span>x<span class="op">,</span> newVals<span class="op">.</span><span class="fu">Take</span><span class="op">(</span>chunkLength<span class="op">));</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>                    newVals <span class="op">=</span> newVals<span class="op">.</span><span class="fu">Skip</span><span class="op">(</span>chunkLength<span class="op">);</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> _m1<span class="op">.</span><span class="fu">MultiSet</span><span class="op">(</span>oldObj<span class="op">,</span> <span class="fu">NewT2s</span><span class="op">());</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><code>MultiSet</code> chops <code>newVals</code> into chunks that are the length of each group of descendants. This is safe as long as a user never calls <code>MultiSet</code> with a different number of elements than was returned by <code>MultiGet</code>.</p>
<p>So far we can compose multi-lenses on their own, but they don’t yet interoperate well with lenses. But note multi-lenses generalise lenses by relaxing the requirement that there should be exactly one substructure. Every lens is also a multi-lens by forgetting that there’s a single <code>TProp</code>. (Once again we’re relying on the assumption that the list does not change length in between <code>MultiGet</code> and <code>MultiSet</code> calls.)</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ILens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span> <span class="op">:</span> IMultiLens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    TProp <span class="fu">Get</span><span class="op">(</span>T obj<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Set</span><span class="op">(</span>T oldObj<span class="op">,</span> TProp newVal<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> <span class="fu">MultiGet</span><span class="op">(</span>T obj<span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> <span class="fu">Get</span><span class="op">(</span>obj<span class="op">)</span> <span class="op">};</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">MultiSet</span><span class="op">(</span>T oldObj<span class="op">,</span> IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> newVals<span class="op">)</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="fu">Set</span><span class="op">(</span>oldObj<span class="op">,</span> newVals<span class="op">.</span><span class="fu">Single</span><span class="op">());</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Inheriting from <code>IMultiLens</code> like this is just the same trick as inheriting from <code>IGetter</code>. It allows you to compose a lens with a multi-lens using <code>_</code>; the result will be a multi-lens.</p>
<p>If lenses are like a first-class <code>.</code>, then multi-lenses are like a first-class <code>Select</code>. Composing a lens onto the end of a multi-lens is like <code>Select</code>ing a field from each element of a list, with the added power of being able to write new values to the list. Like lenses, multi-lenses are point-free: you compose a multi-lens describing a path through a datatype, then apply that multi-lens to a specific instance of the datatype.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>Order <span class="fu">TwentyPercentOff</span><span class="op">(</span>Order order<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IMultiLens<span class="op">&lt;</span>Order<span class="op">,</span> <span class="dt">decimal</span><span class="op">&gt;</span> l <span class="op">=</span> <span class="kw">new</span> <span class="fu">ProductsL</span><span class="op">().</span><span class="fu">_</span><span class="op">(</span><span class="kw">new</span> <span class="fu">PriceL</span><span class="op">());</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> l<span class="op">.</span><span class="fu">Map</span><span class="op">(</span>order<span class="op">,</span> x <span class="op">=&gt;</span> x <span class="op">*</span> <span class="fl">0.8</span><span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><img src="/images/2018-12-06-zooming-in-on-field-accessors/product-and-price.jpg" />
<p>Incorporating the earlier <code>IGetter</code> fix, and extending <code>IMultiLens</code> upwards in parallel, leaves us with the following hierarchy.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMultiGetter<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> <span class="fu">MultiGet</span><span class="op">(</span>T obj<span class="op">);</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IMultiLens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span> <span class="op">:</span> IMultiGetter<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">MultiSet</span><span class="op">(</span>T oldObj<span class="op">,</span> IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> newVals<span class="op">);</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Map</span><span class="op">(</span>T oldObj<span class="op">,</span> Func<span class="op">&lt;</span>TProp<span class="op">,</span> TProp<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="fu">MultiSet</span><span class="op">(</span>oldObj<span class="op">,</span> <span class="fu">MultiGet</span><span class="op">(</span>oldObj<span class="op">).</span><span class="fu">Select</span><span class="op">(</span>transformer<span class="op">));</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IGetter<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span> <span class="op">:</span> IMultiGetter<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    TProp <span class="fu">Get</span><span class="op">(</span>T obj<span class="op">);</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> <span class="fu">MultiGet</span><span class="op">(</span>T obj<span class="op">)</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> <span class="fu">Get</span><span class="op">(</span>obj<span class="op">)</span> <span class="op">};</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> ILens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span> <span class="op">:</span> IGetter<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;,</span> IMultiLens<span class="op">&lt;</span>T<span class="op">,</span> TProp<span class="op">&gt;</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">Set</span><span class="op">(</span>T oldObj<span class="op">,</span> TProp newVal<span class="op">);</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">MultiSet</span><span class="op">(</span>T oldObj<span class="op">,</span> IEnumerable<span class="op">&lt;</span>TProp<span class="op">&gt;</span> newVals<span class="op">)</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="fu">Set</span><span class="op">(</span>oldObj<span class="op">,</span> newVals<span class="op">.</span><span class="fu">Single</span><span class="op">());</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><img src="/images/2018-12-06-zooming-in-on-field-accessors/hierarchy.jpg" />
<h2 id="default-interface-implementations"><a href="#default-interface-implementations">Default Interface Implementations</a></h2>
<p>The code above makes central use of default interface implementations, so it’s probably time to talk about what they are.</p>
<p>In C#8, interfaces won’t just be type declarations any more. You’ll be allowed to write code in an interface method, to function as the default implementation of that method. Typically it’ll be written in terms of the other methods on the interface, like an extension method. They differ from extension methods, however, in that they are virtual. If an implementing class has a better (faster, typically) way of implementing the operation, it’s free to override it.</p>
<p>Here’s an example. How would LINQ’s design look different if default interface methods had been around at the time? Today’s <a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.count"><code>Count</code></a> method, an extension method, works in linear time by counting up all of the elements of the input <code>IEnumerable</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> <span class="dt">int</span> Count<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> IEnumerable<span class="op">&lt;</span>T<span class="op">&gt;</span> source<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> count <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> _ <span class="kw">in</span> source<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        count<span class="op">++;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> count<span class="op">;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>However, there are certain implementations of <code>IEnumerable</code> which can count themselves much faster than that:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> List<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> IEnumerable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> T<span class="op">[]</span> _array<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> _count<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> Count <span class="op">=&gt;</span> _count<span class="op">;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p><a href="https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Count.cs">The real <code>Count</code> extension method</a> takes a fast path when its argument happens to be an <a href="https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.icollection-1?view=netframework-4.7.2"><code>ICollection</code></a>, but that doesn’t scale well. Not every <code>IEnumerable</code> which admits a fast <code>Count</code> can also implement <code>ICollection</code> — for example, an immutable collection can’t implement the <code>void Add(T item)</code> method.</p>
<p>If LINQ had been designed not as a collection of extension methods but as a collection of default interface methods, it’d be possible to override <code>Count</code> in an extensible way:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IEnumerable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IEnumerator<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">GetEnumerator</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="fu">Count</span><span class="op">()</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="dt">var</span> count <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> _ <span class="kw">in</span> source<span class="op">)</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            count<span class="op">++;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">return</span> count<span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="co">// other methods like Select etc</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> List<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">:</span> IEnumerable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> T<span class="op">[]</span> _array<span class="op">;</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> _count<span class="op">;</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    </span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="co">// override the default version from IEnumerable</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> <span class="fu">Count</span><span class="op">()</span> <span class="op">=&gt;</span> _count<span class="op">;</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Interfaces with default methods are somewhat like abstract classes with virtual methods. The main difference is that a class can implement multiple interfaces, while it can only derive from one class. So default interface implementations amount to a form of multiple inheritance! (This provoked much whingeing in <a href="https://github.com/dotnet/csharplang/issues/288">the discussion on GitHub</a>.)</p>
<p>The optics library I’ve outlined above makes central use of multiple inheritance. <code>ILens</code> inherits its <code>MultiGet</code> implementation from <code>IGetter</code> and its <code>Map</code> implementation from <code>IMultiLens</code>. So it wouldn’t work with abstract classes; before C#8 we wouldn’t have been able to write this program. Default interface implementations add new expressive power to the language.</p>
<h2 id="production-worthiness"><a href="#production-worthiness">Production-Worthiness</a></h2>
<p>Lenses are very useful in functional languages, but I would not recommend you use them in practical C#, even after the release of C#8. When you stand it next to <a href="http://hackage.haskell.org/package/lens">Haskell’s <code>lens</code> library</a>, the API I outlined above has a number of significant shortcomings.</p>
<ul>
<li>
<p><strong>Performance</strong>. The big one! Accessing a field is such a common operation that it’d better be fast. The <code>.</code> operator (<code>order.Customer.Address.Postcode</code>) is very fast on the CLR — just a pointer hop. Composed lenses, on the other hand, are tree-shaped objects, and calling <code>Get</code> means traversing that tree with a interface method call at each level. I ran some rudimentary benchmarks and found deeply nested lenses to be orders of magnitude slower than equivalent lensless code.</p>
<p>The <code>lens</code> library sidesteps this performance issue by leaning on Haskell’s optimising compiler. <code>lens</code> has been carefully designed to be easy for GHC to optimise, and the result is that GHC generally produces identical machine code for equivalent lensy and lensless functions.</p>
</li>
<li>
<p><strong>Code generation</strong>. Almost all of the atomic lens classes you’d write for a business system are pure boilerplate — exactly the sort of thing you’d expect a machine to write. You should be able to define an object, perhaps mark it up using an attribute, and get on with using lenses into that object in the rest of your program, with Intellisense support. You shouldn’t ever need to see a lens’s source code. Roslyn, the C# compiler, has no facilities for compile-time code injection like this. A lens library could bundle a source code generator, perhaps using Roslyn’s API, which users run ahead-of-time — many ORMs do this — but that’s a much less compelling user experience.</p>
<p>This may be a good use case for F#’s type providers. (In any case F# places more emphasis on immutability than C#, making lenses a more natural fit in the first place.) Presently you can’t use a type provider to generate code based on another type (though <a href="https://github.com/fsharp/fslang-design/issues/125">it appears to be planned</a>), and <a href="https://github.com/fsharp/fslang-suggestions/issues/679#issuecomment-399411192">there don’t seem to be plans</a> to support multiple inheritance in the F# source language. In principle one could implement the hierarchy in C# and consume it from an F# type provider.</p>
</li>
<li>
<p>Two ergonomic complaints regarding C#’s support for <strong>generics</strong>:</p>
<ul>
<li>
<p><strong>Type inference</strong>. C# has only minimal support for type inference. This makes generic lenses unpleasant to use. The following lens picks out a <code>KeyValuePair</code>’s <code>Value</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> ValueL<span class="op">&lt;</span>K<span class="op">,</span> V<span class="op">&gt;</span> <span class="op">:</span> ILens<span class="op">&lt;</span>KeyValuePair<span class="op">&lt;</span>K<span class="op">,</span> V<span class="op">&gt;,</span> V<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> V <span class="fu">Get</span><span class="op">(</span>KeyValuePair<span class="op">&lt;</span>K<span class="op">,</span> V<span class="op">&gt;</span> kvp<span class="op">)</span> <span class="op">=&gt;</span> kvp<span class="op">.</span><span class="fu">Value</span><span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> KeyValuePair<span class="op">&lt;</span>K<span class="op">,</span> V<span class="op">&gt;</span> <span class="fu">Set</span><span class="op">(</span>KeyValuePair<span class="op">&lt;</span>K<span class="op">,</span> V<span class="op">&gt;</span> kvp<span class="op">,</span> V val<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> KeyValuePair<span class="op">&lt;</span>K<span class="op">,</span> V<span class="op">&gt;(</span>kvp<span class="op">.</span><span class="fu">Key</span><span class="op">,</span> val<span class="op">);</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>You can’t use <code>ValueL</code> without explicitly mentioning the concrete type parameters at which you’re using it:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">new</span> ValueL<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> <span class="dt">int</span><span class="op">&gt;().</span><span class="fu">Set</span><span class="op">(</span><span class="kw">new</span> KeyValuePair<span class="op">&lt;</span><span class="dt">string</span><span class="op">,</span> <span class="dt">int</span><span class="op">&gt;(</span><span class="st">&quot;foo&quot;</span><span class="op">,</span> <span class="dv">3</span><span class="op">),</span> <span class="dv">7</span><span class="op">);</span></span></code></pre></div><p>Ideally the compiler would be able to deduce the <code>&lt;string, int&gt;</code> part by noticing that we’re using it on a <code>KeyValuePair&lt;string, int&gt;</code>. This is difficult to implement in a subtyping-based language, though.</p>
</li>
<li>
<p><strong>Generic type aliases</strong>. <a href="http://comonad.com/reader/2012/mirrored-lenses/">The most general formulation of lenses</a> actually has <em>four</em> type parameters: <code>ILens&lt;in S, out T, out A, in B&gt;</code>! This is to support lenses into generic types, allowing you to change the type of the resulting structure by writing a different type into the lens. (<code>new ValueL().Set(new KeyValuePair&lt;string, string&gt;(&quot;foo&quot;, &quot;bar&quot;), 3)</code> should return a <code>KeyValuePair&lt;string, int&gt;</code> — that is, a new <code>KeyValuePair</code> with a different type to the original.)</p>
<p>The old <code>ILens&lt;S, A&gt;</code> is then equivalent to <code>ILens&lt;S, S, A, A&gt;</code>. Ideally we’d be able to define a <em>type alias</em>, so that you can type <code>ILens&lt;S, A&gt;</code> for <code>ILens&lt;S, S, A, A&gt;</code>, but C# doesn’t support this. (<a href="https://github.com/dotnet/roslyn/issues/3993">A modest proposed extension to <code>using</code></a> would largely service this complaint, reducing the noise to a few lines of boilerplate at the top of each file.)</p>
</li>
</ul>
</li>
<li>
<p><strong>Noisy syntax</strong>. Haskell allows you to define custom symbolic operators, and <code>lens</code> ships a large collection of operators to debigulate your code. <code>new CustomerL()._(new AddressL())._(new PostcodeL()).Get(order)</code> is clunky in comparison to Haskell’s cute OO-style <code>order^.customer.address.postcode</code>.</p>
<ul>
<li>Related to this concern is <strong>namespacing</strong>. Above I’ve used a convention of appending the letter <code>L</code> to lens classes (<code>CustomerL</code>), but that starts to break down when you have more than one property with the same name in your system. One option might be to nest the lenses inside the objects themselves and import them with <code>using static</code>.
</li>
</ul>
</li>
<li>
<p><strong>Platform compatibility</strong>. According to <a href="https://blogs.msdn.microsoft.com/dotnet/2018/11/12/building-c-8-0/">a recent announcement</a>, default interface implementations are only going to be available on .NET Core, and won’t be in the desktop framework for the foreseeable future. As I understand it, the desktop CLR’s stringent backwards compatibility requirements make testing a wide-reaching CLR feature like this difficult and expensive. But to me, a library author, this is a very disappointing development: libraries <em>must</em> support the desktop CLR if they expect to have any users, so locking down features designed for library authors seems like a misfire. I’d prefer it if Microsoft just said directly that the desktop framework is being sunsetted — that way I’d at least have some ammunition for GitHub issues.</p>
</li>
</ul>
<p>All that said, there are a couple of things which I find preferable about this design when compared to <code>lens</code>. Haskell doesn’t feature subtyping directly, so <code>lens</code> uses a clever function-based encoding of its type hierarchy, using the type class solver to handle the various subtype relationships. Encoding lenses as functions is partly why <code>lens</code> is so fast, but it does make for a steep learning curve and notoriously confusing type errors. Using a more direct representation of subtyping means the model is clearer, and it’s easier to see how one would slot (eg) prisms or indexed lenses into the system I outlined above. What’s more, the four-parameter version of <code>ILens</code> I mentioned above is variously co- and contra-variant in its parameters, meaning it interoperates well with the rest of C#’s type hierarchy. In some sense these lenses are <em>more</em> composable than <code>lens</code>’s lenses.</p>
<p>I’d love to tell you I’ve written this up as a published library, but the shortfalls I noted above make this formulation of lenses impractical for real-world use. I’d love to hear your ideas on how to improve the situation! In the meantime, I bagsie the name <code>OptiCS</code>.</p>

]]></summary>
</entry>
<entry>
    <title>Live-streaming</title>
    <link href="http://www.benjamin.pizza/posts/2018-07-16-live-streaming.html" />
    <id>http://www.benjamin.pizza/posts/2018-07-16-live-streaming.html</id>
    <published>2018-07-16T00:00:00Z</published>
    <updated>2018-07-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>My esteemed colleague <a href="https://twitter.com/g3rv4?lang=en">Gervasio</a> and I have arranged to live-stream some programming <del>this Friday, the 20th of July</del> <strong>Update</strong>: we’ve decided to move it to next <strong>Tuesday, the 24th</strong>, at 2PM BST. We’re going to be working on adding some basic <code>Span</code> support to <a href="https://github.com/benjamin-hodgson/Pidgin">my parsing library</a>, and it’s going to involve <code>unsafe</code> and custom IL, which should be a bit of fun.</p>
<p>The stream will be <a href="https://www.youtube.com/watch?v=O23OLkQtiS4">on YouTube</a> and we’re planning to start at 2PM BST. Hope to see you there with your questions!</p>

]]></summary>
</entry>
<entry>
    <title>Eighty</title>
    <link href="http://www.benjamin.pizza/posts/2018-03-16-eighty.html" />
    <id>http://www.benjamin.pizza/posts/2018-03-16-eighty.html</id>
    <published>2018-03-16T00:00:00Z</published>
    <updated>2018-03-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>HTML templating systems are great but they sure are complex. ASP.NET’s Razor, for example, is a whole new programming language! While Razor does happen to have a large chunk of C# embedded within it, and it works by generating and then compiling C# code, it’s still a separate language with a separate syntax, separate abstraction techniques, separate compiler tooling, a separate file type, and separate (and usually inferior) editor support. All this for a task as simple and common as generating HTML!</p>
<p>This overhead can be worth it if you’re building a complex web application, but for simple tools such as report generators or email batch mailers Razor is unwieldy. Many people in these situations resort to generating their own HTML, either by building strings manually or by imperatively building tags using .NET’s supplied XML manipulation APIs. But there’s a whole world of possible designs out there, and there’s a lot of space in between “complex templating language” and “build strings by hand”.</p>
<h2 id="eighty"><a href="#eighty">Eighty</a></h2>
<p><a href="https://github.com/benjamin-hodgson/Eighty">Eighty</a> (as in <em>eigh-ty-M-L</em>) is my attempt at striking a balance between these two extremes: not so abstract as to constitute a separate programming language, but not so concrete that you have to manipulate XML tags or strings manually. It’s a simple embedded domain-specific language which piggybacks on C#’s syntax, enabling you to write code resembling the HTML you’re generating. Rather than embedding C# into an HTML generator, Eighty embeds an HTML generator into C#.</p>
<p>Here’s an example from <a href="https://github.com/benjamin-hodgson/Eighty/blob/master/README.md">the readme</a>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> html <span class="op">=</span> <span class="fu">article</span><span class="op">(</span>@class<span class="op">:</span> <span class="st">&quot;readme&quot;</span><span class="op">).</span><span class="fu">_</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">h1</span><span class="op">(</span>id<span class="op">:</span> <span class="st">&quot;Eighty&quot;</span><span class="op">).</span><span class="fu">_</span><span class="op">(</span><span class="st">&quot;Eighty&quot;</span><span class="op">),</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">p_</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;Eighty (as in &quot;</span><span class="op">,</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="fu">i_</span><span class="op">(</span><span class="st">&quot;eigh-ty-M-L&quot;</span><span class="op">),</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="st">&quot;) is a simple HTML generation library.&quot;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">);</span></span></code></pre></div><p>Eighty is organised around <a href="https://www.benjamin.pizza/Eighty/v1.2.0/api/Eighty.Html.html">the <code>Html</code> class</a>, being an immutable chunk of HTML which knows how to render itself using <a href="https://www.benjamin.pizza/Eighty/v1.2.0/api/Eighty.Html.html#Eighty_Html_Write_System_IO_TextWriter_">its <code>Write(TextWriter)</code> method</a>. <code>Html</code> defines a large collection of static methods (designed to be imported with <code>using static</code>), with names like <a href="https://www.benjamin.pizza/Eighty/v1.2.0/api/Eighty.Html.html#Eighty_Html_h1_System_String_System_String_System_String_System_String_System_String_System_String_"><code>h1</code></a> and <a href="https://www.benjamin.pizza/Eighty/v1.2.0/api/Eighty.Html.html#Eighty_Html_p_System_String_System_String_System_String_System_String_System_String_System_String_"><code>p</code></a>, which create <code>Html</code> values representing their respective tags, with a collection of children which are smaller <code>Html</code> values.</p>
<p>Eighty adopts some simple conventions for its HTML-esque domain-specific language:</p>
<ul>
<li>Tags are created using (lower-case) methods like <code>p()</code> and <code>i()</code>.
</li>
<li>Attributes are passed as optional named arguments: <code>a(href: &quot;benjamin.pizza&quot;, @class: &quot;website-link&quot;)</code>. I can’t force you to name your arguments — you could pass them positionally — but that’s not a good idea.
</li>
<li>A tag’s children are introduced using the <code>_</code> character, which can appear at the end of a method name or as a method name all by itself. <code>a(href: &quot;benjamin.pizza&quot;)._(&quot;Visit my website&quot;)</code> creates an <code>a</code> tag with an <code>href</code> attribute and some text inside it; <code>p_(&quot;a paragraph of text&quot;)</code> represents a <code>p</code> tag with some text but no attributes. I chose <code>_</code> because it’s the least noisy character that can be used as an identifier in C#.
</li>
<li>Strings can be implicitly converted to <code>Html</code> and are interpreted as HTML text. Text is HTML-encoded by default. You can opt out of this using the <code>Raw</code> method.
</li>
</ul>
<h2 id="eighty-vs-razor"><a href="#eighty-vs-razor">Eighty vs Razor</a></h2>
<p>Of course, C# code will only ever look <em>a bit</em> like HTML. Razor code looks much more like HTML than this! This can be a drawback when you’re working with designers who want to read and write HTML — I’m planning to write a tool to convert HTML text into an Eighty expression to partially ease this pain point. But Eighty has two big advantages which make it simpler and easier than Razor to program with:</p>
<ol>
<li>It plugs into your existing system. You don’t require any extra tools to work with Eighty: if you can compile C#, you can use Eighty.
</li>
<li>Programming with Eighty is <em>just programming</em>. <code>Html</code> instances are plain old immutable CLR objects, so you can use all your favourite techniques for abstraction and code reuse.
</li>
</ol>
<p>To illustrate the second point, here are some examples of how you might emulate some of Razor’s programming constructs using Eighty. In many of these cases Eighty does a better job than Razor of allowing abstraction and code reuse, because Eighty is embedded within C# rather than layered on top of C#.</p>
<h3 id="models"><a href="#models">Models</a></h3>
<p>In Razor, each view file you write declares a <em>model type</em> — the type of object it expects you to pass in to direct the generation of HTML. You use the <code>@model</code> directive at the top of your file, and then you can access members of the model in your Razor code.</p>
<pre><code class="language-cshtml">@model ExampleModel

&lt;h1&gt;@Model.Title&lt;/h1&gt;
</code></pre>
<p>One important disadvantage of Razor’s <code>@model</code> construct is that it is dynamically checked. The controller’s <code>View</code> method takes an <code>object</code> for the <code>model</code> parameter. You get a runtime error, without any feedback from the compiler, if you pass in a model whose type doesn’t match the view’s expected model type.</p>
<p>Since Eighty is embedded within C#, there’s no special syntax to declare the type of data a function depends on. You can just use a plain old parameter.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>Html <span class="fu">Example</span><span class="op">(</span>ExampleModel model<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">h1_</span><span class="op">(</span>model<span class="op">.</span><span class="fu">Title</span><span class="op">);</span></span></code></pre></div><p>Since a template is a regular C# method, it’s much easier to run in a unit test harness than Razor. You can just call the method and make assertions about the generated HTML, either by looking at the string directly or by parsing it and traversing the resultant DOM.</p>
<p>Eighty includes <a href="https://www.benjamin.pizza/Eighty/v1.2.0/api/Eighty.IHtmlRenderer-1.html">an <code>IHtmlRenderer&lt;TModel&gt;</code> interface</a>, which captures this pattern of parameterising a chunk of HTML by a model, but its use is optional — it’s used primarily by Eighty’s ASP.NET integration packages.</p>
<h3 id="control-flow"><a href="#control-flow">Control flow</a></h3>
<p>Razor allows you to mix markup with C#’s control flow constructs such as <code>foreach</code> and <code>if</code>. Here’s a simple example of populating a <code>ul</code> based on a list of values:</p>
<pre><code class="language-cshtml">&lt;ul&gt;
    @foreach (var item in Model.Items)
    {
        if (item.Visible)
        {
            &lt;li&gt;@item.Value&lt;/li&gt;
        }
    }
&lt;/ul&gt;
</code></pre>
<p>With Eighty, it’s a question of building different <code>Html</code> values. You can use LINQ’s high-level functional looping constructs:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">return</span> <span class="fu">ul_</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    model<span class="op">.</span><span class="fu">Items</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Where</span><span class="op">(</span>item <span class="op">=&gt;</span> item<span class="op">.</span><span class="fu">Visible</span><span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>item <span class="op">=&gt;</span> <span class="fu">li_</span><span class="op">(</span>item<span class="op">.</span><span class="fu">Value</span><span class="op">))</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">);</span></span></code></pre></div><p>Or you can write your own loop and build a list:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="dt">var</span> lis <span class="op">=</span> <span class="kw">new</span> List<span class="op">&lt;</span>Html<span class="op">&gt;();</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> item <span class="kw">in</span> model<span class="op">.</span><span class="fu">Items</span><span class="op">)</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">if</span> <span class="op">(</span>item<span class="op">.</span><span class="fu">Visible</span><span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        lis<span class="op">.</span><span class="fu">Add</span><span class="op">(</span><span class="fu">li_</span><span class="op">(</span>item<span class="op">.</span><span class="fu">Value</span><span class="op">));</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="kw">return</span> <span class="fu">ul_</span><span class="op">(</span>lis<span class="op">);</span></span></code></pre></div><p>Mixing markup with C# is not a problem, because markup <em>is</em> C#.</p>
<h3 id="partials-and-helpers"><a href="#partials-and-helpers">Partials and Helpers</a></h3>
<p>Razor’s two main tools for code reuse are <em>partial views</em> and <em>helpers</em>. For the purposes of this article, they’re roughly equivalent. Partial views can be returned directly from a controller but their model type is checked at runtime, whereas helpers’ parameters are checked by the compiler but they can only be invoked from within a Razor view.</p>
<p>Eighty handles both of these uses in the simplest of ways: <em>calling a function</em>. If I want to include an HTML snippet in more than one place, I can just extract it into a method returning an <code>Html</code> object. Transliterating an example from <a href="https://docs.microsoft.com/en-us/aspnet/web-pages/overview/ui-layouts-and-themes/creating-and-using-a-helper-in-an-aspnet-web-pages-site">the MVC documentation</a>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>Html <span class="fu">MakeNote</span><span class="op">(</span><span class="dt">string</span> content<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">div</span><span class="op">(</span>@class<span class="op">:</span> <span class="st">&quot;note&quot;</span><span class="op">).</span><span class="fu">_</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="fu">p_</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>            <span class="fu">strong_</span><span class="op">(</span><span class="st">&quot;Note&quot;</span><span class="op">),</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            <span class="fu">Raw</span><span class="op">(</span><span class="st">&quot;&amp;nbsp;&amp;nbsp; &quot;</span><span class="op">),</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            content</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>Html <span class="fu">SomeHtmlContainingANote</span><span class="op">()</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">article_</span><span class="op">(</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="fu">p_</span><span class="op">(</span><span class="st">&quot;This is some opening paragraph text&quot;</span><span class="op">),</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="fu">MakeNote</span><span class="op">(</span><span class="st">&quot;My test note content&quot;</span><span class="op">),</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="fu">p_</span><span class="op">(</span><span class="st">&quot;This is some following text&quot;</span><span class="op">)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>This is the best of both worlds: types are checked by the compiler as usual, but the returned <code>Html</code> value is a perfectly good standalone chunk of HTML, and can be rendered separately if necessary.</p>
<p><code>Html</code> values being ordinary C# values, Eighty actually supports more types of reuse than Razor does. For example, you can pass a chunk of HTML as an argument, which is not easy to do with Razor:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>Html <span class="fu">RepeatFiveTimes</span><span class="op">(</span>Html html<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">_</span><span class="op">(</span>Enumerable<span class="op">.</span><span class="fu">Repeat</span><span class="op">(</span>html<span class="op">,</span> <span class="dv">5</span><span class="op">));</span></span></code></pre></div><p>Since <code>Html</code> values are immutable, you can safely share them between different HTML documents, across different threads, etc. Sharing parts of your HTML document that don’t change can be an important optimisation.</p>
<h3 id="layouts"><a href="#layouts">Layouts</a></h3>
<p>Razor lets you define a shared <em>layout</em> page, which acts as a template for the other pages in your application. For example, you might put the <code>html</code> and <code>body</code> tags in a layout page, and use the built in <code>RenderBody</code> helper to render the concrete page’s body inside the <code>body</code> tag. This is also where global navs and the like are defined.</p>
<p>One way to handle global layouts and sections in Eighty would be to define an abstract base class. Each section becomes an abstract method, allowing individual pages to fill in their own HTML for those sections.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> Layout</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> Html <span class="fu">GetHtml</span><span class="op">()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="fu">doctypeHtml_</span><span class="op">(</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            <span class="fu">head</span><span class="op">(</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>                <span class="fu">link</span><span class="op">(</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>                    rel<span class="op">:</span> <span class="st">&quot;stylesheet&quot;</span><span class="op">,</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                    type<span class="op">:</span> <span class="st">&quot;text/css&quot;</span><span class="op">,</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>                    href<span class="op">:</span> <span class="st">&quot;default.css&quot;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>                <span class="op">),</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>                <span class="fu">Css</span><span class="op">(),</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                <span class="fu">script</span><span class="op">(</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>                    type<span class="op">:</span> <span class="st">&quot;text/javascript&quot;</span><span class="op">,</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                    src<span class="op">:</span> <span class="st">&quot;jquery-3.3.1.min.js&quot;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                <span class="op">),</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                <span class="fu">Js</span><span class="op">()</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>            <span class="op">),</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="fu">body</span><span class="op">(</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>                <span class="fu">Body</span><span class="op">()</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>            <span class="op">)</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>        <span class="op">);</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">protected</span> <span class="kw">abstract</span> Html <span class="fu">Css</span><span class="op">();</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">protected</span> <span class="kw">abstract</span> Html <span class="fu">Js</span><span class="op">();</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">protected</span> <span class="kw">abstract</span> Html <span class="fu">Body</span><span class="op">();</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Then, inheriting a layout is as easy as inheriting a class.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> DashboardPage <span class="op">:</span> Layout</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> DashboardModel _model<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="fu">Dashboard</span><span class="op">(</span>DashboardModel model<span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        _model <span class="op">=</span> model<span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">protected</span> <span class="kw">override</span> Html <span class="fu">Css</span><span class="op">()</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="co">/* Dashboard-specific CSS */</span><span class="op">;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">protected</span> <span class="kw">override</span> Html <span class="fu">Js</span><span class="op">()</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="co">/* Dashboard-specific scripts */</span><span class="op">;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">protected</span> <span class="kw">override</span> Html <span class="fu">Body</span><span class="op">()</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="co">/* The body of the dashboard page */</span><span class="op">;</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><h2 id="twenty"><a href="#twenty">Twenty</a></h2>
<p>Eighty comes bundled with a second HTML generation library called Twenty. Twenty is harder to use correctly than Eighty, and its API is more verbose, but it’s faster.</p>
<p>HTML tags have to be balanced: every opening tag has to have a matching closing tag and vice versa. While an <code>Html</code> value is being written to a <code>TextWriter</code>, Eighty manages the stack of currently-open tags using the call stack. Each tag writes its opening tag, tells its children to write themselves, and then writes its closing tag. This is possible because <code>Html</code> is an ordinary reference type; the objects you build with methods like <code>p()</code> and <code>h1()</code> are tree-shaped objects representing a DOM of statically-unknown size.</p>
<p>Twenty instead takes an imperative view of HTML generation. Each tag method writes an opening tag to the <code>TextWriter</code> immediately, and returns an <code>IDisposable</code> which writes out the closing tag when it’s disposed. You, the programmer, use C#’s <code>using</code> statement to ensure that the <code>Dispose</code> method is called as soon as the children have been written. The structure of your HTML document is still visible in the code, but it’s present in the nesting of <code>using</code> statements, rather than by the structure of a tree-shaped object.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> MyHtmlBuilder <span class="op">:</span> HtmlBuilder</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">protected</span> <span class="kw">override</span> <span class="dt">void</span> <span class="fu">Build</span><span class="op">()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">using</span> <span class="op">(</span><span class="fu">article</span><span class="op">(</span>@class<span class="op">:</span> <span class="st">&quot;readme&quot;</span><span class="op">))</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">using</span> <span class="op">(</span><span class="fu">h1</span><span class="op">(</span>id<span class="op">:</span> <span class="st">&quot;Eighty&quot;</span><span class="op">))</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                <span class="fu">Text</span><span class="op">(</span><span class="st">&quot;Eighty&quot;</span><span class="op">);</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">using</span> <span class="op">(</span><span class="fu">p</span><span class="op">())</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>                <span class="fu">Text</span><span class="op">(</span><span class="st">&quot;Eighty (as in &quot;</span><span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                <span class="kw">using</span> <span class="op">(</span><span class="fu">i</span><span class="op">())</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>                    <span class="fu">Text</span><span class="op">(</span><span class="st">&quot;eigh-ty-M-L&quot;</span><span class="op">);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                <span class="fu">Text</span><span class="op">(</span><span class="st">&quot;) is a simple HTML generation library.&quot;</span><span class="op">);</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Perhaps this is a bit of an abuse of <code>IDisposable</code>, and the <code>using</code> syntax is comparatively noisy, but this trick allows Twenty to operate quickly and without generating any garbage while still making for a reasonable DSL. Compared to Eighty, Twenty does lose out on some flexibility and safety:</p>
<ul>
<li>You mustn’t forget a <code>using</code> statement, or call <code>Dispose</code> more than once, or Twenty will output malformed HTML. Eighty, on the other hand, will never generate bad HTML (notwithstanding the use of <code>Raw</code>).
</li>
<li>There’s no <code>Html</code> object — you can’t pass around chunks of HTML as first class values. This makes code reuse and abstraction somewhat more difficult.
</li>
<li><code>HtmlBuilder</code> is not re-entrant. You can’t use the same <code>HtmlBuilder</code> from multiple threads.
</li>
<li>There’s no <code>async</code> API, because there’s no way to call <code>Dispose</code> asynchronously.
</li>
</ul>
<p>Given Twenty’s limitations, my advice is to write your markup using <code>Html</code>, and convert it to <code>HtmlBuilder</code> if you see that building <code>Html</code> values is a performance bottleneck.</p>
<h2 id="performance"><a href="#performance">Performance</a></h2>
<p>Eighty is pretty fast. I wrote a benchmark testing how long it takes to spit out around 30kB of HTML (with some encoding characters thrown in for good measure) while running in an in-memory hosted MVC application. Eighty’s synchronous code path does this around three times faster than Razor, and Twenty runs about 30% faster than that — so, four times faster than Razor.</p>
<p>What have I done to make Eighty fast? Honestly, not a huge amount. There are a only few interesting optimisations in Eighty’s codebase.</p>
<ul>
<li>Each call to <code>TextWriter</code>’s <code>Write</code> method is comparatively expensive, so rather than write individual snippets of HTML into the <code>TextWriter</code> directly, Eighty builds up a 4kB buffer and empties it out into the <code>TextWriter</code> when it fills up. The code to fill this buffer is a little fiddly, because you don’t know how long your input string is going to be after HTML-encoding it, so the HTML encoder has to write the encoded HTML in chunks. I toyed with a hand-written encoder, but I wanted to interoperate with ASP.NET’s pluggable <code>HtmlEncoder</code>, so I ended up calling that class’s low-level API.
<ul>
<li>The buffer is managed by <a href="https://github.com/benjamin-hodgson/Eighty/blob/3c431c13200022bb34ee3de635cce305384abef5/Eighty/HtmlEncodingTextWriter.cs">a mutable struct</a> which is <a href="https://github.com/benjamin-hodgson/Eighty/blob/3c431c13200022bb34ee3de635cce305384abef5/Eighty/Html.cs#L61-L63">stored on the stack and passed by reference</a> because mutable structs must never be copied. However, <a href="https://github.com/benjamin-hodgson/Eighty/blob/3c431c13200022bb34ee3de635cce305384abef5/Eighty/AsyncHtmlEncodingTextWriter.cs">the async version</a> <em>cannot</em> be a struct because <code>async</code> methods copy their <code>this</code> variable into a field behind the scenes. My first version of the code used the same mutable struct for both paths, which caused me some head-scratching when the <code>async</code> version didn’t work!
</li>
<li>There’s <a href="https://github.com/benjamin-hodgson/Eighty/blob/3c431c13200022bb34ee3de635cce305384abef5/Eighty/Twenty/HtmlEncodingTextWriterReference.cs">a fun and dangerous hack</a> in Twenty’s codebase to allow storing a reference to one of these stack-allocated structs <a href="https://github.com/benjamin-hodgson/Eighty/blob/3c431c13200022bb34ee3de635cce305384abef5/Eighty/Twenty/HtmlBuilder.cs">in a field</a>. This is safe as long as the reference in the field doesn’t live longer than the stack location to which it refers, but you don’t get any compile-time feedback about this (I just have to program carefully and hope I don’t make a mistake). This hack makes critical use of C# 7’s “<code>ref</code> return types”, so it wouldn’t have been possible a couple of years ago.
</li>
</ul>
</li>
<li>Calling an <code>async</code> method is comparatively expensive, even if it never goes async, because of the way <code>async</code> methods are translated by the compiler into code which builds and then executes a state machine. In the case of Eighty’s frequently-called <a href="https://github.com/benjamin-hodgson/Eighty/blob/3c431c13200022bb34ee3de635cce305384abef5/Eighty/AsyncHtmlEncodingTextWriter.cs#L149"><code>WriteRawImpl</code> method</a>, it’s predictable whether a call will complete synchronously (that is, without calling the underlying <code>TextWriter</code>’s <code>WriteAsync</code> method). <a href="https://github.com/benjamin-hodgson/Eighty/commit/1d6b5f45919363c978de05a5a849835cec6a773b#diff-c3aed398c4361803494b9d59237185e2">I split the <code>async</code> method into two parts</a> — a fast wrapper which synchronously returns a <code>Task</code> and an <code>async</code> method which is only called when necessary — and got a ~15% speedup in my end-to-end benchmarks.
</li>
<li><code>Html</code> values make use of <code>ImmutableArray</code>s to store their children. <code>ImmutableArray</code> is a thin wrapper over a regular array, so if you have a <code>T[]</code> you should be able to turn it into an <code>ImmutableArray</code> in-place without copying the contents, as long as you’re careful never to modify the original array after freezing it. There are several places in Eighty where this is a safe optimisation, but <code>ImmutableArray</code> doesn’t have a public API to do this. However, since <code>ImmutableArray&lt;T&gt;</code> is a struct with a single private <code>T[]</code> field, its runtime representation is the same as <code>T[]</code>’s. This makes it possible to <a href="https://github.com/benjamin-hodgson/Eighty/blob/3c431c13200022bb34ee3de635cce305384abef5/Eighty/ImmutableArrayFactory.cs#L45">unsafely coerce a <code>T[]</code> to an <code>ImmutableArray&lt;T&gt;</code></a> with no runtime cost.
<ul>
<li>I’ve opened <a href="https://github.com/dotnet/corefx/issues/28064">an issue in the <code>corefx</code> repo</a> proposing an officially-supported API for this use case.
</li>
</ul>
</li>
</ul>
<p>I’m not sure exactly why Razor is slower by comparison. My guess is that Razor’s template compiler just tends to generate comparatively slow C# code — so there’s probably some room for improvement — but I would like to investigate this more.</p>
<hr />
<p>HTML generators are an example of a problem where the spectrum of possible solutions is very broad indeed. Just within the C# ecosystem there exists a menagerie of different templating languages, as well as imperative object-oriented APIs like <code>TagBuilder</code> and streaming APIs like <code>XmlWriter</code>. Even Eighty and Twenty, two implementations of the same idea, are substantially different. You can often find yourself somewhere quite interesting if you appreach a common problem from a different direction than the established solutions. What parts of the library ecosystem do you think you could do with a fresh perspective?</p>
<p>Eighty is available <a href="https://www.nuget.org/packages/Eighty">on Nuget</a>, along with some helpers to integrate Eighty with <a href="https://www.nuget.org/packages/Eighty.AspNet.Mvc">MVC</a> and <a href="https://www.nuget.org/packages/Eighty.AspNetCore">ASP.NET Core</a>. API docs are hosted <a href="https://www.benjamin.pizza/Eighty/v1.2.0/api/Eighty.html">on this very domain</a>, and the code’s all <a href="https://github.com/benjamin-hodgson/Eighty">on GitHub</a> where contributions and bug reports are very welcome!</p>

]]></summary>
</entry>
<entry>
    <title>Zip-Folding</title>
    <link href="http://www.benjamin.pizza/posts/2018-01-10-zip-folding.html" />
    <id>http://www.benjamin.pizza/posts/2018-01-10-zip-folding.html</id>
    <published>2018-01-10T00:00:00Z</published>
    <updated>2018-01-10T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>One of my favourite little gems of functional programming is the following implementation of the dot product:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">dot ::</span> [<span class="dt">Double</span>] <span class="ot">-&gt;</span> [<span class="dt">Double</span>] <span class="ot">-&gt;</span> <span class="dt">Double</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>xs <span class="ot">`dot`</span> ys <span class="ot">=</span> <span class="fu">sum</span> (<span class="fu">zipWith</span> (<span class="op">*</span>) xs ys)</span></code></pre></div><p><code>dot</code> zips two lists of numbers, multiplying each pair of elements using <code>(*)</code>, and then aggregates the results with <code>sum</code>. It’s like a <em>map-reduce</em> program, but it processes two collections, not one. It generalises rather beautifully to any zippily <code>Applicative</code> <code>Foldable</code> container whose elements form a <code>Semiring</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">dot ::</span> (<span class="dt">Semiring</span> a, <span class="dt">Applicative</span> t, <span class="dt">Foldable</span> t) <span class="ot">=&gt;</span> t a <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> a</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>xs <span class="ot">`dot`</span> ys <span class="ot">=</span> foldl&#39; (<span class="op">&lt;+&gt;</span>) zero (liftA2 (<span class="op">&lt;.&gt;</span>) xs ys)</span></code></pre></div><p>I think I’m particularly taken with this example because it combines three different abstractions in a totally natural way to produce a concise and generic implementation of a well-known program. It’s a beautiful demonstration of how these mathematical tools fit together. It also happens to be an example of a programming pattern that I call <em>zip-folding</em>.</p>
<hr />
<p>Until recently I felt rather embarrassed that my C# generic programming library <a href="https://github.com/benjamin-hodgson/Sawmill">Sawmill</a> didn’t have a good story for consuming more than one tree at a time. I had lots of tools for <a href="https://github.com/benjamin-hodgson/Sawmill/blob/b87687e67185ddc299ad67455bd7c79f97e066b2/Sawmill/Rewriter.SelfAndDescendants.cs">querying</a>, <a href="https://github.com/benjamin-hodgson/Sawmill/blob/b87687e67185ddc299ad67455bd7c79f97e066b2/Sawmill/Rewriter.Rewrite.cs">editing</a>, and <a href="https://github.com/benjamin-hodgson/Sawmill/blob/b87687e67185ddc299ad67455bd7c79f97e066b2/Sawmill/Rewriter.Fold.cs">tearing down</a> single trees, but nothing that could help you process two trees at once. This is a very common requirement - for example, if you’re unit testing a parser or a transformation pass, you need to compare the output tree to the one that you expected.</p>
<p>I got to thinking about what it means to zip two trees together - an operation which should make sense if you think of a tree as a container of subtrees. Pairing up nodes in a tree is straightforward, even if the two trees are unevenly shaped. You just pair up the children of each pair of nodes, ignoring those which don’t have a partner (the grey-coloured ones in the drawing):</p>
<img src="/images/2018-01-10-zip-folding/zip.jpg" alt="Pairing up nodes" />
<p>But I got stuck on how to plug those paired nodes back into a single tree representing the zipped trees. Nodes typically have space for a fixed number of children, but pairing up children will typically change that number. That is, a binary operator has precisely two children, but when zipping two binary operators together you need to do something with four children.</p>
<p>And, more generally, what would it mean to zip trees recursively? You can imagine a scheme wherein each child of a node is replaced with a tuple of two children. But each child is really a subtree, with its own children, so the two subtrees need to be zipped - but that ought to produce a single tree, not a pair of trees. It’s contradictory! The intuitive idea that a node in a tree is a container of subtrees fails when you consider zipping.</p>
<hr />
<p>Guess where this is going: you can’t <em>zip</em> trees to produce a new tree, but you can <em>zip-fold</em> trees to produce a value. The idea is to take pairs of nodes in a tree and combine them with the results of zipping their children.</p>
<p>Let’s start by looking at (an abbreviated version of) Sawmill’s existing <code>Fold</code>. <code>Fold</code> says <em>if you give me a way to combine a node with the results of folding its children, I can recursively fold the entire tree to produce a single summary value</em>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> U Fold<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> T value<span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>T<span class="op">,</span> Children<span class="op">&lt;</span>U<span class="op">&gt;,</span> U<span class="op">&gt;</span> func</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">func</span><span class="op">(</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        value<span class="op">,</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        value<span class="op">.</span><span class="fu">GetChildren</span><span class="op">()</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>            <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>child <span class="op">=&gt;</span> child<span class="op">.</span><span class="fu">Fold</span><span class="op">(</span>func<span class="op">))</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>Revisiting <a href="https://www.benjamin.pizza/posts/2017-11-13-recursion-without-recursion.html">the JQL example</a>, <code>Fold</code> will take an input tree like <code>[c#] and (not [javascript] or salary:50000gbp)</code> and compute the expression:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="fu">func</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">AndNode</span><span class="op">(</span><span class="co">/* ... */</span><span class="op">),</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Children<span class="op">.</span><span class="fu">Two</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="fu">func</span><span class="op">(</span><span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;c#&quot;</span><span class="op">),</span> Children<span class="op">.</span><span class="fu">None</span><span class="op">&lt;</span>U<span class="op">&gt;()),</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="fu">func</span><span class="op">(</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span><span class="co">/* ... */</span><span class="op">),</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            Children<span class="op">.</span><span class="fu">Two</span><span class="op">(</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                <span class="fu">func</span><span class="op">(</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span><span class="co">/* ... */</span><span class="op">),</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>                    Children<span class="op">.</span><span class="fu">One</span><span class="op">(</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>                        <span class="fu">func</span><span class="op">(</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                            <span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;javascript&quot;</span><span class="op">),</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>                            Children<span class="op">.</span><span class="fu">None</span><span class="op">&lt;</span>U<span class="op">&gt;()</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                        <span class="op">)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                    <span class="op">)</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                <span class="op">),</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                <span class="fu">func</span><span class="op">(</span><span class="kw">new</span> <span class="fu">SalaryNode</span><span class="op">(</span><span class="dv">50000</span><span class="op">,</span> <span class="st">&quot;gbp&quot;</span><span class="op">),</span> Children<span class="op">.</span><span class="fu">None</span><span class="op">&lt;</span>U<span class="op">&gt;())</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="op">)</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="op">)</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div><p><code>Fold</code> traverses a tree from bottom to top, applying <code>func</code> to each subtree and the current set of intermediate results.</p>
<p><code>ZipFold</code> works by analogy to <code>Fold</code>. It says <em>if you give me a way to combine two nodes with the results of zip-folding their children, I can recursively zip the two entire trees to produce a single summary value</em>. <code>ZipFold</code> pairs up the children of the two input nodes using the standard <code>Enumerable.Zip</code>, recursively zip-folds each pair, and then feeds the results to <code>func</code>. Note that the length of the <code>IEnumerable</code> that’s passed to <code>func</code> is the length of the smaller of the two nodes’ collections of children.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> U ZipFold<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> T value1<span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    T value2</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">,</span> IEnumerable<span class="op">&lt;</span>U<span class="op">&gt;,</span> U<span class="op">&gt;</span> zipFunc</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">zipFunc</span><span class="op">(</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        value1<span class="op">,</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        value2<span class="op">,</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        value1<span class="op">.</span><span class="fu">GetChildren</span><span class="op">().</span><span class="fu">Zip</span><span class="op">(</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            value2<span class="op">.</span><span class="fu">GetChildren</span><span class="op">(),</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="op">(</span>child1<span class="op">,</span> child2<span class="op">)</span> <span class="op">=&gt;</span> child1<span class="op">.</span><span class="fu">ZipFold</span><span class="op">(</span>child2<span class="op">,</span> zipFunc<span class="op">)</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="op">)</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>The two trees are zipped together and torn down in a single pass.</p>
<p>Here’s how it looks in Haskell, using the <a href="https://hackage.haskell.org/package/lens-4.15.4/docs/Control-Lens-Plated.html"><code>Control.Lens.Plated</code></a> API. Haskellers like to use tongue-in-cheek Greek names for recursion schemes. Apparently the Greek word for “zip” is “fermouár”, so I’m calling this a <em>fermomorphism</em>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">fermo ::</span> <span class="dt">Plated</span> a <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [r] <span class="ot">-&gt;</span> r) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> r</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>fermo f x y <span class="ot">=</span> f x y <span class="op">$</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">zipWith</span> (fermo f) (toListOf plate x) (toListOf plate y)</span></code></pre></div><p>As an example: <code>ZipFold</code> allows you to concisely test a pair of trees for equality, by looking only at one pair of nodes at a time.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> <span class="dt">bool</span> <span class="fu">Equal</span><span class="op">(</span>JqlNode j1<span class="op">,</span> JqlNode j2<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> j1<span class="op">.</span><span class="fu">ZipFold</span><span class="op">&lt;</span>JqlNode<span class="op">,</span> <span class="dt">bool</span><span class="op">&gt;(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        j2<span class="op">,</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">(</span>n1<span class="op">,</span> n2<span class="op">,</span> childrenEqual<span class="op">)</span> <span class="op">=&gt;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">switch</span> <span class="op">(</span>n1<span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> SalaryNode s1 when n2 <span class="kw">is</span> SalaryNode s2<span class="op">:</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> s1<span class="op">.</span><span class="fu">Currency</span> <span class="op">==</span> s2<span class="op">.</span><span class="fu">Currency</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>                        <span class="op">&amp;&amp;</span> s1<span class="op">.</span><span class="fu">Amount</span> <span class="op">==</span> s2<span class="op">.</span><span class="fu">Amount</span><span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> TagNode t1 when n2 <span class="kw">is</span> TagNode t2<span class="op">:</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> t1<span class="op">.</span><span class="fu">Tag</span> <span class="op">==</span> t2<span class="op">.</span><span class="fu">Tag</span><span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> AndNode a1 when n2 <span class="kw">is</span> AndNode a2<span class="op">:</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> OrNode o1 when n2 <span class="kw">is</span> OrNode o2<span class="op">:</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> NotNode a1 when n2 <span class="kw">is</span> NotNode a2<span class="op">:</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> childrenEqual<span class="op">.</span><span class="fu">All</span><span class="op">(</span>c <span class="op">=&gt;</span> c<span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                <span class="kw">default</span><span class="op">:</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> <span class="kw">false</span><span class="op">;</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>The <code>ZipFold</code> that you’ll find in Sawmill is actually an <em>n</em>-ary zip-fold. Instead of taking two <code>T</code>s, and passing two <code>T</code>s to <code>func</code>, it works with an arbitrary number of <code>T</code>s. Here’s the code:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> U ZipFold<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> T<span class="op">[]</span> values<span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>T<span class="op">[],</span> IEnumerable<span class="op">&lt;</span>U<span class="op">&gt;,</span> U<span class="op">&gt;</span> func</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="fu">func</span><span class="op">(</span>values<span class="op">,</span> xs<span class="op">.</span><span class="fu">ZipChildren</span><span class="op">(</span>children <span class="op">=&gt;</span> children<span class="op">.</span><span class="fu">ZipFold</span><span class="op">(</span>func<span class="op">)));</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> <span class="kw">static</span> IEnumerable<span class="op">&lt;</span>U<span class="op">&gt;</span> ZipChildren<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;(</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> T<span class="op">[]</span> input<span class="op">,</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>T<span class="op">[],</span> U<span class="op">&gt;</span> zipFunc</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="op">)</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> enumerators <span class="op">=</span> input</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>x <span class="op">=&gt;</span> x<span class="op">.</span><span class="fu">GetChildren</span><span class="op">().</span><span class="fu">GetEnumerator</span><span class="op">())</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">ToArray</span><span class="op">();</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">while</span> <span class="op">(</span>enumerators<span class="op">.</span><span class="fu">All</span><span class="op">(</span>e <span class="op">=&gt;</span> e<span class="op">.</span><span class="fu">MoveNext</span><span class="op">()))</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        <span class="kw">yield</span> <span class="kw">return</span> <span class="fu">zipFunc</span><span class="op">(</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>            enumerators<span class="op">.</span><span class="fu">Select</span><span class="op">(</span>e <span class="op">=&gt;</span> e<span class="op">.</span><span class="fu">Current</span><span class="op">).</span><span class="fu">ToArray</span><span class="op">()</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="op">);</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Sadly, the invariant that <code>zipFunc</code> receives the same number of <code>T</code>s as were passed to <code>ZipFold</code> is not expressible in C#’s type system. So as a consumer of <code>ZipFold</code>, you just have to trust that <code>zipFunc</code>’s argument is of a certain size. In the <code>Equal</code> example, that size is two, because we’re consuming two trees:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> <span class="dt">bool</span> <span class="fu">Equal</span><span class="op">(</span>JqlNode j1<span class="op">,</span> JqlNode j2<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> j1<span class="op">,</span> j2 <span class="op">}.</span><span class="fu">ZipFold</span><span class="op">&lt;</span>JqlNode<span class="op">,</span> <span class="dt">bool</span><span class="op">&gt;(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="op">(</span>ns<span class="op">,</span> childrenEqual<span class="op">)</span> <span class="op">=&gt;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            <span class="kw">switch</span> <span class="op">(</span>ns<span class="op">[</span><span class="dv">0</span><span class="op">])</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="op">{</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> SalaryNode s1 when ns<span class="op">[</span><span class="dv">1</span><span class="op">]</span> <span class="kw">is</span> SalaryNode s2<span class="op">:</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> s1<span class="op">.</span><span class="fu">Currency</span> <span class="op">==</span> s2<span class="op">.</span><span class="fu">Currency</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>                        <span class="op">&amp;&amp;</span> s1<span class="op">.</span><span class="fu">Amount</span> <span class="op">==</span> s2<span class="op">.</span><span class="fu">Amount</span><span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> TagNode t1 when ns<span class="op">[</span><span class="dv">1</span><span class="op">]</span> <span class="kw">is</span> TagNode t2<span class="op">:</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> t1<span class="op">.</span><span class="fu">Tag</span> <span class="op">==</span> t2<span class="op">.</span><span class="fu">Tag</span><span class="op">;</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> AndNode a1 when ns<span class="op">[</span><span class="dv">1</span><span class="op">]</span> <span class="kw">is</span> AndNode a2<span class="op">:</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> OrNode o1 when ns<span class="op">[</span><span class="dv">1</span><span class="op">]</span> <span class="kw">is</span> OrNode o2<span class="op">:</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                <span class="kw">case</span> NotNode n1 when ns<span class="op">[</span><span class="dv">1</span><span class="op">]</span> <span class="kw">is</span> NotNode n2<span class="op">:</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> childrenEqual<span class="op">.</span><span class="fu">All</span><span class="op">(</span>c <span class="op">=&gt;</span> c<span class="op">);</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>                <span class="kw">default</span><span class="op">:</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">return</span> <span class="kw">false</span><span class="op">;</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>Here’s the Haskell transliteration of this <em>n</em>-ary zip-fold function, which <code>traverse</code>s in the <code>ZipList</code> <code>Applicative</code> to concisely zip <em>n</em> lists of children:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">fermo ::</span> <span class="dt">Plated</span> a <span class="ot">=&gt;</span> ([a] <span class="ot">-&gt;</span> [r] <span class="ot">-&gt;</span> r) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> r</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>fermo f xs <span class="ot">=</span> f xs (</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">map</span> (fermo f) <span class="op">$</span> getZipList <span class="op">$</span> <span class="fu">traverse</span> (<span class="dt">ZipList</span> <span class="op">.</span> toListOf plate) xs</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    )</span></code></pre></div><p><code>ZipFold</code> is available in <a href="https://www.nuget.org/packages/Sawmill/">version 1.3.0 of Sawmill</a>.</p>

]]></summary>
</entry>
<entry>
    <title>Functor Functors</title>
    <link href="http://www.benjamin.pizza/posts/2017-12-15-functor-functors.html" />
    <id>http://www.benjamin.pizza/posts/2017-12-15-functor-functors.html</id>
    <published>2017-12-15T00:00:00Z</published>
    <updated>2017-12-15T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>You can teach a new dog old tricks.</p>
<p>One of the fun things about category theory is that once you’ve learned an idea in one context it’s easy to apply it to another one. Of the numerous categories available to Haskell programmers, <strong>Hask</strong>, the category of Haskell types and functions, gets the lion’s share of the attention. Working with standard abstractions in more overlooked categories is a great way to reuse ideas: it makes you look clever, like you’ve invented something new, but actually all you’ve done is put the building blocks together differently. I won’t tell if you don’t.</p>
<h2 id="templates-reusable-records"><a href="#templates-reusable-records">Templates: Reusable Records</a></h2>
<p>Every now and then I’ll see a question on Stack Overflow or Reddit in which a programmer is trying to work with a bunch of record types which share a similar structure. For a contrived example, in a shopping system you may want to differentiate between completed checkout forms, which are ready to be dispatched, and “draft” checkout forms, which the user is currently filling in. The simplest way to do this is to build separate types, and write a function to upgrade a draft form to a regular form if all of its fields are filled in.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">CardType</span> <span class="ot">=</span> <span class="dt">Visa</span> <span class="op">|</span> <span class="dt">AmEx</span> <span class="op">|</span> <span class="dt">Mastercard</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Form</span> <span class="ot">=</span> <span class="dt">Form</span> {</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">    form_email ::</span> <span class="dt">Text</span>,</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">    form_cardType ::</span> <span class="dt">CardType</span>,</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="ot">    form_cardNumber ::</span> <span class="dt">Text</span>,</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="ot">    form_cardExpiry ::</span> <span class="dt">Day</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">DraftForm</span> <span class="ot">=</span> <span class="dt">DraftForm</span> {</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="ot">    draftForm_email ::</span> <span class="dt">Maybe</span> <span class="dt">Text</span>,</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="ot">    draftForm_cardType ::</span> <span class="dt">Maybe</span> <span class="dt">CardType</span>,</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="ot">    draftForm_cardNumber ::</span> <span class="dt">Maybe</span> <span class="dt">Text</span>,</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="ot">    draftForm_cardExpiry ::</span> <span class="dt">Maybe</span> <span class="dt">Day</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="ot">toForm ::</span> <span class="dt">DraftForm</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Form</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>toForm (<span class="dt">DraftForm</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Just</span> email)</span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Just</span> cardType)</span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Just</span> cardNumber)</span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Just</span> cardExpiry)) <span class="ot">=</span> <span class="dt">Just</span> <span class="op">$</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Form</span> email cardType cardNumber cardExpiry</span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>toForm _ <span class="ot">=</span> <span class="dt">Nothing</span></span></code></pre></div><p>Now, the standard trick to de-duplicate these two types is to derive both from what I’ll call a <em>template</em> type, wrapping each field of the template in some type constructor <code>f</code>. You recover <code>Form</code> by setting <code>f</code> to the boring <code>Identity</code> functor, and you get <code>DraftForm</code> by setting <code>f</code> to <code>Maybe</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">FormTemplate</span> f <span class="ot">=</span> <span class="dt">FormTemplate</span> {</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    _email ::</span> f <span class="dt">Text</span>,</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    _cardType ::</span> f <span class="dt">CardType</span>,</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">    _cardNumber ::</span> f <span class="dt">Text</span>,</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">    _cardExpiry ::</span> f <span class="dt">Day</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Form</span> <span class="ot">=</span> <span class="dt">FormTemplate</span> <span class="dt">Identity</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">DraftForm</span> <span class="ot">=</span> <span class="dt">FormTemplate</span> <span class="dt">Maybe</span></span></code></pre></div><p>So a template is a record type parameterised by a type constructor. It’ll generally have a kind of <code>(* -&gt; *) -&gt; *</code>. The fields of the record are the type constructor applied to a variety of different type arguments. Working with a template typically involves coming up with an interesting type constructor <code>(* -&gt; *)</code> and plugging it in to get interestingly-typed fields. You can think of a record as a container of <code>f</code>s.</p>
<p>This trick has become Haskell folklore - I couldn’t tell you where I first saw it - but I’ve only seen a few people talk about what happens when you treat templates as first class citizens. To get used to this style, a simple example is giving names to specific instantiations of arbitrary templates:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Record</span> t <span class="ot">=</span> t <span class="dt">Identity</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Partial</span> t <span class="ot">=</span> t <span class="dt">Maybe</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Form</span> <span class="ot">=</span> <span class="dt">Record</span> <span class="dt">FormTemplate</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">DraftForm</span> <span class="ot">=</span> <span class="dt">Partial</span> <span class="dt">FormTemplate</span></span></code></pre></div><p>The rest of this blog post is about treating template types intuitively as fixed-size containers of functors. I’ll be taking familiar tools for working with containers of <em>values</em> - <code>Functor</code>, <code>Traversable</code>, <code>Representable</code> - and applying them to the context of containers of <em>functors</em>.</p>
<h2 id="functors-from-the-category-of-endofunctors"><a href="#functors-from-the-category-of-endofunctors">Functors from the Category of Endofunctors</a></h2>
<p>In Haskell, categories are represented as a <em>kind</em> <code>k</code> of objects and a <em>type constructor</em> <code>c :: k -&gt; k -&gt; *</code> of morphisms between those objects. If the category <code>C</code> has objects in <code>k1</code> and morphisms in <code>c</code>, and <code>D</code> has objects in <code>k2</code> and morphisms in <code>d</code>, then a functor from <code>C</code> to <code>D</code> is a type constructor <code>f :: k1 -&gt; k2</code> mapping objects paired with an operation <code>fmap :: c a b -&gt; d (f a) (f b)</code> mapping the morphisms. The standard <code>Functor</code> class is for <em>endofunctors on <strong>Hask</strong></em> - the special case in which <code>k1 ~ k2 ~ *</code> and <code>c ~ d ~ (-&gt;)</code>.</p>
<img src="/images/2017-12-15-functor-functors/hask.jpg" alt="Endofunctors on Hask" />
<p>Given two categories <code>C</code> and <code>D</code>, you can construct the category of functors between <code>C</code> and <code>D</code>, written as <code>[C, D]</code>. Objects in this category are functors from <code>C</code> to <code>D</code>, and morphisms are natural transformations between those functors. Since <code>[C, D]</code> is a regular category, you can of course have functors mapping that category to other categories. So in Haskell that’d be a type of kind <code>(k1 -&gt; k2) -&gt; k3</code>. I’ll call such types <em>functor functors</em>.</p>
<p>We’re talking about record templates of kind <code>(* -&gt; *) -&gt; *</code>. This fits the pattern of a functor from the functor category, with <code>k1 ~ k2 ~ k3 ~ *</code>. So the functor category in question is the category of endofunctors on <strong>Hask</strong> (that is, members of the standard <code>Functor</code> class), and the destination category is <strong>Hask</strong>. So it’s reasonable to expect record templates to be functorial in their argument:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">-- natural transformations between functors f and g</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> f <span class="op">~&gt;</span> g <span class="ot">=</span> <span class="kw">forall</span> x<span class="op">.</span> f x <span class="ot">-&gt;</span> g x</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="co">-- &quot;functor functors&quot;, functors from the functor category</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">FFunctor</span> f <span class="kw">where</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="ot">    ffmap ::</span> (<span class="dt">Functor</span> g, <span class="dt">Functor</span> h) <span class="ot">=&gt;</span> (g <span class="op">~&gt;</span> h) <span class="ot">-&gt;</span> f g <span class="ot">-&gt;</span> f h</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FFunctor</span> <span class="dt">FormTemplate</span> <span class="kw">where</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    ffmap eta (<span class="dt">FormTemplate</span> email cardType cardNumber cardExpiry)</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> <span class="dt">FormTemplate</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            (eta email)</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            (eta cardType)</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            (eta cardNumber)</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            (eta cardExpiry)</span></code></pre></div><p><code>FFunctor</code> comes with the usual functor laws. The only difference is the types.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">-- identity</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>ffmap <span class="fu">id</span> <span class="ot">=</span> <span class="fu">id</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="co">-- composition</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>ffmap (eta <span class="op">.</span> phi) <span class="ot">=</span> ffmap eta <span class="op">.</span> ffmap phi</span></code></pre></div><img src="/images/2017-12-15-functor-functors/ffunctor.jpg" alt="Functor functors" />
<p><code>ffmap</code> encodes the notion of generalising the functor a template has been instantiated with. If you can embed the functor <code>f</code> into <code>g</code>, then you can map a record of <code>f</code>s to a record of <code>g</code>s by embedding each <code>f</code>. (This is also sometimes called “hoisting”.) For example, the boring <code>Identity</code> functor can be embedded into an arbitrary <code>Applicative</code> by injecting the contained value using <code>pure</code>. We can use this to turn a total record into a partial one:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">generalise ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Identity</span> a <span class="ot">-&gt;</span> f a</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>generalise (<span class="dt">Identity</span> x) <span class="ot">=</span> <span class="fu">pure</span> x</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">toPartial ::</span> <span class="dt">FFunctor</span> t <span class="ot">=&gt;</span> <span class="dt">Record</span> t <span class="ot">-&gt;</span> <span class="dt">Partial</span> t</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>toPartial <span class="ot">=</span> ffmap generalise</span></code></pre></div><h2 id="traversing-records"><a href="#traversing-records">Traversing Records</a></h2>
<p>Now that we have a new dog, it’s natural to ask which old tricks we can teach it. With the intuition that a template <code>t f</code> is like a container of <code>f</code>s, what does it mean to traverse such a container? <code>sequenceA :: Applicative f =&gt; t (f a) -&gt; f (t a)</code> takes a container of strategies to produce values and sequences them to get a strategy to produce a container of values. Replacing <em>value</em> with <em>functor</em> in the above sentence, it’s clear that we need to decide on a notion of “strategy to produce a functor”. <a href="https://stackoverflow.com/questions/44187945/what-should-a-higher-order-traversable-class-look-like">With thanks to Li-yao Xia</a>, the simplest of such notions is a regular applicative functor <code>a</code> returning a functorial value <code>g x</code> - that is, <code>Compose a g</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">FFunctor</span> t <span class="ot">=&gt;</span> <span class="dt">FTraversable</span> t <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ftraverse ::</span> (<span class="dt">Functor</span> f, <span class="dt">Functor</span> g, <span class="dt">Applicative</span> a)</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>              <span class="ot">=&gt;</span> (f <span class="op">~&gt;</span> <span class="dt">Compose</span> a g) <span class="ot">-&gt;</span> t f <span class="ot">-&gt;</span> a (t g)</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    ftraverse eta <span class="ot">=</span> fsequence <span class="op">.</span> ffmap eta</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">    fsequence ::</span> (<span class="dt">Functor</span> f, <span class="dt">Applicative</span> a)</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>              <span class="ot">=&gt;</span> t (<span class="dt">Compose</span> a f) <span class="ot">-&gt;</span> a (t f)</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    fsequence <span class="ot">=</span> ftraverse <span class="fu">id</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="ot">ffmapDefault ::</span> (<span class="dt">Functor</span> f, <span class="dt">Functor</span> g, <span class="dt">FTraversable</span> t)</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=&gt;</span> (f <span class="op">~&gt;</span> g) <span class="ot">-&gt;</span> t f <span class="ot">-&gt;</span> t g</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>ffmapDefault eta <span class="ot">=</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    runIdentity <span class="op">.</span> ftraverse (<span class="dt">Compose</span> <span class="op">.</span> <span class="dt">Identity</span> <span class="op">.</span> eta)</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a><span class="ot">fsequence&#39; ::</span> (<span class="dt">FTraversable</span> t, <span class="dt">Applicative</span> a) <span class="ot">=&gt;</span> t a <span class="ot">-&gt;</span> a (<span class="dt">Record</span> t)</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>fsequence&#39; <span class="ot">=</span> ftraverse (<span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Identity</span>)</span></code></pre></div><p>The <code>FTraversable</code> laws come about by adjusting the <code>Traversable</code> laws to add some <code>Compose</code>-bookkeeping.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">-- naturality</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>nu <span class="op">.</span> ftraverse eta <span class="ot">=</span> ftraverse (<span class="dt">Compose</span> <span class="op">.</span> nu <span class="op">.</span> getCompose <span class="op">.</span> eta)</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="co">-- for any applicative transformation nu</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="co">-- identity</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>ftraverse (<span class="dt">Compose</span> <span class="op">.</span> <span class="dt">Identity</span>) <span class="ot">=</span> <span class="dt">Identity</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="co">-- composition</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>ftraverse (<span class="dt">Compose</span> <span class="op">.</span> <span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> (getCompose<span class="op">.</span>phi) <span class="op">.</span> getCompose <span class="op">.</span> eta)</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> (ftraverse phi) <span class="op">.</span> ftraverse eta</span></code></pre></div><p>Implementations of <code>traverse</code> look like implementations of <code>fmap</code> but in an applicative context. Likewise, implementations of <code>ftraverse</code> look like implementations of <code>ffmap</code> in an applicative context, with a few <code>getCompose</code>s scattered around.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FTraversable</span> <span class="dt">FormTemplate</span> <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    ftraverse eta (<span class="dt">FormTemplate</span> email cardType cardNumber cardExpiry)</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> <span class="dt">FormTemplate</span> <span class="op">&lt;$&gt;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>            (getCompose <span class="op">$</span> eta email) <span class="op">&lt;*&gt;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            (getCompose <span class="op">$</span> eta cardType) <span class="op">&lt;*&gt;</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            (getCompose <span class="op">$</span> eta cardNumber) <span class="op">&lt;*&gt;</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            (getCompose <span class="op">$</span> eta cardExpiry)</span></code></pre></div><p>This is where things start to get interesting. The <code>toForm</code> function, which converts a draft form to a regular form if all of its fields have been filled in, can be defined tersely in terms of <code>ftraverse</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">toRecord ::</span> <span class="dt">FTraversable</span> t <span class="ot">=&gt;</span> <span class="dt">Partial</span> t <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Record</span> t)</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>toRecord <span class="ot">=</span> ftraverse (<span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Identity</span>)</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">toForm ::</span> <span class="dt">DraftForm</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Form</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>toForm <span class="ot">=</span> toRecord</span></code></pre></div><p>Here’s another example: a generic program, defined by analogy to <code>Foldable</code>’s <code>foldMap</code>, to collapse the fields of a record into a monoidal value. Note that <code>f () -&gt; m</code> is isomorphic to, but simpler than, <code>forall x. f x -&gt; m</code>. Annoyingly, we have to give a type signature to <code>mkConst</code> to resolve the ambiguity over <code>g</code> in the call to <code>ftraverse</code>. I’m picking <code>Empty</code> as a way of demonstrating that I have nothing up my sleeves.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Empty</span> a <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">ffoldMap ::</span> <span class="kw">forall</span> f t m<span class="op">.</span> (<span class="dt">Monoid</span> m, <span class="dt">Functor</span> f, <span class="dt">FTraversable</span> t)</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>         <span class="ot">=&gt;</span> (f () <span class="ot">-&gt;</span> m) <span class="ot">-&gt;</span> t f <span class="ot">-&gt;</span> m</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>ffoldMap f <span class="ot">=</span> getConst <span class="op">.</span> ftraverse mkConst</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="co">-- using ScopedTypeVariables to bind f</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="ot">        mkConst ::</span> f x <span class="ot">-&gt;</span> <span class="dt">Compose</span> (<span class="dt">Const</span> m) <span class="dt">Empty</span> x</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        mkConst <span class="ot">=</span> <span class="dt">Compose</span> <span class="op">.</span> <span class="dt">Const</span> <span class="op">.</span> f <span class="op">.</span> (<span class="op">$&gt;</span> ())</span></code></pre></div><h2 id="zipping-templates"><a href="#zipping-templates">Zipping templates</a></h2>
<p>Given a pair of records of the same shape <code>t</code>, we should be able to combine them point-wise, matching up the fields of each: <code>fzip :: t f -&gt; t g -&gt; t (Product f g)</code>. In <strong>Hask</strong>, “combining point-wise” is exactly what the “reader” applicative <code>(-&gt;) r</code> does, so any functor which enjoys an isomorphism to <code>(-&gt;) r</code> for some <code>r</code> has at least a zippy <code>Applicative</code> instance. Such functors are called <em>representable functors</em> and they are members of the class <a href="https://hackage.haskell.org/package/adjunctions-4.3/docs/Data-Functor-Rep.html#t:Representable"><code>Representable</code></a>.</p>
<p>Of course, we’re working with functors from the functor category, so the relevant notion of <code>Representable</code> will need a little adjustment. Instead of an isomorphism to a function <code>(-&gt;) r</code> we’ll use an isomorphism to a natural transformation <code>(~&gt;) r</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">FFunctor</span> t <span class="ot">=&gt;</span> <span class="dt">FRepresentable</span> t <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">FRep</span><span class="ot"> t ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="ot">    ftabulate ::</span> (<span class="dt">FRep</span> t <span class="op">~&gt;</span> f) <span class="ot">-&gt;</span> t f</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">    findex ::</span> t f <span class="ot">-&gt;</span> <span class="dt">FRep</span> t a <span class="ot">-&gt;</span> f a</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="ot">fzipWith ::</span> <span class="dt">FRepresentable</span> t</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>         <span class="ot">=&gt;</span> (<span class="kw">forall</span> x<span class="op">.</span> f x <span class="ot">-&gt;</span> g x <span class="ot">-&gt;</span> h x)</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span>            t f <span class="ot">-&gt;</span> t g <span class="ot">-&gt;</span> t h</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>fzipWith f t u <span class="ot">=</span> ftabulate <span class="op">$</span> \r <span class="ot">-&gt;</span> f (findex t r) (findex u r)</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="ot">fzipWith3 ::</span> <span class="dt">FRepresentable</span> t</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>          <span class="ot">=&gt;</span> (<span class="kw">forall</span> x<span class="op">.</span> f x <span class="ot">-&gt;</span> g x <span class="ot">-&gt;</span> h x <span class="ot">-&gt;</span> k x)</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span>            t f <span class="ot">-&gt;</span> t g <span class="ot">-&gt;</span> t h <span class="ot">-&gt;</span> t k</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>fzipWith3 f t u v <span class="ot">=</span> ftabulate <span class="op">$</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    \r <span class="ot">-&gt;</span> f (findex t r) (findex u r) (findex v r)</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="ot">fzip ::</span> <span class="dt">FRepresentable</span> t <span class="ot">=&gt;</span> t f <span class="ot">-&gt;</span> t g <span class="ot">-&gt;</span> t (<span class="dt">Product</span> f g)</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>fzip <span class="ot">=</span> fzipWith <span class="dt">Pair</span></span></code></pre></div><p>The laws for <code>FRepresentable</code> simply state that <code>ftabulate</code> and <code>findex</code> must witness an isomorphism:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="co">-- isomorphism</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>ftabulate <span class="op">.</span> findex <span class="ot">=</span> findex <span class="op">.</span> ftabulate <span class="ot">=</span> <span class="fu">id</span></span></code></pre></div><p><code>FRep</code> will typically be a GADT: it tells you what type of value one should expect to find at a given position in a record.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">FormTemplateRep</span> a <span class="kw">where</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Email</span><span class="ot"> ::</span> <span class="dt">FormTemplateRep</span> <span class="dt">Text</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">CardType</span><span class="ot"> ::</span> <span class="dt">FormTemplateRep</span> <span class="dt">CardType</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">CardNumber</span><span class="ot"> ::</span> <span class="dt">FormTemplateRep</span> <span class="dt">Text</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">CardExpiry</span><span class="ot"> ::</span> <span class="dt">FormTemplateRep</span> <span class="dt">Day</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FRepresentable</span> <span class="dt">FormTemplate</span> <span class="kw">where</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">FRep</span> <span class="dt">FormTemplate</span> <span class="ot">=</span> <span class="dt">FormTemplateRep</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    ftabulate eta <span class="ot">=</span> <span class="dt">FormTemplate</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        (eta <span class="dt">Email</span>)</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        (eta <span class="dt">CardType</span>)</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        (eta <span class="dt">CardNumber</span>)</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        (eta <span class="dt">CardExpiry</span>)</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    </span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    findex p <span class="dt">Email</span> <span class="ot">=</span> _email p</span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    findex p <span class="dt">CardType</span> <span class="ot">=</span> _cardType p</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    findex p <span class="dt">CardNumber</span> <span class="ot">=</span> _cardNumber p</span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    findex p <span class="dt">CardExpiry</span> <span class="ot">=</span> _cardExpiry p</span></code></pre></div><p>Something useful you can do with this infrastructure: filling in defaults for missing values of a partial record. Or, looking at it the other way, overriding certain parts of a record.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">with ::</span> <span class="dt">FRepresentable</span> t <span class="ot">=&gt;</span> <span class="dt">Record</span> t <span class="ot">-&gt;</span> <span class="dt">Partial</span> t <span class="ot">-&gt;</span> <span class="dt">Record</span> t</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>with <span class="ot">=</span> fzipWith override</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span> override x <span class="dt">Nothing</span> <span class="ot">=</span> x</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>          override _ (<span class="dt">Just</span> y) <span class="ot">=</span> <span class="dt">Identity</span> y</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="ot">fillInDefaults ::</span> <span class="dt">FRepresentable</span> t <span class="ot">=&gt;</span> <span class="dt">Partial</span> t <span class="ot">-&gt;</span> <span class="dt">Record</span> t <span class="ot">-&gt;</span> <span class="dt">Record</span> t</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>fillInDefaults t defaults <span class="ot">=</span> defaults <span class="ot">`with`</span> t</span></code></pre></div><p>You can also make a record of <code>Monoid</code> values into a <code>Monoid</code>, once again by zipping.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Wrap</span> t f <span class="ot">=</span> <span class="dt">Wrap</span> {<span class="ot"> unWrap ::</span> t f }</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>makeWrapped &#39;<span class="dt">&#39;Wrap</span>  <span class="co">-- from Control.Lens.Wrapped</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">FRepresentable</span> t, <span class="dt">Monoid</span> c) <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Wrap</span> t (<span class="dt">Const</span> c)) <span class="kw">where</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Wrap</span> <span class="op">$</span> ftabulate (<span class="fu">const</span> (<span class="dt">Const</span> <span class="fu">mempty</span>))</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Wrap</span> t <span class="ot">`mappend`</span> <span class="dt">Wrap</span> u <span class="ot">=</span> <span class="dt">Wrap</span> <span class="op">$</span> fzipWith <span class="fu">mappend</span> t u</span></code></pre></div><h2 id="lenses"><a href="#lenses">Lenses</a></h2>
<p>Rather than come up with a new notion of <code>Lens</code> formulated in terms of <code>FFunctor</code>, we can reuse the standard <code>Lens</code> type as long as we’re careful about how polymorphic lenses should be. Specifically, a lens into a record template should express no opinion as to which functor the template should be instantiated with.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">FLens</span> t a <span class="ot">=</span> <span class="dt">FLens</span> (<span class="kw">forall</span> f<span class="op">.</span> <span class="dt">Lens&#39;</span> (t f) (f a))</span></code></pre></div><p>We can store a template’s lenses in an instance of the template itself!</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Lenses</span> t <span class="ot">=</span> t (<span class="dt">FLens</span> t)</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">HasLenses</span> t <span class="kw">where</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">    lenses ::</span> <span class="dt">Lenses</span> t</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>makeLenses &#39;<span class="dt">&#39;FormTemplate</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">HasLenses</span> <span class="dt">FormTemplate</span> <span class="kw">where</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    lenses <span class="ot">=</span> <span class="dt">FormTemplate</span> {</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        _email <span class="ot">=</span> <span class="dt">FLens</span> email,</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        _cardType <span class="ot">=</span> <span class="dt">FLens</span> cardType,</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        _cardNumber <span class="ot">=</span> <span class="dt">FLens</span> cardNumber,</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        _cardExpiry <span class="ot">=</span> <span class="dt">FLens</span> cardExpiry</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div><h2 id="compositional-validation"><a href="#compositional-validation">Compositional Validation</a></h2>
<p>Now for an extended example: form validation. We’ll be making use of all of the tools from above - zipping, traversing, and mapping - to design a typed API for validating individual fields of a form.</p>
<p><code>Either</code> isn’t a great choice for a validation monad, because <code>Either</code> aborts the computation at the first failure. You typically want to report all the errors in a form. Instead, we’ll be working with the following type, which is isomorphic to <code>Either</code> but with an <code>Applicative</code> instance which returns <em>all</em> of the failures in a given computation, combining the values using a <code>Monoid</code>. So it’s kind of a Frankensteinian mishmash of the <code>Either</code> and <code>Writer</code> applicatives.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Validation</span> e a <span class="ot">=</span> <span class="dt">Failure</span> e <span class="op">|</span> <span class="dt">Success</span> a <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Bifunctor</span> <span class="dt">Validation</span> <span class="kw">where</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    bimap f g (<span class="dt">Failure</span> e) <span class="ot">=</span> <span class="dt">Failure</span> (f e)</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    bimap f g (<span class="dt">Success</span> x) <span class="ot">=</span> <span class="dt">Success</span> (g x)</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> e <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Validation</span> e) <span class="kw">where</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Success</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Success</span> f <span class="op">&lt;*&gt;</span> <span class="dt">Success</span> x <span class="ot">=</span> <span class="dt">Success</span> (f x)</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Failure</span> e1 <span class="op">&lt;*&gt;</span> <span class="dt">Failure</span> e2 <span class="ot">=</span> <span class="dt">Failure</span> (e1 <span class="ot">`mappend`</span> e2)</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Failure</span> e1 <span class="op">&lt;*&gt;</span> _ <span class="ot">=</span> <span class="dt">Failure</span> e1</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    _ <span class="op">&lt;*&gt;</span> <span class="dt">Failure</span> e2 <span class="ot">=</span> <span class="dt">Failure</span> e2</span></code></pre></div><p>This <code>Applicative</code> instance has no compatible <code>Monad</code> instance.</p>
<p>We’ll build a library for validation processes which examine a single field of a record at a time. A validation rule for a field typed <code>a</code> is a function which takes an <code>a</code> and returns a <code>Validation e a</code>.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Validator</span> e a <span class="ot">=</span> <span class="dt">Validator</span> {<span class="ot"> runValidator ::</span> a <span class="ot">-&gt;</span> <span class="dt">Validation</span> e a }</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="co">-- a validator which always succeeds</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">noop ::</span> <span class="dt">Validator</span> e a</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>noop <span class="ot">=</span> <span class="dt">Validator</span> <span class="dt">Success</span></span></code></pre></div><p>If a given field has multiple validation rules, you can compose them under the assumption that each validator leaves its input unchanged.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="ot">(&amp;&gt;) ::</span> <span class="dt">Monoid</span> e <span class="ot">=&gt;</span> <span class="dt">Validator</span> e a <span class="ot">-&gt;</span> <span class="dt">Validator</span> e a <span class="ot">-&gt;</span> <span class="dt">Validator</span> e a</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="dt">Validator</span> f <span class="op">&amp;&gt;</span> <span class="dt">Validator</span> g <span class="ot">=</span> <span class="dt">Validator</span> <span class="op">$</span> \x <span class="ot">-&gt;</span> f x <span class="op">*&gt;</span> g x</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="co">-- for example</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">emailValidator ::</span> <span class="dt">Validator</span> [<span class="dt">Text</span>] <span class="dt">Text</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>emailValidator <span class="ot">=</span> hasAtSymbol <span class="op">&amp;&gt;</span> hasTopLevelDomain</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        hasAtSymbol <span class="ot">=</span> <span class="dt">Validator</span> <span class="op">$</span> \email <span class="ot">-&gt;</span> </span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> <span class="st">&quot;@&quot;</span> <span class="ot">`isInfixOf`</span> email</span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">then</span> <span class="dt">Success</span> email</span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span> <span class="dt">Failure</span> [<span class="st">&quot;No @ in email&quot;</span>]</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        hasTopLevelDomain <span class="ot">=</span> <span class="dt">Validator</span> <span class="op">$</span> \email <span class="ot">-&gt;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">if</span> <span class="fu">any</span> (<span class="ot">`isSuffixOf`</span> email) topLevelDomains</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            <span class="kw">then</span> <span class="dt">Success</span> email</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            <span class="kw">else</span> <span class="dt">Failure</span> [<span class="st">&quot;Invalid TLD&quot;</span>]</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        topLevelDomains <span class="ot">=</span> [<span class="st">&quot;.com&quot;</span>, <span class="st">&quot;.org&quot;</span>, <span class="st">&quot;.co.uk&quot;</span>]  <span class="co">-- etc</span></span></code></pre></div><p>The plan is to store these <code>Validator</code>s in a record template, zip them along an instance of the record itself, and then traverse the result to get either a validated record or a collection of errors. To make things interesting, we’ll store the validation results for a given field in the matching field of another record.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Validators</span> e t <span class="ot">=</span> t (<span class="dt">Validator</span> e)</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Errors</span> e t <span class="ot">=</span> t (<span class="dt">Const</span> e)</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="co">-- turn a record of validators into a validator of records</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">validate ::</span> (<span class="dt">HasLenses</span> t, <span class="dt">FTraversable</span> t, <span class="dt">FRepresentable</span> t, <span class="dt">Monoid</span> e)</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>         <span class="ot">=&gt;</span> <span class="dt">Validators</span> e t</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="dt">Validator</span> (<span class="dt">Errors</span> e t) (<span class="dt">Record</span> t)</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>validate validators <span class="ot">=</span> <span class="dt">Validator</span> <span class="op">$</span> \record <span class="ot">-&gt;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    first unWrap <span class="op">$</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    fsequence&#39; <span class="op">$</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    fzipWith3 applyValidator lenses validators record</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        applyValidator</span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">FLens</span> lens)</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Validator</span> validator)</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Identity</span> value) <span class="ot">=</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                <span class="kw">let</span> setError e <span class="ot">=</span> <span class="fu">mempty</span> <span class="op">&amp;</span> _Wrapped&#39;<span class="op">.</span>lens<span class="op">.</span>_Wrapped&#39; <span class="op">.~</span> e</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>                <span class="kw">in</span> first setError <span class="op">$</span> validator value</span></code></pre></div><p><code>applyValidator</code> takes a lens into a record field, a validator for that field and the value in that field. It applies the validator to the value; upon failure it stores the error message (<code>e</code>) in the correct field of the <code>Errors</code> record using the lens. <code>fzipWith3</code> handles the logic of running <code>applyValidator</code> for each field of the record, then <code>fsequence'</code> combines the resulting <code>Validation</code> applicative actions into a single one. So all of the errors from all of the fields are eventually collected into the matching fields of the <code>Errors</code> record and combined monoidally.</p>
<p>A quick test, wherein I test validation on the email field:</p>
<pre><code>ghci&gt; let formValidator = validate
    $ FormTemplate emailValidator noop noop noop
ghci&gt; let today = read &quot;2017-08-17&quot; :: Day

ghci&gt; let form1 = FormTemplate
    (Identity &quot;bhodgson@stackoverflow.com&quot;)
    (Identity Visa)
    (Identity &quot;1234567890123456&quot;)
    (Identity today)
ghci&gt; runValidator formValidator form1
Success (FormTemplate {
    _email = Identity &quot;bhodgson@stackoverflow.com&quot;,
    _cardType = Identity Visa,
    _cardNumber = Identity &quot;1234567890123456&quot;,
    _cardExpiry = Identity 2017-08-17
    })

ghci&gt; let form2 = FormTemplate
    (Identity &quot;notanemail&quot;)
    (Identity Visa)
    (Identity &quot;1234567890123456&quot;)
    (Identity today)
ghci&gt; runValidator formValidator form2
Failure (FormTemplate {
    _email = Const [&quot;No @ in email&quot;,&quot;Invalid TLD&quot;],
    _cardType = Const [],
    _cardNumber = Const [],
    _cardExpiry = Const []
    })
</code></pre>
<h2 id="code-review"><a href="#code-review">Code review</a></h2>
<p>So we have a categorical framework for working with records and templates. Other things fit into this framework, more or less neatly:</p>
<ul>
<li>Monad transformers are often functorial in their <code>m</code> argument.
</li>
<li><code>Fix f</code> (a “list of <code>f</code>s”, if you will) is also a functor functor, where <code>ffmap</code>ping represents a change of variables.
</li>
<li>Since the <code>Const</code>, <code>Sum</code>, <code>Product</code> and <code>Compose</code> type combinators are poly-kinded, they can be reused as functor functors too.
</li>
<li>Add another primitive <code>FFunctor</code> to apply a functor to a type, <code>newtype At a f = At { getAt :: f a }</code>, and you have a kit to build polynomial functor functors with which you can build templates and write generic programs.
</li>
</ul>
<p>One design decision I made when developing the <code>FFunctor</code> class was to give <code>ffmap</code> a <code>(Functor f, Functor g)</code> constraint, so you can only <code>ffmap</code> between types that are in fact functors. This is mathematically principled in some sense, but it has certain engineering tradeoffs compared to an unconstrained type for <code>ffmap</code>. It enables more instances of <code>FFunctor</code> - for example, you can only write <code>Fix</code>’s <code>ffmap</code> with a <code>Functor</code> constraint for either the input or output type parameters - but it rules out certain usages of <code>ffmap</code>. You can’t <code>ffmap</code> over a template containing <code>Validator</code>s, for example, because <code>Validator</code> is not a <code>Functor</code>. I <em>didn’t</em> put the same <code>Functor</code> constraints into <code>FRepresentable</code>’s methods. An <code>FRep</code> type typically won’t be functorial - it’ll be GADT-like - so adding a <code>Functor (FRep t)</code> constraint would be far too restrictive.</p>
<p>You’ll notice that the concept of an applicative functor functor is conspicuously absent from my presentation above. <code>FApplicative</code> would probably look something like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> (f <span class="op">:-&gt;</span> g) a <span class="ot">=</span> <span class="dt">Morph</span> {<span class="ot"> getMorph ::</span> f a <span class="ot">-&gt;</span> g a }</span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">FFunctor</span> t <span class="ot">=&gt;</span> <span class="dt">FApplicative</span> t <span class="kw">where</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="ot">    fpure ::</span> (<span class="kw">forall</span> a<span class="op">.</span> f a) <span class="ot">-&gt;</span> t f</span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="ot">    fap ::</span> t (f <span class="op">:-&gt;</span> g) <span class="ot">-&gt;</span> t f <span class="ot">-&gt;</span> t g</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="ot">fliftA ::</span> <span class="dt">FApplicative</span> t <span class="ot">=&gt;</span> (f <span class="op">~&gt;</span> g) <span class="ot">-&gt;</span> t f <span class="ot">-&gt;</span> t g</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>fliftA eta t <span class="ot">=</span> fpure (<span class="dt">Morph</span> eta) <span class="ot">`fap`</span> t</span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FApplicative</span> <span class="dt">FormTemplate</span> <span class="kw">where</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    fpure x <span class="ot">=</span> <span class="dt">FormTemplate</span> x x x x</span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    fap</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        (<span class="dt">FormTemplate</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Morph</span> f1)</span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Morph</span> f2)</span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Morph</span> f3)</span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Morph</span> f4))</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>        (<span class="dt">FormTemplate</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>            email</span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>            cardType</span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            cardNumber</span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>            cardExpiry)</span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> <span class="dt">FormTemplate</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>            (f1 email)</span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>            (f2 cardType)</span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>            (f3 cardNumber)</span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>            (f4 cardExpiry)</span></code></pre></div><p><code>FApplicative</code> is a more general interface than <code>FRepresentable</code>, in that it supports notions of composition other than zipping. However, that bookkeeping <code>:-&gt;</code> <code>newtype</code> wrapper is inconvenient. With the normal <code>Applicative</code> class you can map an <em>n</em>-ary function over <em>n</em> applicative values directly: <code>f &lt;$&gt; x &lt;*&gt; y &lt;*&gt; z</code>. With <code>FApplicative</code> you have to apply the <code>Morph</code> constructor as many times as <code>f</code> has arguments: <code>fpure (Morph $ \x -&gt; Morph $ \y -&gt; Morph $ \z -&gt; f x y z) `fap` t `fap` u `fap` v</code>, which becomes very unwieldy very quickly. (<a href="https://www.reddit.com/r/haskell/comments/78xxql/structures_of_arrays_functors_and_continuations/doy80ft/">/u/rampion has come up with nicer syntax for this</a>, but it involves <a href="https://gist.github.com/rampion/20291bde6c8568c11f9cc5923d9639eb#file-ffunctor-hs-L28">a more complicated formulation of <code>FApplicative</code></a>.) On the other hand, <code>FApplicative</code> does open up some interesting options for the design of <code>FTraversable</code>: one can traverse in an <code>FApplicative</code> rather than an <code>Applicative</code>. This gives some nice type signatures - <code>fsequence :: (FTraversable t, FApplicative f) =&gt; t f -&gt; f t</code> - and is strictly more general than the <code>FTraversable</code> I gave above, since any <code>Applicative</code> can be lifted into an <code>FApplicative</code> by composition (<code>newtype ComposeAt a f g = ComposeAt { getComposeAt :: f (g a) }</code>).</p>
<p>How useful are these tools in practice? Would I structure a production application around functor functors? Probably not. It’s a question of balance - while it’s useful to recognise functorial structures in categories other than <strong>Hask</strong> as a thinking tool, actually representing such abstractions in code doesn’t always pay off. Haskell already has a rich ecosystem of tools for working with the <code>Functor</code> family, but there’s much less code in the wild that’s structured around functor functors. This is partly because <code>Functor</code> has the advantage of being a standard class in <code>base</code>, but it’s also because code built around functor functors is a little less convenient to work with, typically requiring some tedious <code>newtype</code> bookkeeping.</p>
<p>Over the course of putting together this article I came across some work by others on this very topic. I’ve spotted versions of these classes being packaged with bigger libraries such as <a href="http://hackage.haskell.org/package/hedgehog-0.5.1/docs/Hedgehog-Internal-HTraversable.html"><code>hedgehog</code></a> and <a href="https://hackage.haskell.org/package/quickcheck-state-machine-0.2.0/docs/Test-StateMachine-Types-HFunctor.html"><code>quickcheck-state-machine</code></a>. There are also a few packages providing similar tools. The most mature of these seems to be <a href="http://hackage.haskell.org/package/rank2classes"><code>rank2classes</code></a>, which includes some Template Haskell tools for deriving instances; there’s also <a href="http://hackage.haskell.org/package/conkin">the Conkin package</a>, which has <a href="https://github.com/rampion/conkin/blob/master/README.md">a well-written tutorial</a> focusing on working with data in column-major order.</p>
<p>Haskell’s full of big ideas and powerful programming idioms. In this post we saw an example of reinterpreting some familiar tools - <code>Functor</code>, <code>Traversable</code> and <code>Representable</code> - in a new context. With the intuition that a record template is a container of functors, and the formalism of functors from the functor category, we were able to reuse intuitions about those familiar tools to write terse and generic programs.</p>

]]></summary>
</entry>
<entry>
    <title>Recursion Without Recursion</title>
    <link href="http://www.benjamin.pizza/posts/2017-11-13-recursion-without-recursion.html" />
    <id>http://www.benjamin.pizza/posts/2017-11-13-recursion-without-recursion.html</id>
    <published>2017-11-13T00:00:00Z</published>
    <updated>2017-11-13T00:00:00Z</updated>
    <summary type="html"><![CDATA[
<p>If you visit <a href="https://www.stackoverflow.com/jobs">Stack Overflow Jobs</a> you’ll see that our job search form supports a simple advanced search syntax, including Boolean operators and a number of custom filters such as technology tags and minimum salary. For example, I hate writing JavaScript, but my loyalties can be bought, so I might type <a href="https://stackoverflow.com/jobs?sort=i&amp;q=%5Bc%23%5D+and+(not+%5Bjavascript%5D+or+salary%3A50000gbp)"><code>[c#] and (not [javascript] or salary:50000gbp)</code></a> into the search box. This advanced search syntax is called JQL, for <em>Jobs Query Language</em>.</p>
<p>It should come as no surprise that our codebase contains a miniature compiler for our miniature query language. Our compiler looks much like any other compiler: there’s a parser which produces an abstract syntax tree (hereafter <em>AST</em>), a pipeline of analysers and transformations which operate on that AST, and a code generator which turns the JQL into an ElasticSearch query. (Actually, queries that are simple enough end up skipping the Elastic code generation step, instead being used by an interpreter to search an in-memory cache of jobs.)</p>
<img src="/images/2017-11-13-recursion-without-recursion/compiler.jpg" alt="Compiler overview" />
<p>In this post I’m going to focus on the middle part of that pipeline: how to write operations traversing a tree with a minimum of boilerplate.</p>
<h2 id="asts-and-operations"><a href="#asts-and-operations">ASTs and operations</a></h2>
<p>The JQL AST looks roughly like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> JqlNode <span class="op">{}</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> AndNode <span class="op">:</span> JqlNode</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> JqlNode Left <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> JqlNode Right <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> OrNode <span class="op">:</span> JqlNode</span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> JqlNode Left <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> JqlNode Right <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> NotNode <span class="op">:</span> JqlNode</span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> JqlNode Operand <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> SalaryNode <span class="op">:</span> JqlNode</span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> Amount <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Currency <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> TagNode <span class="op">:</span> JqlNode</span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">string</span> Tag <span class="op">{</span> <span class="kw">get</span><span class="op">;</span> <span class="op">}</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Each syntactic form in the source language is represented as a subclass of <code>JqlNode</code>. Using the example I gave above, the input string <code>[c#] and (not [javascript] or salary:50000gbp)</code> would be represented as:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">new</span> <span class="fu">AndNode</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;c#&quot;</span><span class="op">),</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span><span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;javascript&quot;</span><span class="op">)),</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">SalaryNode</span><span class="op">(</span><span class="dv">50000</span><span class="op">,</span> <span class="st">&quot;gbp&quot;</span><span class="op">)</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div><img src="/images/2017-11-13-recursion-without-recursion/ast.jpg" alt="The abstract syntax tree" />
<p>When you need to analyse a <code>JqlNode</code>, you use pattern matching to see what type of node you have, and recursively query the operands of <code>And</code>/<code>Or</code>/<code>Not</code> nodes. Here’s a function which searches for the <code>TagNode</code>s in a tree:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>IEnumerable<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> <span class="fu">ExtractTags</span><span class="op">(</span>JqlNode node<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">switch</span> <span class="op">(</span>node<span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> TagNode t<span class="op">:</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> t<span class="op">.</span><span class="fu">Tag</span> <span class="op">};</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> AndNode a<span class="op">:</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>            <span class="co">// recursively extract the tags from the two operands</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="fu">ExtractTags</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Left</span><span class="op">).</span><span class="fu">Concat</span><span class="op">(</span><span class="fu">ExtractTags</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Right</span><span class="op">));</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> OrNode o<span class="op">:</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="fu">ExtractTags</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Left</span><span class="op">).</span><span class="fu">Concat</span><span class="op">(</span><span class="fu">ExtractTags</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Right</span><span class="op">));</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> NotNode n<span class="op">:</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="fu">ExtractTags</span><span class="op">(</span>n<span class="op">.</span><span class="fu">Operand</span><span class="op">);</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> SalaryNode s<span class="op">:</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> Enumerable<span class="op">.</span><span class="fu">Empty</span><span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;();</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>        <span class="kw">default</span><span class="op">:</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>            <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">ArgumentOutOfRangeException</span><span class="op">(</span><span class="fu">nameof</span><span class="op">(</span>node<span class="op">));</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Transforming a <code>JqlNode</code> to produce a new <code>JqlNode</code> is a similar story: you recursively traverse the tree, taking it apart and putting it back together. Here’s an example of an optimisation step which never doesn’t remove double-negatives, so a query like <code>not (not [java])</code> gets simplified to <code>[java]</code>:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>JqlNode <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>JqlNode node<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">switch</span> <span class="op">(</span>node<span class="op">)</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> NotNode n1 when n1<span class="op">.</span><span class="fu">Operand</span> <span class="kw">is</span> NotNode n2<span class="op">:</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>n2<span class="op">.</span><span class="fu">Operand</span><span class="op">);</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> TagNode t<span class="op">:</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> t<span class="op">;</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> SalaryNode s<span class="op">:</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> s<span class="op">;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> AndNode a<span class="op">:</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>            <span class="co">// recursively process the operands and rebuild the node</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">new</span> <span class="fu">AndNode</span><span class="op">(</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Left</span><span class="op">),</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Right</span><span class="op">)</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            <span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> OrNode o<span class="op">:</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>                <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Left</span><span class="op">),</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>                <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Right</span><span class="op">)</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            <span class="op">);</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> NotNode n<span class="op">:</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>                <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>n<span class="op">.</span><span class="fu">Operand</span><span class="op">)</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>            <span class="op">);</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>        <span class="kw">default</span><span class="op">:</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a>            <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">ArgumentOutOfRangeException</span><span class="op">(</span><span class="fu">nameof</span><span class="op">(</span>node<span class="op">));</span></span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>This type of code gets pretty tedious pretty quickly! In both of these functions, only one of the <code>case</code>s was interesting (<code>case TagNode t</code> in <code>ExtractTags</code> and <code>case NotNode n1 when n1.Operand is NotNode n2</code> in <code>SimplifyDoubleNegatives</code>); the rest of each function was just boilerplate to recursively operate on nodes’ children. You’re interested in a particular syntactic pattern, but searching the whole tree for that pattern requires more code than finding the pattern does. In the real JQL compiler we have about a dozen subclasses of <code>JqlNode</code>, so around 90% of the code in each operation is boilerplate!</p>
<h2 id="easier-querying"><a href="#easier-querying">Easier Querying</a></h2>
<p>Here’s the first insight that’ll help us improve on this situation. In <code>ExtractTags</code> we were searching the tree for nodes satisfying a particular pattern. But supposing you had a list of every possible subtree - the root node, all of its children, all of their children, and so on - you could use LINQ to query that list to find nodes satisfying the pattern you’re looking for. We’ll call the function which extracts the list of subtrees <code>SelfAndDescendants</code>.</p>
<p>Given a tree like the example from above (<code>[c#] and (not [javascript] or salary:50000gbp)</code>), <code>SelfAndDescendants</code> will yield every subtree in a depth-first, left-to-right manner:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">new</span> JqlNode<span class="op">[]</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">AndNode</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;c#&quot;</span><span class="op">),</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span><span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;javascript&quot;</span><span class="op">)),</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">new</span> <span class="fu">SalaryNode</span><span class="op">(</span><span class="dv">50000</span><span class="op">,</span> <span class="st">&quot;gbp&quot;</span><span class="op">)</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="op">)</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="op">),</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;c#&quot;</span><span class="op">),</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span><span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;javascript&quot;</span><span class="op">)),</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>        <span class="kw">new</span> <span class="fu">SalaryNode</span><span class="op">(</span><span class="dv">50000</span><span class="op">,</span> <span class="st">&quot;gbp&quot;</span><span class="op">)</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="op">),</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span><span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;javascript&quot;</span><span class="op">)),</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;javascript&quot;</span><span class="op">),</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> <span class="fu">SalaryNode</span><span class="op">(</span><span class="dv">50000</span><span class="op">,</span> <span class="st">&quot;gbp&quot;</span><span class="op">)</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Here’s <code>SelfAndDescendants</code> in use:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>IEnumerable<span class="op">&lt;</span><span class="dt">string</span><span class="op">&gt;</span> <span class="fu">ExtractTags</span><span class="op">(</span>JqlNode node<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> node</span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">SelfAndDescendants</span><span class="op">()</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">OfType</span><span class="op">&lt;</span>TagNode<span class="op">&gt;()</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">Select</span><span class="op">(</span>n <span class="op">=&gt;</span> n<span class="op">.</span><span class="fu">Tag</span><span class="op">);</span></span></code></pre></div><p>What an improvement! This code is much shorter, but more importantly it’s clearer and more direct. You can directly read off the intention of the code, rather than having to decipher the pattern of recursive calls. It’s also harder to get wrong - I personally am rather prone to forgetting to make a recursive call when I’m writing these sorts of functions. What’s more, <code>SelfAndDescendants</code> is totally reusable. If you can write a LINQ query, you can get whatever information you need from a <code>JqlNode</code>.</p>
<p>Of course, the pattern-matching and recursion has to go somewhere, and that somewhere is the reusable <code>SelfAndDescendants</code> function.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">static</span> IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> <span class="fu">SelfAndDescendants</span><span class="op">(</span><span class="kw">this</span> JqlNode node<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">yield</span> <span class="kw">return</span> node<span class="op">;</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">switch</span> <span class="op">(</span>node<span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> TagNode t<span class="op">:</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">yield</span> <span class="kw">break</span><span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> SalaryNode s<span class="op">:</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">yield</span> <span class="kw">break</span><span class="op">;</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> AndNode a<span class="op">:</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> descendant <span class="kw">in</span> <span class="fu">SelfAndDescendants</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Left</span><span class="op">))</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>                <span class="kw">yield</span> <span class="kw">return</span> descendant<span class="op">;</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> descendant <span class="kw">in</span> <span class="fu">SelfAndDescendants</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Right</span><span class="op">))</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                <span class="kw">yield</span> <span class="kw">return</span> descendant<span class="op">;</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> OrNode o<span class="op">:</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> descendant <span class="kw">in</span> <span class="fu">SelfAndDescendants</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Left</span><span class="op">))</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>                <span class="kw">yield</span> <span class="kw">return</span> descendant<span class="op">;</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> descendant <span class="kw">in</span> <span class="fu">SelfAndDescendants</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Right</span><span class="op">))</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>                <span class="kw">yield</span> <span class="kw">return</span> descendant<span class="op">;</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> NotNode n<span class="op">:</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> descendant <span class="kw">in</span> <span class="fu">SelfAndDescendants</span><span class="op">(</span>n<span class="op">.</span><span class="fu">Operand</span><span class="op">))</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>                <span class="kw">yield</span> <span class="kw">return</span> descendant<span class="op">;</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>        <span class="kw">default</span><span class="op">:</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>            <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">ArgumentOutOfRangeException</span><span class="op">(</span><span class="fu">nameof</span><span class="op">(</span>node<span class="op">));</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Google crawls links between pages for you, so you can search the Web for a specific piece of information; <code>SelfAndDescendants</code> crawls pointers between nodes for you, so you can search a tree for a specific piece of information. Programming tree traversals by hand is like manually clicking every link on the Web!</p>
<h2 id="a-reusable-transformer"><a href="#a-reusable-transformer">A Reusable Transformer</a></h2>
<p>How about transforming a JQL AST? <code>SimplifyDoubleNegatives</code> searches a JQL tree for a pattern and rebuilds a new version of the tree. Can this be extracted into a reusable function?</p>
<p>To rewrite a tree, you search the tree for nodes satisfying the pattern you’re looking for and replace them. As with <code>SelfAndDescendants</code>, the trick is to separate the responsibilities of <em>looking at every node in the tree</em> and <em>deciding whether to replace a given node</em>. You can write a higher-order function - let’s call it <code>Rewrite</code> - which applies a <code>Func</code> to every node in a JQL tree from bottom to top; then it’s the <code>Func</code>’s job to decide what to do with each node.</p>
<p>For example, <code>Rewrite</code> will take the query above (<code>[c#] and (not [javascript] or salary:50000gbp)</code>) and a function <code>transformer</code>, and compute the expression:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="fu">transformer</span><span class="op">(</span><span class="kw">new</span> <span class="fu">AndNode</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">transformer</span><span class="op">(</span><span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;c#&quot;</span><span class="op">)),</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">transformer</span><span class="op">(</span><span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>        <span class="fu">transformer</span><span class="op">(</span><span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            <span class="fu">transformer</span><span class="op">(</span><span class="kw">new</span> <span class="fu">TagNode</span><span class="op">(</span><span class="st">&quot;javascript&quot;</span><span class="op">))</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="op">)),</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>        <span class="fu">transformer</span><span class="op">(</span><span class="kw">new</span> <span class="fu">SalaryNode</span><span class="op">(</span><span class="dv">50000</span><span class="op">,</span> <span class="st">&quot;gbp&quot;</span><span class="op">))</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="op">))</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="op">))</span></span></code></pre></div><p>So <code>transformer</code> gets applied to every subtree exactly once. <code>Rewrite</code> is a mapping operation, like LINQ’s <code>Select</code>. Here’s how it’s implemented.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> JqlNode <span class="fu">Rewrite</span><span class="op">(</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">this</span> JqlNode node<span class="op">,</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    Func<span class="op">&lt;</span>JqlNode<span class="op">,</span> JqlNode<span class="op">&gt;</span> transformer</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">switch</span> <span class="op">(</span>node<span class="op">)</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>    <span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> TagNode t<span class="op">:</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="fu">transformer</span><span class="op">(</span>t<span class="op">);</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> SalaryNode s<span class="op">:</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="fu">transformer</span><span class="op">(</span>s<span class="op">);</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> AndNode a<span class="op">:</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">new</span> <span class="fu">AndNode</span><span class="op">(</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>                <span class="fu">transformer</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Left</span><span class="op">),</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>                <span class="fu">transformer</span><span class="op">(</span>a<span class="op">.</span><span class="fu">Right</span><span class="op">)</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a>            <span class="op">);</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> OrNode o<span class="op">:</span></span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>                <span class="fu">transformer</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Left</span><span class="op">),</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>                <span class="fu">transformer</span><span class="op">(</span>o<span class="op">.</span><span class="fu">Right</span><span class="op">)</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>            <span class="op">);</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> NotNode n<span class="op">:</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>            <span class="kw">return</span> <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span><span class="fu">transformer</span><span class="op">(</span>n<span class="op">.</span><span class="fu">Operand</span><span class="op">));</span></span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>        <span class="kw">default</span><span class="op">:</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>            <span class="kw">throw</span> <span class="kw">new</span> <span class="fu">ArgumentOutOfRangeException</span><span class="op">(</span><span class="fu">nameof</span><span class="op">(</span>node<span class="op">));</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>To use this <code>Rewrite</code> method, you write a transformation function which calculates a replacement for each node. If there’s no replacing to do, it just returns the same node. Like this:</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a>JqlNode <span class="fu">SimplifyDoubleNegatives</span><span class="op">(</span>JqlNode node<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    <span class="op">=&gt;</span> node<span class="op">.</span><span class="fu">Rewrite</span><span class="op">(</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>        n <span class="op">=&gt;</span> n <span class="kw">is</span> NotNode n1 <span class="op">&amp;&amp;</span> n1<span class="op">.</span><span class="fu">Operand</span> <span class="kw">is</span> NotNode n2</span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>            <span class="op">?</span> n2<span class="op">.</span><span class="fu">Operand</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>            <span class="op">:</span> n</span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>    <span class="op">);</span></span></code></pre></div><p>Once again, this code is a huge improvement over the verbose version which used <code>switch</code> and recursion. <code>Rewrite</code> allows us to get straight to the point and only think about the parts of the tree we’re interested in.</p>
<h2 id="from-pattern-to-library"><a href="#from-pattern-to-library">From Pattern to Library</a></h2>
<p><code>Rewrite</code> and <code>SelfAndDescendants</code> wrap up two particular types of recursion, for reuse in a wide variety of operations. This is a powerful way to program - gone are the days of writing a bespoke traversal for every operation! - and these two functions form the basis of most of the operations in the production JQL compiler, but in this form they don’t constitute a library. <code>SelfAndDescendants</code> and <code>Rewrite</code>, as written above, have knowledge of <code>JqlNode</code> baked in to them; you have to hand-write equivalent functions to work on your own datatypes.</p>
<p>We can turn this design into something generic, though, by abstracting over tree-shaped structures. What do we mean when we say a datatype is tree-shaped? The distinguishing feature which makes a tree a tree, unlike any other datatype, is recursion: each node in a tree has <em>children</em> which are also nodes.</p>
<img src="/images/2017-11-13-recursion-without-recursion/children.jpg" alt="Nodes and their children" />
<p>As the picture shows, you can reach every node in a tree just by looking at each node’s children. If you can show me how to replace your children, I can replace your children’s children and so on. So let’s use an interface to model the notion of an object with a collection of children.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">interface</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span> where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    IEnumerable<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    T <span class="fu">SetChildren</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>T<span class="op">&gt;</span> newChildren<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>A type <code>T</code> is <em>rewritable</em> if it knows how to access its immediate children - in other words, if you can get and set an <code>IEnumerable&lt;T&gt;</code> representing a node’s children. We’re working with immutable trees, remember, so <code>SetChildren</code> doesn’t modify the current instance - it returns a new <code>T</code> the same as the current instance but with different children. Part of the contract of <code>IRewritable</code> is that you shouldn’t call <code>SetChildren</code> with a different number of children to what you got from <code>GetChildren</code>. For example, an <code>And</code> node always has two children, so you shouldn’t try to call <code>SetChildren</code> with only one child (because, how would the <code>And</code> node rebuild itself?).</p>
<p>Now we can package up those <code>Rewrite</code> and <code>SelfAndDescendants</code> functions for any rewritable object, once and for all. If you show me how to reach each node’s immediate children, I can recursively apply that recipe to look at the children’s children and so on.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> IEnumerable<span class="op">&lt;</span>T<span class="op">&gt;</span> SelfAndDescendants<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T node<span class="op">)</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">yield</span> <span class="kw">return</span> node<span class="op">;</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> child <span class="kw">in</span> node<span class="op">.</span><span class="fu">GetChildren</span><span class="op">())</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">foreach</span> <span class="op">(</span><span class="dt">var</span> descendant <span class="kw">in</span> <span class="fu">SelfAndDescendants</span><span class="op">(</span>child<span class="op">))</span></span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a>            <span class="kw">yield</span> <span class="kw">return</span> descendant<span class="op">;</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a><span class="kw">static</span> T Rewrite<span class="op">&lt;</span>T<span class="op">&gt;(</span><span class="kw">this</span> T node<span class="op">,</span> Func<span class="op">&lt;</span>T<span class="op">,</span> T<span class="op">&gt;</span> transformer<span class="op">)</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>    where T <span class="op">:</span> IRewritable<span class="op">&lt;</span>T<span class="op">&gt;</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> children <span class="op">=</span> node<span class="op">.</span><span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> newChildren <span class="op">=</span> children<span class="op">.</span><span class="fu">Select</span><span class="op">(</span>c <span class="op">=&gt;</span> c<span class="op">.</span><span class="fu">Rewrite</span><span class="op">(</span>transformer<span class="op">)).</span><span class="fu">ToList</span><span class="op">();</span></span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>    <span class="dt">var</span> nodeWithNewChildren <span class="op">=</span> node<span class="op">.</span><span class="fu">SetChildren</span><span class="op">(</span>newChildren<span class="op">);</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">return</span> <span class="fu">transformer</span><span class="op">(</span>nodeWithNewChildren<span class="op">);</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>You typically implement <code>IRewritable</code> abstractly on the base type, using overrides on each subclass to find the children.</p>
<div class="sourceCode"><pre class="sourceCode"><code class="sourceCode"><span id="1"><a href="#1" aria-hidden="true" tabindex="-1"></a><span class="kw">abstract</span> <span class="kw">class</span> JqlNode <span class="op">:</span> IRewritable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span></span>
<span id="2"><a href="#2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="3"><a href="#3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">abstract</span> IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">();</span></span>
<span id="4"><a href="#4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">abstract</span> JqlNode <span class="fu">SetChildren</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> newChildren<span class="op">);</span></span>
<span id="5"><a href="#5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="6"><a href="#6" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> AndNode <span class="op">:</span> JqlNode</span>
<span id="7"><a href="#7" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="8"><a href="#8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// fields as before</span></span>
<span id="9"><a href="#9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">()</span></span>
<span id="10"><a href="#10" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> Left<span class="op">,</span> Right <span class="op">};</span></span>
<span id="11"><a href="#11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> JqlNode <span class="fu">SetChildren</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> newChildren<span class="op">)</span></span>
<span id="12"><a href="#12" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">AndNode</span><span class="op">(</span></span>
<span id="13"><a href="#13" aria-hidden="true" tabindex="-1"></a>            newChildren<span class="op">.</span><span class="fu">ElementAt</span><span class="op">(</span><span class="dv">0</span><span class="op">),</span> </span>
<span id="14"><a href="#14" aria-hidden="true" tabindex="-1"></a>            newChildren<span class="op">.</span><span class="fu">ElementAt</span><span class="op">(</span><span class="dv">1</span><span class="op">)</span></span>
<span id="15"><a href="#15" aria-hidden="true" tabindex="-1"></a>        <span class="op">);</span></span>
<span id="16"><a href="#16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="17"><a href="#17" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> OrNode <span class="op">:</span> JqlNode</span>
<span id="18"><a href="#18" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="19"><a href="#19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">()</span></span>
<span id="20"><a href="#20" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> Left<span class="op">,</span> Right <span class="op">};</span></span>
<span id="21"><a href="#21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> JqlNode <span class="fu">SetChildren</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> newChildren<span class="op">)</span></span>
<span id="22"><a href="#22" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">OrNode</span><span class="op">(</span></span>
<span id="23"><a href="#23" aria-hidden="true" tabindex="-1"></a>            newChildren<span class="op">.</span><span class="fu">ElementAt</span><span class="op">(</span><span class="dv">0</span><span class="op">),</span> </span>
<span id="24"><a href="#24" aria-hidden="true" tabindex="-1"></a>            newChildren<span class="op">.</span><span class="fu">ElementAt</span><span class="op">(</span><span class="dv">1</span><span class="op">)</span></span>
<span id="25"><a href="#25" aria-hidden="true" tabindex="-1"></a>        <span class="op">);</span></span>
<span id="26"><a href="#26" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="27"><a href="#27" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> NotNode <span class="op">:</span> JqlNode</span>
<span id="28"><a href="#28" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="29"><a href="#29" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">()</span></span>
<span id="30"><a href="#30" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span><span class="op">[]</span> <span class="op">{</span> Operand <span class="op">};</span></span>
<span id="31"><a href="#31" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> JqlNode <span class="fu">SetChildren</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> newChildren<span class="op">)</span></span>
<span id="32"><a href="#32" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">new</span> <span class="fu">NotNode</span><span class="op">(</span>newChildren<span class="op">.</span><span class="fu">Single</span><span class="op">());</span></span>
<span id="33"><a href="#33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="34"><a href="#34" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> SalaryNode <span class="op">:</span> JqlNode</span>
<span id="35"><a href="#35" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="36"><a href="#36" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">()</span></span>
<span id="37"><a href="#37" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> Enumerable<span class="op">.</span><span class="fu">Empty</span><span class="op">&lt;</span>JqlNode<span class="op">&gt;();</span></span>
<span id="38"><a href="#38" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> JqlNode <span class="fu">SetChildren</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> newChildren<span class="op">)</span></span>
<span id="39"><a href="#39" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">this</span><span class="op">;</span></span>
<span id="40"><a href="#40" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="41"><a href="#41" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> TagNode <span class="op">:</span> JqlNode</span>
<span id="42"><a href="#42" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="43"><a href="#43" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> <span class="fu">GetChildren</span><span class="op">()</span></span>
<span id="44"><a href="#44" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> Enumerable<span class="op">.</span><span class="fu">Empty</span><span class="op">&lt;</span>JqlNode<span class="op">&gt;();</span></span>
<span id="45"><a href="#45" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="kw">override</span> JqlNode <span class="fu">SetChildren</span><span class="op">(</span>IEnumerable<span class="op">&lt;</span>JqlNode<span class="op">&gt;</span> newChildren<span class="op">)</span></span>
<span id="46"><a href="#46" aria-hidden="true" tabindex="-1"></a>        <span class="op">=&gt;</span> <span class="kw">this</span><span class="op">;</span></span>
<span id="47"><a href="#47" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div><p>Note that there isn’t a single line of recursion in the JQL-specific code. It’s all wrapped up in the <code>SelfAndDescendants</code> and <code>Rewrite</code> functions, which are totally generic and reusable for any type of tree.</p>
<p>The old-fashioned way of writing reusable tree traversals is the Visitor pattern: you put the recursive traversal code in a base class, with virtual methods for each type of node that can be overridden to carry out specific operations. (This is how the Roslyn API works, for example.) <code>IRewritable</code> is a clear improvement over the Visitor pattern. Being designed around base classes and overriding, the Visitor pattern is far clunkier to use than the functional API I outlined above; and <code>IRewritable</code> allows operations like <code>Rewrite</code> can be written totally generically, whereas with the Visitor pattern every type of tree has its own Visitor base class.</p>
<h2 id="sawmill"><a href="#sawmill">Sawmill</a></h2>
<p>I’ve named this generic tree-processing library Sawmill - because it’s all about taking trees apart! - and it’s available on <a href="https://www.nuget.org/packages/Sawmill">NuGet</a> and <a href="https://github.com/benjamin-hodgson/Sawmill">GitHub</a>. I’ll outline some improvements on the design I demonstrated above, which you’ll find in Sawmill.</p>
<p>First, what I find remarkable about this design is its power-to-weight ratio. <code>IRewritable</code> is a very simple interface with an easily-grasped meaning, but you can build a load of rich, generic tools on top of it. Sawmill contains versions of <code>SelfAndDescendants</code> and <code>Rewrite</code>, but also a bunch of other extension methods at varying levels of nicheness, all getting squeezed through the <code>IRewritable</code> interface:</p>
<ul>
<li>A family of versions of <code>SelfAndDescendants</code> capturing a variety of traversal orders (preorder, postorder and breadth-first), in both eager and lazy form
</li>
<li>A <code>Fold</code> method for reducing a whole tree to a value, like LINQ’s <code>Aggregate</code>
</li>
<li>An iterative version of <code>Rewrite</code> which rewrites an expression repeatedly until it reaches a normal form
</li>
<li>Functions for replacing one node at a time
</li>
<li>A method to get an efficient mutable view of a node and its neighbours, which supports complex sequences of edits to a localised part of a tree
</li>
<li>Tools to help you implement <code>IRewriter</code>, either using a typed fluent interface or using reflection and code generation.
</li>
<li>Some minor API changes to the outline above, to enable greater efficiency for certain common cases.
</li>
</ul>
<p>I’ve also had success implementing <code>IRewritable</code> for a variety of tree-like types. Sawmill comes bundled with versions of all of these extension methods for some well-known tree types - <code>Expression</code>, <code>XmlNode</code>, and <code>XElement</code> - and I’ve written extension packages which do the same for <code>Newtonsoft.Json.Linq</code> and Roslyn’s syntax trees. (These implementations actually use a separate <code>IRewriter</code> interface, because of course I can’t add a new interface to the above types.) Realising that I could use Sawmill to layer a simple, uniform API on top of preexisting objects felt like a real validation of the design.</p>
<p>Sawmill’s version of <code>Rewrite</code> also makes an important optimisation which I glossed over above: parts of the tree which the <code>transformer</code> function didn’t change are <em>shared</em> between the new and old versions of the tree. If you change a single node, you only have to rebuild that node’s ancestors (because their children have changed), not the parts of the tree you didn’t touch.</p>
<img src="/images/2017-11-13-recursion-without-recursion/sharing.jpg" alt="The sharing optimisation" />
<p>(This is safe for immutable trees like those in Roslyn; for mutable trees like <code>XmlNode</code> the whole tree has to be copied if any part of it changes. This makes me sad - in my view those types should have been immutable all along.)</p>
<p>Finally and most importantly, I want to acknowledge Neil Mitchell’s great work in his <a href="https://hackage.haskell.org/package/uniplate"><code>uniplate</code> Haskell library</a> (and <a href="https://hackage.haskell.org/package/lens-4.15.4/docs/Control-Lens-Plated.html">its modernised port in <code>lens</code></a>), upon which Sawmill is based. I wouldn’t even have thought of this C# library if I hadn’t already encountered it in Haskell. It’s weird to think that <a href="http://ndmitchell.com/downloads/paper-uniform_boilerplate_and_list_processing-30_sep_2007.pdf"><code>uniplate</code>’s accompanying article</a> was published in 2007! Someone - my mum, if you must know - once told me that in the field of medicine it takes a decade for new research to reach mainstream practice. I think that process might take even longer in computer science, but I hope that in writing this I’ve helped these ideas along a little.</p>

]]></summary>
</entry>

</feed>
