<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Posts on Schier</title>
		<link>https://www.erikschierboom.com/posts/</link>
		<description>Recent content in Posts on Schier</description>
		<generator>Hugo -- gohugo.io</generator>
		<language>en-us</language>
		<lastBuildDate>Thu, 10 Dec 2020 00:00:00 +0000</lastBuildDate>
		<atom:link href="https://www.erikschierboom.com/posts/index.xml" rel="self" type="application/rss+xml" />
		
		<item>
			<title>Timing code using computation expressions</title>
			<link>https://www.erikschierboom.com/2020/12/10/timing-code-using-computation-expressions/</link>
			<pubDate>Thu, 10 Dec 2020 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2020/12/10/timing-code-using-computation-expressions/</guid>
			<description>While building a link checking tool, I wanted to log the time it took to check a link. For demonstration purposes, we&amp;rsquo;ll define the link checking function as follows:
let linkIsValid () = // Simulate link checking by sleeping for a second System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1.)) true To measure this function&amp;rsquo;s execution time, we&amp;rsquo;ll use the Stopwatch class, which is designed specifically for this purpose:
// This namespace contains the Stopwatch class open System.</description>
			<content type="html"><![CDATA[<p>While building a link checking tool, I wanted to log the time it took to check a link. For demonstration purposes, we&rsquo;ll define the link checking function as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">linkIsValid</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// Simulate link checking by sleeping for a second
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="nn">System</span><span class="p">.</span><span class="nn">Threading</span><span class="p">.</span><span class="nn">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="o">(</span><span class="nn">TimeSpan</span><span class="p">.</span><span class="n">FromSeconds</span><span class="o">(</span><span class="n">1</span><span class="o">.))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">true</span>
</span></span></code></pre></div><p>To measure this function&rsquo;s execution time, we&rsquo;ll use the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netcore-3.1"><code>Stopwatch</code> class</a>, which is designed specifically for this purpose:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="c1">// This namespace contains the Stopwatch class
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">open</span> <span class="nn">System.Diagnostics</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Create the stopwatch and immediately start measuring time
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Execute the function we want to time
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">let</span> <span class="nv">isValid</span> <span class="o">=</span> <span class="n">linkIsValid</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Stop measuring time
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Output the measured (elapsed) time
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">printfn</span> <span class="s">&#34;%A&#34;</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span>
</span></span></code></pre></div><p>If we run this code, the output will look like this:</p>
<pre tabindex="0"><code>00:00:01.0155117
</code></pre><p>To allow re-using the link timing functionality, we&rsquo;ll encapsulate the above code in a function which returns the link check result <em>and</em> the elapsed time as a tuple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">linkIsValidWithTiming</span><span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">  <span class="k">let</span> <span class="nv">linkStatus</span> <span class="o">=</span> <span class="n">linkIsValid</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">  <span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Return the link status _and_ the elapsed time
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="n">linkStatus</span><span class="o">,</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">isValid</span><span class="o">,</span> <span class="n">elapsed</span> <span class="o">=</span> <span class="n">linkIsValidWithTiming</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl"><span class="n">printfn</span> <span class="s">&#34;%A&#34;</span> <span class="n">elapsed</span>
</span></span></code></pre></div><h2 id="generalizing">Generalizing</h2>
<p>What if we want to mesure the execution time of other functions? Well, we can generalize the <code>linkIsValidWithTiming</code> function to work with other functions by taking the function to time as a parameter:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">executeAndTime</span> <span class="n">func</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Call the `func` parameter (which is a function)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">let</span> <span class="nv">funcResult</span> <span class="o">=</span> <span class="n">func</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">funcResult</span><span class="o">,</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span>
</span></span></code></pre></div><p>We can then pass in the <code>linkIsValid</code> function as an argument to get its result <em>and</em> its timing information:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">isValid</span><span class="o">,</span> <span class="n">elapsed</span> <span class="o">=</span> <span class="n">executeAndTime</span> <span class="n">linkIsValid</span>
</span></span><span class="line"><span class="cl"><span class="n">printfn</span> <span class="s">&#34;%A&#34;</span> <span class="n">elapsed</span>
</span></span></code></pre></div><h2 id="timing-type">Timing type</h2>
<p>To make our code more explicit, let&rsquo;s define a type to hold timing results:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Timed</span><span class="o">&lt;</span><span class="k">&#39;</span><span class="n">T</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="o">{</span> <span class="n">Result</span><span class="o">:</span> <span class="k">&#39;</span><span class="n">T</span>
</span></span><span class="line"><span class="cl">    <span class="n">Elapsed</span><span class="o">:</span> <span class="n">TimeSpan</span> <span class="o">}</span>
</span></span></code></pre></div><p>We can then return this type from our <code>executeAndTime</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">executeAndTime</span> <span class="n">func</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">  <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="n">func</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">  <span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="o">{</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">result</span><span class="o">;</span> <span class="n">Elapsed</span> <span class="o">=</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">executeAndTime</span> <span class="n">linkIsValid</span>
</span></span><span class="line"><span class="cl"><span class="n">printfn</span> <span class="s">&#34;%A&#34;</span> <span class="n">timedResult</span><span class="o">.</span><span class="n">Elapsed</span>
</span></span></code></pre></div><p>To me, this version has better <em>motivational transparency</em> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> as it makes it more explicit what the code is doing.</p>
<h2 id="timing-asynchronous-functions">Timing asynchronous functions</h2>
<p>To allow for non-blocking link checking, let&rsquo;s define an asynchronous version of the <code>linkIsValid</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">linkIsValidAsync</span> <span class="bp">()</span> <span class="o">=</span> <span class="n">async</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">do</span><span class="o">!</span> <span class="nn">Async</span><span class="p">.</span><span class="n">Sleep</span><span class="o">(</span><span class="n">1000</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="k">true</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>If we time this function, the elapsed time seems to be off:</p>
<pre tabindex="0"><code>00:00:00.0010091
</code></pre><p>As the <code>linkIsValidAsync</code> function should run for <em>at least</em> 1000 milliseconds, this can&rsquo;t be right. The problem is that we don&rsquo;t wait for the async function to complete. This means that we&rsquo;re not timing the execution of the function from begin to end, but only the time it takes to start executing. To ensure that the asynchronous function call blocks until it has completed, we can pipe it into <code>Async.RunSynchronously</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">executeAndTime</span> <span class="n">func</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">  <span class="k">let</span> <span class="nv">funcResult</span> <span class="o">=</span> <span class="n">func</span><span class="bp">()</span> <span class="o">|&gt;</span> <span class="nn">Async</span><span class="p">.</span><span class="n">RunSynchronously</span>
</span></span><span class="line"><span class="cl">  <span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="o">{</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">funcResult</span><span class="o">;</span> <span class="n">Elapsed</span> <span class="o">=</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span> <span class="o">}</span>
</span></span></code></pre></div><p>Our asynchronous function is now timed correctly:</p>
<pre tabindex="0"><code>00:00:01.0390756
</code></pre><p>However, if we try to time the old, synchronous <code>linkIsValid</code> function, we get a compile error:</p>
<pre tabindex="0"><code>[FS0001] Type mismatch. Expecting a
  &#39;unit -&gt; Async&lt;&#39;a&gt;&#39;
but given a
  &#39;unit -&gt; bool&#39;
The type &#39;Async&lt;&#39;a&gt;&#39; does not match the type &#39;bool&#39;
</code></pre><p>The compiler informs us that <code>Async.RunSynchronously</code> expects an <code>Async&lt;'a&gt;</code> argument, but that it received a <code>bool</code> argument, which is indeed what the (synchronous) <code>linkIsValid</code> function returns.</p>
<p>To fix this, let&rsquo;s revert back to our previous, synchronous version of the <code>executeAndTime</code> function (by removing <code>Async.RunSynchronously</code>). We can then pass in a lambda as the argument where we pipe the <code>linkIsValidAsync</code> result to <code>Async.RunSynchronously</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">executeAndTime</span> <span class="o">(</span><span class="k">fun</span><span class="bp">()</span> <span class="o">-&gt;</span> <span class="n">linkIsValidAsync</span><span class="bp">()</span> <span class="o">|&gt;</span> <span class="nn">Async</span><span class="p">.</span><span class="n">RunSynchronously</span><span class="o">)</span>
</span></span></code></pre></div><p>Using this approach, we can time both synchronous and asynchronous functions, without the <code>executeAndTime</code> function having to be aware of the difference. The output confirms that we correctly time our asynchronous function:</p>
<pre tabindex="0"><code>00:00:01.0390756
</code></pre><h2 id="computation-expression">Computation Expression</h2>
<p>While the function-based approach works well, wouldn&rsquo;t it be great if we could this instead?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">timed</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="n">linkIsValid</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>This code looks very similar to the <code>async</code> syntax we used before in our <code>linkIsValidAsync</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">linkIsValidAsync</span> <span class="bp">()</span> <span class="o">=</span> <span class="n">async</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">do</span><span class="o">!</span> <span class="nn">Async</span><span class="p">.</span><span class="n">Sleep</span><span class="o">(</span><span class="n">1000</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="k">true</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>As it turns out, the <code>async</code> syntax is provided by an F# feature called <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions">computation expressions</a>, which provides a convenient syntax for computations that can be sequenced and combined. Besides the <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions#built-in-computation-expressions">built-in computation expressions</a> (like <code>async</code>), one can also define custom computation expressions, so let&rsquo;s try and build a <code>timed</code> computation expression.</p>
<p>Computation expressions are implemented as classes, which are known as <em>builder</em> types. To get the nice syntax we saw above, one has to bind an instance of the builder type to an identifier. The name of the identifier determines how one can use the computation expression in code.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="c1">// Empty build class
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">type</span> <span class="nc">TimedBuilder</span><span class="bp">()</span> <span class="o">=</span> <span class="k">class</span> <span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Builder class instance. The name determines how to use the computation expression
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">let</span> <span class="nv">timed</span> <span class="o">=</span> <span class="n">TimedBuilder</span><span class="bp">()</span>
</span></span></code></pre></div><p>This will allow us to do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">timed</span> <span class="o">{}</span>
</span></span></code></pre></div><p>If we try to compile this code, we get can error:</p>
<pre tabindex="0"><code>[FS0003] This value is not a function and cannot be applied.
</code></pre><p>While the message is slightly cryptic, it tries to tell us that we&rsquo;re not doing anything in our computation expression. This starts to make sense if you realize that computation expressions are translated to method invocations on the builder type instance (in our case: <code>timed</code>). Let&rsquo;s try to mimic the <code>async</code> computation expression and return the result of calling the <code>linkIsValid</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">timed</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="n">linkIsValid</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>This time, we get the following compile error:</p>
<pre tabindex="0"><code>[FS0708] This control construct may only be used if the computation expression builder defines a &#39;Return&#39; method
</code></pre><p>This is actually very descriptive! It tells us that to be able to use the <code>return</code> keyword inside our custom computation expression, its builder (type) needs to define a <code>Return</code> method. If we <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions#creating-a-new-type-of-computation-expression">check the documentation</a>, the <code>Return</code> method should be of type <code>'T -&gt; M&lt;'T&gt;</code>. You should read this as: it takes a &ldquo;regular&rdquo; type and returns a computation expression-specific type that &ldquo;wraps&rdquo; the &ldquo;regular&rdquo; type. For our computation expression, our &ldquo;wrapped&rdquo; type is the <code>Timed&lt;'T&gt;</code> type. Let&rsquo;s add the <code>Return</code> member to the <code>TimedBuilder</code> class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">TimedBuilder</span><span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">member</span> <span class="n">x</span><span class="p">.</span><span class="nf">Return</span><span class="o">(</span><span class="n">value</span><span class="o">)</span> <span class="o">=</span> <span class="o">{</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span> <span class="n">Elapsed</span> <span class="o">=</span> <span class="nn">TimeSpan</span><span class="p">.</span><span class="n">Zero</span> <span class="o">}</span>
</span></span></code></pre></div><p>We can then use this as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">timed</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="n">linkIsValid</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="n">printfn</span> <span class="s">&#34;%A&#34;</span> <span class="n">timedResult</span><span class="o">.</span><span class="n">Elapsed</span>
</span></span></code></pre></div><p>This time, the code runs successfully and outputs:</p>
<pre tabindex="0"><code>00:00:00
</code></pre><p>Let&rsquo;s try and time the function execution:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">TimedBuilder</span><span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">member</span> <span class="n">x</span><span class="p">.</span><span class="nf">Return</span><span class="o">(</span><span class="n">value</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="n">value</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">result</span><span class="o">;</span> <span class="n">Elapsed</span> <span class="o">=</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span> <span class="o">}</span>
</span></span></code></pre></div><p>As with our <code>executeAndTime</code> function, the <code>Return</code> method now expects its parameter to be a function, which means that the computation expression should not return the result of invoking the <code>linkIsValid</code> function, but return the function itself:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">timed</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="n">linkIsValid</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>And this works! Nice and clean, right?</p>
<h3 id="improved-function-handling">Improved function handling</h3>
<p>Our current implementation is not idiomatic though. When executing functions in a computation expression, the <code>Delay</code> member should be implemented. Its signature is <code>(unit -&gt; M&lt;'T&gt;) -&gt; M&lt;'T&gt;</code>, which means that it takes a function without parameters that returns the &ldquo;wrapped&rdquo; type and also returns the &ldquo;wrapped&rdquo; type. Let&rsquo;s implement this method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">TimedBuilder</span><span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">member</span> <span class="n">x</span><span class="p">.</span><span class="nf">Delay</span><span class="o">(</span><span class="n">func</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">func</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">timedResult</span> <span class="k">with</span> <span class="n">Elapsed</span> <span class="o">=</span> <span class="n">timedResult</span><span class="o">.</span><span class="n">Elapsed</span> <span class="o">+</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span> <span class="o">}</span>
</span></span></code></pre></div><p>The time measuring code is the same, the biggest change is that when we invoke the <code>func</code> parameter, we receive a <code>Timed&lt;'T&gt;</code> value. We then deconstruct this value and return a new <code>Timed&lt;'T&gt;</code> instance, but with the elapsed time as measured by the stopwatch added to the elapsed time returned by the function. If we try to compile this, we get:</p>
<pre tabindex="0"><code>[FS0708] This control construct may only be used if the computation expression builder defines a &#39;Return&#39; method
</code></pre><p>Whoops. We&rsquo;re still using the <code>return</code> keyword in our computation expression invocation, which means that we still have to implement the <code>Return</code> method. Note though that any value passed to the <code>Return</code> method is automatically wrapped in a &ldquo;delay&rdquo; function and passed to the <code>Delay</code> method to execute. We can use our original <code>Return</code> method implementation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">TimedBuilder</span><span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="k">member</span> <span class="n">x</span><span class="p">.</span><span class="nf">Return</span><span class="o">(</span><span class="n">value</span><span class="o">)</span> <span class="o">=</span> <span class="o">{</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">value</span><span class="o">;</span> <span class="n">Elapsed</span> <span class="o">=</span> <span class="nn">TimeSpan</span><span class="p">.</span><span class="n">Zero</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">member</span> <span class="n">x</span><span class="p">.</span><span class="nf">Delay</span><span class="o">(</span><span class="n">func</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">stopwatch</span> <span class="o">=</span> <span class="nn">Stopwatch</span><span class="p">.</span><span class="n">StartNew</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span> <span class="n">func</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">stopwatch</span><span class="o">.</span><span class="n">Stop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">timedResult</span> <span class="k">with</span> <span class="n">Elapsed</span> <span class="o">=</span> <span class="n">timedResult</span><span class="o">.</span><span class="n">Elapsed</span> <span class="o">+</span> <span class="n">stopwatch</span><span class="o">.</span><span class="n">Elapsed</span> <span class="o">}</span>
</span></span></code></pre></div><p>We&rsquo;ll have to change our computation expression to actually invoke the <code>linkIsValid</code> function again:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="n">timed</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">linkIsValid</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span></code></pre></div><p>And we&rsquo;re back to things working. Note that we can now also return a constant value from our computation expression (although that admittedly doesn&rsquo;t make much sense):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">timedResult</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="n">timed</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">2</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span></code></pre></div><p>And with that, we have created a computation expression that elegantly allows us to measure function execution time using a nice and concise syntax.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Computation expressions are a great way to help make your code more expressive. While writing a computation expression takes a little getting used to, they are not that hard once you&rsquo;re familiar with their implementation rules. The compiler is also quite helpful, outputting detailed error message that help pinpoint what methods to implement.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://www.apress.com/gp/book/9781484239995">Stylish F# by Kit Eason</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content>
		</item>
		
		<item>
			<title>Cleaning up local git branches deleted on a remote</title>
			<link>https://www.erikschierboom.com/2020/02/17/cleaning-up-local-git-branches-deleted-on-a-remote/</link>
			<pubDate>Mon, 17 Feb 2020 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2020/02/17/cleaning-up-local-git-branches-deleted-on-a-remote/</guid>
			<description>Introduction When using git, local branches can track remote branches that no longer exist (the remote branch is gone). To identify these branches, we first have to cleanup (prune) the remote&amp;rsquo;s branches:
$ git fetch -p From https://test.com - [deleted] (none) -&amp;gt; origin/disable-feature-x - [deleted] (none) -&amp;gt; origin/fix-typo - [deleted] (none) -&amp;gt; origin/grammar-fix In this case, three remote branches were deleted. Let&amp;rsquo;s see if we have local branches that are tracking deleted branches:</description>
			<content type="html"><![CDATA[<h1 id="introduction">Introduction</h1>
<p>When using <a href="https://git-scm.com/">git</a>, local branches can track remote branches that no longer exist (the remote branch is <em>gone</em>). To identify these branches, we first have to cleanup (prune) the remote&rsquo;s branches:</p>
<pre tabindex="0"><code>$ git fetch -p
From https://test.com
 - [deleted]         (none)     -&gt; origin/disable-feature-x
 - [deleted]         (none)     -&gt; origin/fix-typo
 - [deleted]         (none)     -&gt; origin/grammar-fix
</code></pre><p>In this case, three remote branches were deleted. Let&rsquo;s see if we have local branches that are tracking deleted branches:</p>
<pre tabindex="0"><code>$ git branch -v
  fix-typo            7b57d4f [gone] Fix typo in README
  grammar-fix         01257bd [gone] Fix some bad grammar
* master              477010d Bump to version 1.1
</code></pre><p>There are three local branches, of which two (<code>fix-typo</code> and <code>grammar-fix</code>) are marked with <code>[gone]</code>. This indicates that these branches are indeed tracking remote branches that have been deleted.</p>
<p>Unfortunately, git does not have built-in functionality to cleanup these local branches. Our only option is to manually delete them through <code>git branch -d &lt;branch-name&gt;</code>. But what if there are many of these branches? Things would get tedious quickly, so let&rsquo;s try to automate this!</p>
<h1 id="identifying-the-gone-branches">Identifying the gone branches</h1>
<p>The first step in our automation is to identify the branches to delete. A naive approach would be to parse the aforementioned output of <code>git branch -v</code>. However, this is problematic for the following reasons:</p>
<ol>
<li>The output could change in the future. See <a href="https://git-blame.blogspot.com/2013/06/checking-current-branch-programatically.html">this blog post</a> by Junio C Hamano (git maintainer).</li>
<li>The output can be modified by the user. See <a href="https://stackoverflow.com/a/26152574/2071395">this StackOverflow post</a>.</li>
</ol>
<p>Hmmm, let&rsquo;s try a different approach. It so happens that the <a href="https://git-scm.com/docs/git-for-each-ref"><code>git for-each-ref</code> command</a> lets us specify its output format, neatly circumventing the aforementioned problems.</p>
<p>We can use <code>git for-each-ref</code> to list all branches <em>and</em> their upstream&rsquo;s branch&rsquo;s status in our desired format:</p>
<pre tabindex="0"><code>$ git for-each-ref --format &#39;%(refname) %(upstream:track)&#39;
refs/heads/bugfix-1
refs/heads/fix-typo [gone]
refs/heads/grammar-fix [gone]
refs/heads/master [behind 15]
refs/heads/new-function [ahead 2, behind 9]
refs/remotes/origin/HEAD
refs/remotes/origin/master
refs/remotes/origin/new-function
refs/stash
</code></pre><p>Now this is something we can work with! As we&rsquo;re only interested in our local branches (heads), we&rsquo;ll filter them by appending <code>refs/heads</code> to our command:</p>
<pre tabindex="0"><code>$ git for-each-ref --format &#39;%(refname) %(upstream:track)&#39; refs/heads
refs/heads/bugfix-1
refs/heads/fix-typo [gone]
refs/heads/grammar-fix [gone]
refs/heads/master [behind 15]
refs/heads/new-function [ahead 2, behind 9]
</code></pre><p>Nice. We can do one last optimization here, and that is to return the branches in their shortened format by using <code>refname:short</code>:</p>
<pre tabindex="0"><code>$ git for-each-ref --format &#39;%(refname:short) %(upstream:track)&#39; refs/heads
bugfix-1
fix-typo [gone]
grammar-fix [gone]
master [behind 15]
new-function [ahead 2, behind 9]
</code></pre><p>Great! We now have a reliable, consistent way to retrieve our local branches and their remote tracking status.</p>
<h1 id="deleting-the-gone-branches">Deleting the gone branches</h1>
<p>The next step is to filter the branches which remote branch is gone. We can do this by piping the output to <code>awk</code>, which can filter the branches and print their name (removing the remote tracking status):</p>
<pre tabindex="0"><code>$ git for-each-ref --format &#39;%(refname:short) %(upstream:track)&#39; |
  awk &#39;$2 == &#34;[gone]&#34; {print $1}&#39;
fix-typo
grammar-fix
</code></pre><p>Sweet! The final step is to pipe this output to <code>xargs</code> to delete the branches:</p>
<pre tabindex="0"><code>$ git for-each-ref --format &#39;%(refname:short) %(upstream:track)&#39; |
  awk &#39;$2 == &#34;[gone]&#34; {print $1}&#39; |
  xargs -r git branch -D

Deleted branch fix-typo (was 7b57d4f).
Deleted branch grammar-fix (was 01257bd).
</code></pre><p>And that&rsquo;s it! We now have a single command to delete all local branches which remote tracking branches have been deleted.</p>
<h1 id="integrating-with-git">Integrating with git</h1>
<p>Our final step is to add our command as a <a href="https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases">git alias</a>, which allows one to define custom commands that can be called as if they were built into git. Aliases in git are defined in the <code>.gitconfig</code> file found in your home dir. You can edit this file by running: <code>git config --global --edit</code>. Within that file, find the <code>[alias]</code> section (or add it), and add an alias to it named <code>gone</code>:</p>
<pre tabindex="0"><code>[alias]
  gone = ! &#34;git fetch -p &amp;&amp; git for-each-ref --format &#39;%(refname:short) %(upstream:track)&#39; | awk &#39;$2 == \&#34;[gone]\&#34; {print $1}&#39; | xargs -r git branch -D&#34;
</code></pre><p>The <code>gone</code> alias does two things:</p>
<ol>
<li>Run <code>git fetch -p</code> (to remove any deleted remote branches).</li>
<li>Run our custom command (to remove local branches with a deleted remote branch).</li>
</ol>
<p>Having added our alias, we can now run <code>git gone</code> as if it was a built-in command:</p>
<pre tabindex="0"><code>$ git gone

Deleted branch fix-typo (was 7b57d4f).
Deleted branch grammar-fix (was 01257bd).
</code></pre><p>The behavior is exactly the same as manually running <code>git fetch -p</code> followed by our custom command. Nice, isn&rsquo;t it?</p>
<p>You don&rsquo;t even have to manually edit the <code>.gitconfig</code> file, as the alias can also be added using the following command:</p>
<pre tabindex="0"><code>git config --global alias.gone &#34;! git fetch -p &amp;&amp; git for-each-ref --format &#39;%(refname:short) %(upstream:track)&#39; | awk &#39;\$2 == \&#34;[gone]\&#34; {print \$1}&#39; | xargs -r git branch -D&#34;
</code></pre><p>Interestingly, due to the way git is implemented on Windows, the above alias also works on Windows.</p>
<h1 id="conclusion">Conclusion</h1>
<p>In this blog post, we&rsquo;ve shown how to cleanup local git branches that are tracking remote branches that no longer exist. We did this by combining the <code>git for-each-ref</code> command with the <code>awk</code> and <code>xargs</code> commands. As a bonus, we added a git alias for our cleanup command that allows us to cleanup our local branches using <code>git gone</code>.</p>
]]></content>
		</item>
		
		<item>
			<title>Solving reverse polish notation equations in WebAssembly using F#</title>
			<link>https://www.erikschierboom.com/2019/12/06/solving-reverse-polish-notation-equations-in-webassembly-using-f/</link>
			<pubDate>Fri, 06 Dec 2019 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2019/12/06/solving-reverse-polish-notation-equations-in-webassembly-using-f/</guid>
			<description>Note: this blog post is part of the F# advent calendar 2019.
Introduction In this blog post, we&amp;rsquo;ll build a website that can solve Reverse Polish Notation (RPN) equations. All code (including the website) will be written in F#, but the equations themselves will be solved using WebAssembly.
Reverse Polish Notation In RPN equations, operators (+, -, etc.) follow their operands (1, 3, etc.). This is known as postfix notation. Its main advantage: parentheses are no longer needed to define precedence.</description>
			<content type="html"><![CDATA[<p>Note: this blog post is part of the <a href="https://sergeytihon.com/2019/11/05/f-advent-calendar-in-english-2019/">F# advent calendar 2019</a>.</p>
<h1 id="introduction">Introduction</h1>
<p>In this blog post, we&rsquo;ll build a website that can solve <a href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse Polish Notation</a> (RPN) equations. All code (including the website) will be written in F#, but the equations themselves will be solved using <a href="https://webassembly.org/">WebAssembly</a>.</p>
<h1 id="reverse-polish-notation">Reverse Polish Notation</h1>
<p>In RPN equations, operators (<code>+</code>, <code>-</code>, etc.) follow their operands (<code>1</code>, <code>3</code>, etc.). This is known as postfix notation. Its main advantage: parentheses are no longer needed to define precedence. Consider the following equation (in standard mathematical notation):</p>
<pre tabindex="0"><code>(1 + 3) * (5 - 2)
</code></pre><p>This is the same equation, but specified in RPN:</p>
<pre tabindex="0"><code>1 3 + 5 2 - *
</code></pre><p>To solve this RPN equation we can just interpret its parts as a series of stack operations:</p>
<ul>
<li>Push <code>1</code> on the stack.</li>
<li>Push <code>3</code> on the stack.</li>
<li>Pop <code>3</code> from the stack. Pop <code>1</code> from the stack. Apply the <code>+</code> operator to the popped operands. Push <code>4</code> on the stack.</li>
<li>Push <code>5</code> on the stack.</li>
<li>Push <code>2</code> on the stack.</li>
<li>Pop <code>2</code> from the stack. Pop <code>5</code> from the stack. Apply the <code>-</code> operator to the popped operands. Push <code>3</code> on the stack.</li>
<li>Pop <code>3</code> from the stack. Pop <code>4</code> from the stack. Apply the <code>*</code> operator to the popped operands. Push <code>12</code> on the stack.</li>
</ul>
<p>As you can imagine, the code to solve RPN equations will be a lot simpler than code to solve equations in standard mathematical notation, as the latter requires one to handle operator precedence rules and nesting (parentheses).</p>
<p>Side note: the famous Edsger Dijkstra invented the <a href="https://en.wikipedia.org/wiki/Shunting-yard_algorithm">Shunting-yard algorithm</a> to convert from infix notation to postfix notation.</p>
<p>In order for our website to be able to solve RPN equations, we&rsquo;ll start by building a parser. As said, all our code will be written in F#.</p>
<h2 id="parsing">Parsing</h2>
<p>Each RPN equation is composed of:</p>
<ol>
<li>Operands (the integers).</li>
<li>Operators (the functions).</li>
</ol>
<p>We&rsquo;ll model this as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Add</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Sub</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Mul</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Div</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operand</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Integer</span> <span class="k">of</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Expression</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="k">of</span> <span class="n">Operator</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperandExpression</span> <span class="k">of</span> <span class="n">Operand</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Equation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Equation</span> <span class="k">of</span> <span class="n">Expression</span> <span class="kt">list</span>
</span></span></code></pre></div><p>Our model allows for both empty- and invalid equations. A more advanced model would make <a href="https://fsharpforfunandprofit.com/posts/designing-with-types-making-illegal-states-unrepresentable/">illegal states unrepresentable</a>, but for now we&rsquo;ll keep it simple.</p>
<p>Not all equations will be valid though. There are three types of errors we&rsquo;ll cover:</p>
<ul>
<li>Empty equations: no operands nor operators.</li>
<li>Invalid equations: one or more unknown tokens.</li>
<li>Unbalanced equations: equation does not resolve to a single operand.</li>
</ul>
<p>We&rsquo;ll model these errors as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">EquationError</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Empty</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Invalid</span> <span class="k">of</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Unbalanced</span>
</span></span></code></pre></div><p>Now on to the actual parsing. First, let&rsquo;s try to parse an expression (which is either an operand or an operator):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseExpression</span> <span class="o">(</span><span class="n">word</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">Expression</span><span class="o">,</span> <span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">word</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;+&#34;</span> <span class="o">-&gt;</span> <span class="n">Ok</span><span class="o">(</span><span class="n">OperatorExpression</span> <span class="n">Add</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;-&#34;</span> <span class="o">-&gt;</span> <span class="n">Ok</span><span class="o">(</span><span class="n">OperatorExpression</span> <span class="n">Sub</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;*&#34;</span> <span class="o">-&gt;</span> <span class="n">Ok</span><span class="o">(</span><span class="n">OperatorExpression</span> <span class="n">Mul</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;/&#34;</span> <span class="o">-&gt;</span> <span class="n">Ok</span><span class="o">(</span><span class="n">OperatorExpression</span> <span class="n">Div</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Int32</span> <span class="n">i</span> <span class="o">-&gt;</span> <span class="n">Ok</span><span class="o">(</span><span class="n">OperandExpression</span><span class="o">(</span><span class="n">Integer</span> <span class="n">i</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">Error</span><span class="o">(</span><span class="n">Invalid</span> <span class="n">word</span><span class="o">)</span>
</span></span></code></pre></div><p>This is fairly straightforward code, where we map strings to operator expressions and integers to operand expressions using a <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/active-patterns#partial-active-patterns">custom active pattern</a>. Note that the return type is not an <code>Expression</code>, but a <code>Result&lt;Expression, EquationError&gt;</code>, as we also want to capture if the word we tried to parse was invalid.</p>
<p>Our next step is to convert a <code>string</code> to its words (represented as a list of strings):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">module</span> <span class="nn">String</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">words</span> <span class="o">(</span><span class="n">str</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="kt">string</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="n">str</span><span class="o">.</span><span class="n">Trim</span><span class="bp">()</span><span class="o">.</span><span class="n">Split</span><span class="o">([|</span> <span class="sc">&#39; &#39;</span> <span class="o">|],</span> <span class="nn">StringSplitOptions</span><span class="p">.</span><span class="n">RemoveEmptyEntries</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">ofArray</span>
</span></span></code></pre></div><p>Using these two functions, we can start building the <code>parse</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parse</span> <span class="o">(</span><span class="n">str</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">Equation</span><span class="o">,</span> <span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">words</span> <span class="o">=</span> <span class="nn">String</span><span class="p">.</span><span class="n">words</span> <span class="n">str</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">expressions</span> <span class="o">=</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span> <span class="n">parseExpression</span> <span class="n">words</span>
</span></span><span class="line"><span class="cl">    <span class="o">...</span>
</span></span></code></pre></div><p>The <code>expressions</code> value has type <code>Result&lt;Expression, EquationError&gt; list</code>, so it is a list of <code>Result</code>&rsquo;s. We&rsquo;d like to convert it to a <code>Result&lt;Expression list, EquationError&gt;</code>, as we can then convert the <code>Expression list</code> to an <code>Equation</code>. We can flatten the <code>Result list</code> into a single <code>Result</code> using this function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">module</span> <span class="nn">Result</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">ofList</span> <span class="o">(</span><span class="n">results</span><span class="o">:</span> <span class="n">Result</span><span class="o">&lt;</span><span class="k">&#39;</span><span class="n">a</span><span class="o">,</span> <span class="k">&#39;</span><span class="n">b</span><span class="o">&gt;</span> <span class="kt">list</span><span class="o">):</span> <span class="n">Result</span><span class="o">&lt;</span><span class="k">&#39;</span><span class="n">a</span> <span class="kt">list</span><span class="o">,</span> <span class="k">&#39;</span><span class="n">b</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">folder</span> <span class="n">resultState</span> <span class="n">resultElement</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">            <span class="k">match</span> <span class="n">resultState</span><span class="o">,</span> <span class="n">resultElement</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="n">Ok</span> <span class="n">results</span><span class="o">,</span> <span class="n">Ok</span> <span class="n">element</span> <span class="o">-&gt;</span> <span class="n">Ok</span><span class="o">(</span><span class="n">element</span> <span class="o">::</span> <span class="n">results</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="n">Error</span> <span class="n">err</span><span class="o">,</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">Error</span> <span class="n">err</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="o">_,</span> <span class="n">Error</span> <span class="n">err</span> <span class="o">-&gt;</span> <span class="n">Error</span> <span class="n">err</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">results</span>
</span></span><span class="line"><span class="cl">        <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">fold</span> <span class="n">folder</span> <span class="o">(</span><span class="n">Ok</span> <span class="bp">[]</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">map</span> <span class="nn">List</span><span class="p">.</span><span class="n">rev</span>
</span></span></code></pre></div><p>We are now able to create a complete, working version of our <code>parse</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parse</span> <span class="o">(</span><span class="n">str</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">Equation</span><span class="o">,</span> <span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">str</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">String</span><span class="p">.</span><span class="n">words</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span> <span class="n">parseExpression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">ofList</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">map</span> <span class="n">Equation</span>
</span></span></code></pre></div><p>Let&rsquo;s try calling our <code>parse</code> function to test it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">parse</span> <span class="s">&#34;1 2 +&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">Equation</span><span class="o">,</span><span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">  <span class="n">Ok</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">Equation</span>
</span></span><span class="line"><span class="cl">       <span class="o">[</span><span class="n">OperandExpression</span> <span class="o">(</span><span class="n">Integer</span> <span class="n">1</span><span class="o">);</span> <span class="n">OperandExpression</span> <span class="o">(</span><span class="n">Integer</span> <span class="n">2</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">OperatorExpression</span> <span class="n">Add</span><span class="o">])</span>
</span></span></code></pre></div><p>Hurray! Parsing works. We&rsquo;re not completely done with parsing though, as we have two types of errors that we haven&rsquo;t checked for: empty- and unbalanced equations. To handle these cases, we&rsquo;ll add the following function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">validate</span> <span class="o">(</span><span class="n">expressions</span><span class="o">:</span> <span class="n">Expression</span> <span class="kt">list</span><span class="o">):</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">Expression</span> <span class="kt">list</span><span class="o">,</span> <span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">rec</span> <span class="n">helper</span> <span class="n">remainder</span> <span class="n">stack</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="k">match</span> <span class="n">remainder</span><span class="o">,</span> <span class="n">stack</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="bp">[]</span><span class="o">,</span> <span class="bp">[]</span> <span class="o">-&gt;</span> <span class="n">Error</span> <span class="n">Empty</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="bp">[]</span><span class="o">,</span> <span class="o">[</span> <span class="n">OperandExpression</span> <span class="o">_</span> <span class="o">]</span> <span class="o">-&gt;</span> <span class="n">Ok</span><span class="o">(</span><span class="n">expressions</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="n">OperandExpression</span> <span class="n">i</span> <span class="o">::</span> <span class="n">xs</span><span class="o">,</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">helper</span> <span class="n">xs</span> <span class="o">(</span><span class="n">OperandExpression</span> <span class="n">i</span> <span class="o">::</span> <span class="n">stack</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">i</span> <span class="o">::</span> <span class="n">xs</span><span class="o">,</span> <span class="n">OperandExpression</span> <span class="o">_</span> <span class="o">::</span> <span class="n">OperandExpression</span> <span class="o">_</span> <span class="o">::</span> <span class="n">ys</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="n">helper</span> <span class="n">xs</span> <span class="o">(</span><span class="n">OperandExpression</span><span class="o">(</span><span class="n">Integer</span> <span class="n">0</span><span class="o">)</span> <span class="o">::</span> <span class="n">ys</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">Error</span> <span class="n">Unbalanced</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">helper</span> <span class="n">expressions</span> <span class="bp">[]</span>
</span></span></code></pre></div><p>Using pattern matching and recursion, we&rsquo;re walking through an <code>Expression list</code> and check to see if it is empty or unbalanced (an operator is found but not enough operands to work with). We can insert this function into our parsing pipeline using <code>Result.bind</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parse</span> <span class="n">str</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">str</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">String</span><span class="p">.</span><span class="n">words</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span> <span class="n">parseExpression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">ofList</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">bind</span> <span class="n">validate</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">map</span> <span class="n">Equation</span>
</span></span></code></pre></div><p>Let&rsquo;s verify that our pipeline detects these errors:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">parse</span> <span class="s">&#34;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">Equation</span><span class="o">,</span><span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Error</span> <span class="n">Empty</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">parse</span> <span class="s">&#34;3 4 + -&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">Equation</span><span class="o">,</span><span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Error</span> <span class="n">Unbalanced</span>
</span></span></code></pre></div><p>Looks like it&rsquo;s working!</p>
<h1 id="repl">REPL</h1>
<p>Before we move on to the WebAssembly part, let&rsquo;s build a tiny REPL in which we can solve RPN equations. First, let&rsquo;s add code to evaluate (solve) an equation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">EvaluationResult</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EvaluationResult</span> <span class="k">of</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">evaluateExpression</span> <span class="o">(</span><span class="n">stack</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span><span class="o">)</span> <span class="o">(</span><span class="n">expression</span><span class="o">:</span> <span class="n">Expression</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">expression</span><span class="o">,</span> <span class="n">stack</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperandExpression</span><span class="o">(</span><span class="n">Integer</span> <span class="n">operand</span><span class="o">),</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">operand</span> <span class="o">::</span> <span class="n">stack</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Add</span><span class="o">,</span> <span class="n">x</span> <span class="o">::</span> <span class="n">y</span> <span class="o">::</span> <span class="n">xs</span> <span class="o">-&gt;</span> <span class="n">y</span> <span class="o">+</span> <span class="n">x</span> <span class="o">::</span> <span class="n">xs</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Sub</span><span class="o">,</span> <span class="n">x</span> <span class="o">::</span> <span class="n">y</span> <span class="o">::</span> <span class="n">xs</span> <span class="o">-&gt;</span> <span class="n">y</span> <span class="o">-</span> <span class="n">x</span> <span class="o">::</span> <span class="n">xs</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Mul</span><span class="o">,</span> <span class="n">x</span> <span class="o">::</span> <span class="n">y</span> <span class="o">::</span> <span class="n">xs</span> <span class="o">-&gt;</span> <span class="n">y</span> <span class="o">*</span> <span class="n">x</span> <span class="o">::</span> <span class="n">xs</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Div</span><span class="o">,</span> <span class="n">x</span> <span class="o">::</span> <span class="n">y</span> <span class="o">::</span> <span class="n">xs</span> <span class="o">-&gt;</span> <span class="n">y</span> <span class="o">/</span> <span class="n">x</span> <span class="o">::</span> <span class="n">xs</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="o">_,</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Invalid expression&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">evaluateEquation</span> <span class="o">(</span><span class="n">Equation</span> <span class="n">expressions</span><span class="o">):</span> <span class="n">EvaluationResult</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">expressions</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">fold</span> <span class="n">evaluateExpression</span> <span class="bp">[]</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">head</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">EvaluationResult</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">evaluate</span> <span class="o">(</span><span class="n">str</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">EvaluationResult</span><span class="o">,</span> <span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parse</span> <span class="n">str</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">map</span> <span class="n">evaluateEquation</span>
</span></span></code></pre></div><p>Here you can clearly see the stack-based algorithm reflected that we mentioned in the RPN introduction.</p>
<p>Now all that&rsquo;s left is to create a REPL loop:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">printInstructions</span><span class="bp">()</span><span class="o">:</span> <span class="kt">unit</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">printfn</span> <span class="s">&#34;Please enter an equation and evaluate it by pressing enter...&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">read</span><span class="bp">()</span><span class="o">:</span> <span class="kt">unit</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Console</span><span class="p">.</span><span class="n">ReadLine</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">eval</span> <span class="o">(</span><span class="n">input</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="kt">unit</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">evaluate</span> <span class="n">input</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">printOutcome</span> <span class="o">(</span><span class="n">EvaluationResult</span> <span class="n">outcome</span><span class="o">):</span> <span class="kt">unit</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">printfn</span> <span class="s">&#34;Outcome: %A&#34;</span> <span class="n">outcome</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parserErrorMessage</span> <span class="o">(</span><span class="n">error</span><span class="o">:</span> <span class="n">EquationError</span><span class="o">):</span> <span class="kt">string</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">error</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Empty</span> <span class="o">-&gt;</span> <span class="s">&#34;Empty equation&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Invalid</span> <span class="n">token</span> <span class="o">-&gt;</span> <span class="n">sprintf</span> <span class="s">&#34;Invalid token: %s&#34;</span> <span class="n">token</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Unbalanced</span> <span class="o">-&gt;</span> <span class="s">&#34;Equation is unbalanced&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">printError</span> <span class="o">(</span><span class="n">error</span><span class="o">:</span> <span class="n">EquationError</span><span class="o">):</span> <span class="kt">unit</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">errorMessage</span> <span class="o">=</span> <span class="n">parserErrorMessage</span> <span class="n">error</span>
</span></span><span class="line"><span class="cl">    <span class="n">printfn</span> <span class="s">&#34;Error: %s&#34;</span> <span class="n">errorMessage</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">print</span> <span class="o">(</span><span class="n">result</span><span class="o">:</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">EvaluationResult</span><span class="o">,</span> <span class="n">EquationError</span><span class="o">&gt;):</span> <span class="kt">unit</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">result</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Ok</span> <span class="n">outcome</span> <span class="o">-&gt;</span> <span class="n">printOutcome</span> <span class="n">outcome</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Error</span> <span class="n">error</span> <span class="o">-&gt;</span> <span class="n">printError</span> <span class="n">error</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">loop</span><span class="bp">()</span><span class="o">:</span> <span class="kt">unit</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="k">true</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">        <span class="n">read</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">        <span class="o">|&gt;</span> <span class="n">eval</span>
</span></span><span class="line"><span class="cl">        <span class="o">|&gt;</span> <span class="n">print</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">EntryPoint</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">main</span> <span class="o">_</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">printInstructions</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">loop</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">0</span>
</span></span></code></pre></div><p>Simple and elegant. Let&rsquo;s try out the REPL:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Please enter an equation and evaluate it by pressing enter...
</span></span><span class="line"><span class="cl"><span class="m">1</span> <span class="m">2</span> +
</span></span><span class="line"><span class="cl">Outcome: <span class="m">3</span>
</span></span><span class="line"><span class="cl"><span class="m">2</span> <span class="m">4</span> * + <span class="m">7</span>
</span></span><span class="line"><span class="cl">Error: Equation is unbalanced
</span></span></code></pre></div><p>Nice. We&rsquo;re ready to move on solving RPN equations using WebAssembly.</p>
<h1 id="webassembly">WebAssembly</h1>
<p>Before we dive into the details, let&rsquo;s refresh our knowledge on what WebAssembly is. The <a href="https://webassembly.org/">official website</a> has the following definition:</p>
<blockquote>
<p>WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.</p>
</blockquote>
<p>A great way to learn more about WebAssembly is to check out the <a href="https://hacks.mozilla.org/2017/02/a-cartoon-intro-to-webassembly/">cartoon intro to WebAssembly by Lin Clark</a>. For now, just keep in mind that WebAssembly can be executed in the browser and that there is both a <a href="https://webassembly.github.io/spec/core/binary/index.html">binary format</a> (WASM) and a <a href="https://webassembly.github.io/spec/core/text/index.html">text format</a> (WAT).</p>
<p>As said, our goal will be to have a website that can solve RPN equations. The first step is to parse the equation (using the code we just wrote). The parsed equation will then be compiled to (binary) WebAssembly code. The WebAssembly code is then executed in the browser. Finally, we&rsquo;ll display the result of the solved equation as well as the WebAssembly used to solve it (binary <em>and</em> text format). Sounds fun? Let&rsquo;s get to it!</p>
<h2 id="generating-webassembly">Generating WebAssembly</h2>
<p>In principle, we could be writing F# to output a generic RPN notation solver in WebAssembly, but to keep things simple, we&rsquo;ll just compile the minimal WebAssembly needed to solve a RPN equation.</p>
<p>The stack-based algorithm used five types of operations:</p>
<ul>
<li>Push a number.</li>
<li>Add two numbers.</li>
<li>Subtract two numbers.</li>
<li>Multiply two numbers.</li>
<li>Divide two numbers.</li>
</ul>
<p>If we look at the available <a href="%5Binstructions%5D(https://webassembly.github.io/spec/core/exec/instructions.html)">WebAssembly instructions</a>, we can find direct counterparts for all these operations, which we&rsquo;ll model as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">WebAssemblyInstruction</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Const</span> <span class="k">of</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Add</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Sub</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Mul</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Div</span>
</span></span></code></pre></div><p>In our domain, we only support a single numeric type: 32-bit integers. In WebAssembly, these types are referred to as <a href="https://webassembly.github.io/spec/core/syntax/types.html#syntax-valtype">value types</a>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">WebAssemblyValueType</span> <span class="o">=</span> <span class="n">I32</span>
</span></span></code></pre></div><p>For our purposes, a WebAssembly function can be modelled as a name, result type and a list of instructions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">WebAssemblyFunction</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Name</span><span class="o">:</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl">      <span class="n">Result</span><span class="o">:</span> <span class="n">WebAssemblyValueType</span>
</span></span><span class="line"><span class="cl">      <span class="n">Body</span><span class="o">:</span> <span class="n">WebAssemblyInstruction</span> <span class="kt">list</span> <span class="o">}</span>
</span></span></code></pre></div><p>Functions in WebAssembly are always organized in a <a href="https://webassembly.github.io/spec/core/syntax/modules.html">module</a>. Our code will only ever have one function so we can make this a 1-1 mapping:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">WebAssemblyModule</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Function</span><span class="o">:</span> <span class="n">WebAssemblyFunction</span> <span class="o">}</span>
</span></span></code></pre></div><p>We can now convert a parsed equation to its corresponding WebAssembly module:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">expressionToWebAssemblyInstruction</span> <span class="o">(</span><span class="n">expression</span><span class="o">:</span> <span class="n">Expression</span><span class="o">):</span> <span class="n">WebAssemblyInstruction</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">expression</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperandExpression</span><span class="o">(</span><span class="n">Integer</span> <span class="n">i</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">I32Const</span> <span class="n">i</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Add</span> <span class="o">-&gt;</span> <span class="n">I32Add</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Sub</span> <span class="o">-&gt;</span> <span class="n">I32Sub</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Mul</span> <span class="o">-&gt;</span> <span class="n">I32Mul</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">OperatorExpression</span> <span class="n">Div</span> <span class="o">-&gt;</span> <span class="n">I32Div</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationToWebAssemblyCode</span> <span class="o">(</span><span class="n">Equation</span> <span class="n">expressions</span><span class="o">):</span> <span class="n">WebAssemblyInstruction</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">List</span><span class="p">.</span><span class="n">map</span> <span class="n">expressionToWebAssemblyInstruction</span> <span class="n">expressions</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationToWebAssemblyModule</span> <span class="o">(</span><span class="n">equation</span><span class="o">:</span> <span class="n">Equation</span><span class="o">):</span> <span class="n">WebAssemblyModule</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Function</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">          <span class="o">{</span> <span class="n">Name</span> <span class="o">=</span> <span class="s">&#34;evaluate&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="n">Result</span> <span class="o">=</span> <span class="n">I32</span>
</span></span><span class="line"><span class="cl">            <span class="n">Body</span> <span class="o">=</span> <span class="n">equationToWebAssemblyCode</span> <span class="n">equation</span> <span class="o">}</span> <span class="o">}</span>
</span></span></code></pre></div><p>In a moment, we&rsquo;ll write code to convert a <code>WebAssemblyModule</code> to WebAssembly text format (WAT) and binary format (WASM). Let&rsquo;s start with defining some types for the WebAssembly output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">WebAssemblyText</span> <span class="o">=</span> <span class="n">WebAssemblyText</span> <span class="k">of</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">WebAssemblyBinary</span> <span class="o">=</span> <span class="n">WebAssemblyBinary</span> <span class="k">of</span> <span class="n">int</span> <span class="kt">list</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">WebAssembly</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Text</span><span class="o">:</span> <span class="n">WebAssemblyText</span>
</span></span><span class="line"><span class="cl">      <span class="n">Binary</span><span class="o">:</span> <span class="n">WebAssemblyBinary</span> <span class="o">}</span>
</span></span></code></pre></div><p>We can now define the pipeline to compile a RPN equation to WebAssembly:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationToWebAssembly</span> <span class="o">(</span><span class="n">equation</span><span class="o">:</span> <span class="n">Equation</span><span class="o">):</span> <span class="n">WebAssembly</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">webAssemblyModule</span> <span class="o">=</span> <span class="n">equationToWebAssemblyModule</span> <span class="n">equation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Text</span> <span class="o">=</span> <span class="nn">Text</span><span class="p">.</span><span class="n">outputModule</span> <span class="n">webAssemblyModule</span>
</span></span><span class="line"><span class="cl">      <span class="n">Binary</span> <span class="o">=</span> <span class="nn">Binary</span><span class="p">.</span><span class="n">outputModule</span> <span class="n">webAssemblyModule</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">convert</span> <span class="o">(</span><span class="n">str</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">WebAssembly</span><span class="o">,</span> <span class="n">EquationError</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parse</span> <span class="n">str</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Result</span><span class="p">.</span><span class="n">map</span> <span class="n">equationToWebAssembly</span>
</span></span></code></pre></div><p>This code will not compile, as we haven&rsquo;t yet defined the functions to convert the module to text and binary format. Let&rsquo;s fix this.</p>
<h3 id="text-format">Text format</h3>
<p>While the WebAssembly <a href="https://webassembly.github.io/spec/core/text/index.html">text format spec</a> is great, Mozilla&rsquo;s <a href="https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format">Understanding WebAssembly text format</a> page was invaluable when trying to understand what the text format looks like in practice. In essence, a WebAssembly module is an <a href="https://en.wikipedia.org/wiki/S-expression">s-expression</a>, which is a recursive format designed to represent trees.</p>
<p>Here&rsquo;s the WAT text we&rsquo;d like to generate for the RPN equation: <code>1 2 +</code>:</p>
<pre tabindex="0"><code class="language-webassembly" data-lang="webassembly">(module
  (func (export &#34;evaluate&#34;) (result i32)
    i32.const 1
    i32.const 2
    i32.add))
</code></pre><p>There is not much to the WAT output we want to generate. It defines a module with one function. That function takes no parameters, has three instructions and returns an <code>i32</code> value. Finally, the function is exported with the name &ldquo;evaluate,&rdquo; which will allow us to call it from JavaScript later.</p>
<p>The actual code to convert our WebAssembly module to its text format representation is fairly straightforward:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputValueType</span> <span class="o">(</span><span class="n">valueType</span><span class="o">:</span> <span class="n">WebAssemblyValueType</span><span class="o">):</span> <span class="kt">string</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">valueType</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32</span> <span class="o">-&gt;</span> <span class="s">&#34;i32&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputResult</span> <span class="o">(</span><span class="n">resultType</span><span class="o">:</span> <span class="n">WebAssemblyValueType</span><span class="o">):</span> <span class="kt">string</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">sprintf</span> <span class="s">&#34;(result %s)&#34;</span> <span class="o">(</span><span class="n">outputValueType</span> <span class="n">resultType</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputInstruction</span> <span class="o">(</span><span class="n">instruction</span><span class="o">:</span> <span class="n">WebAssemblyInstruction</span><span class="o">):</span> <span class="kt">string</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">instruction</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Const</span> <span class="n">i</span> <span class="o">-&gt;</span> <span class="n">sprintf</span> <span class="s">&#34;i32.const %i&#34;</span> <span class="n">i</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Add</span> <span class="o">-&gt;</span> <span class="s">&#34;i32.add&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Sub</span> <span class="o">-&gt;</span> <span class="s">&#34;i32.sub&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Mul</span> <span class="o">-&gt;</span> <span class="s">&#34;i32.mul&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Div</span> <span class="o">-&gt;</span> <span class="s">&#34;i32.div_32&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputBody</span> <span class="o">(</span><span class="n">instructions</span><span class="o">:</span> <span class="n">WebAssemblyInstruction</span> <span class="kt">list</span><span class="o">):</span> <span class="kt">string</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">instructions</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">map</span> <span class="n">outputInstruction</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">String</span><span class="p">.</span><span class="n">concat</span> <span class="s">&#34; &#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputExport</span> <span class="o">(</span><span class="n">name</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="kt">string</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">sprintf</span> <span class="s">&#34;(export </span><span class="se">\&#34;</span><span class="s">%s</span><span class="se">\&#34;</span><span class="s">)&#34;</span> <span class="n">name</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputFunction</span> <span class="o">(</span><span class="k">function&#39;</span><span class="o">:</span> <span class="n">WebAssemblyFunction</span><span class="o">):</span> <span class="kt">string</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">export</span> <span class="o">=</span> <span class="n">outputExport</span> <span class="k">function&#39;</span><span class="o">.</span><span class="n">Name</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="n">outputResult</span> <span class="k">function&#39;</span><span class="o">.</span><span class="n">Result</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">body</span> <span class="o">=</span> <span class="n">outputBody</span> <span class="k">function&#39;</span><span class="o">.</span><span class="n">Body</span>
</span></span><span class="line"><span class="cl">    <span class="n">sprintf</span> <span class="s">&#34;(func %s %s %s)&#34;</span> <span class="n">export</span> <span class="n">result</span> <span class="n">body</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputModule</span> <span class="o">(</span><span class="k">module&#39;</span><span class="o">:</span> <span class="n">WebAssemblyModule</span><span class="o">):</span> <span class="n">WebAssemblyText</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">outputFunction</span> <span class="k">module&#39;</span><span class="o">.</span><span class="n">Function</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">sprintf</span> <span class="s">&#34;(module %s)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">WebAssemblyText</span>
</span></span></code></pre></div><p>Tiny note: this code doesn&rsquo;t output the code in an indented format, but it is semantically equivalent.</p>
<h3 id="binary-format">Binary format</h3>
<p>The <a href="https://webassembly.github.io/spec/core/binary/index.html">binary format</a> is a bit more involved than the text format. Once again, the basis is formed by a <a href="https://webassembly.github.io/spec/core/binary/modules.html#binary-module">module</a>, which is represented as a list of bytes.</p>
<p>The first two parts of a module are fixed, and consist of a magic header and a version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputMagicHeader</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span> <span class="o">[</span> <span class="n">0x00</span><span class="o">;</span> <span class="n">0x61</span><span class="o">;</span> <span class="n">0x73</span><span class="o">;</span> <span class="n">0x6d</span> <span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputVersion</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span> <span class="o">[</span> <span class="n">0x01</span><span class="o">;</span> <span class="n">0x00</span><span class="o">;</span> <span class="n">0x00</span><span class="o">;</span> <span class="n">0x00</span> <span class="o">]</span>
</span></span></code></pre></div><p>Note that we defined the values in hexadecimal notation to have them correspond directly to how they are defined in the spec. We could have defined them as bytes, but for the sake of code brevity we&rsquo;ll use regular ints.</p>
<p>Let&rsquo;s move on to the contents of a module, which is comprised of zero or more <a href="https://webassembly.github.io/spec/core/binary/modules.html#sections">sections</a>. Each section consists of:</p>
<ul>
<li>A one-byte section ID.</li>
<li>The <code>u32</code> size of the contents, in bytes.</li>
<li>The actual contents, which depends on the type of section.</li>
</ul>
<p>While there are (currently) <a href="https://webassembly.github.io/spec/core/binary/modules.html#sections">12 different types of sections</a>, we only need four of them:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Section</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Type</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Function</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Export</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Code</span>
</span></span></code></pre></div><p>The first part of a section, its ID, can be output as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputSectionIndex</span> <span class="o">(</span><span class="n">section</span><span class="o">:</span> <span class="n">Section</span><span class="o">):</span> <span class="n">int</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">section</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Type</span> <span class="o">-&gt;</span> <span class="n">0x01</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Function</span> <span class="o">-&gt;</span> <span class="n">0x03</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Export</span> <span class="o">-&gt;</span> <span class="n">0x07</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Code</span> <span class="o">-&gt;</span> <span class="n">0x0a</span>
</span></span></code></pre></div><p>The second and third part deal with the section&rsquo;s contents. The second part is defined as the <code>u32</code> size of the contents. If we examine the <a href="https://webassembly.github.io/spec/core/binary/values.html#binary-int"><code>u32</code> spec</a>, we can see that <code>u32</code> values must be encoded using the <a href="https://en.wikipedia.org/wiki/LEB128">LEB128 encoding</a>. LEB128 encoding is a variable-length encoding, which means that different numbers can be encoded using a different number of bytes.</p>
<p>The LEB128 format has two different algorithms: one for unsigned integers and one for signed integers. Let&rsquo;s start with the unsigned integers first:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputUnsignedLEB128</span> <span class="o">(</span><span class="n">i</span><span class="o">:</span> <span class="n">int</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">bitEightMask</span> <span class="o">=</span> <span class="n">0b1000_0000</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">bitsOneToSevenMask</span> <span class="o">=</span> <span class="n">0b0111_1111</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">mutable</span> <span class="n">more</span> <span class="o">=</span> <span class="k">true</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">mutable</span> <span class="n">value</span> <span class="o">=</span> <span class="n">i</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">mutable</span> <span class="n">bytes</span> <span class="o">=</span> <span class="n">ResizeArray</span><span class="o">&lt;</span><span class="n">int</span><span class="o">&gt;</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">more</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">mutable</span> <span class="kt">byte</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&amp;&amp;&amp;</span> <span class="n">bitsOneToSevenMask</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span> <span class="o">&lt;-</span> <span class="n">value</span> <span class="o">&gt;&gt;&gt;</span> <span class="n">7</span>
</span></span><span class="line"><span class="cl">        <span class="n">more</span> <span class="o">&lt;-</span> <span class="n">value</span> <span class="o">&lt;&gt;</span> <span class="n">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">value</span> <span class="o">&lt;&gt;</span> <span class="n">0</span> <span class="k">then</span> <span class="kt">byte</span> <span class="o">&lt;-</span> <span class="kt">byte</span> <span class="o">|||</span> <span class="n">bitEightMask</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">bytes</span><span class="o">.</span><span class="n">Add</span><span class="o">(</span><span class="kt">byte</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nn">List</span><span class="p">.</span><span class="n">ofSeq</span> <span class="n">bytes</span>
</span></span></code></pre></div><p>Note that we used mutation here. While immutability is great, it is good to remember that not all F# code <em>has</em> to be immutable. Here, we only use mutation <em>inside</em> our function; it is an implementation detail. The actual returned value is a regular, immutable list.</p>
<p>The signed output is similar, but slightly different:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputSignedLEB128</span> <span class="o">(</span><span class="n">i</span><span class="o">:</span> <span class="n">int</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">bitEightMask</span> <span class="o">=</span> <span class="n">0b1000_0000</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">bitSevenMask</span> <span class="o">=</span> <span class="n">0b0100_0000</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">bitsOneToSevenMask</span> <span class="o">=</span> <span class="n">0b0111_1111</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">mutable</span> <span class="n">more</span> <span class="o">=</span> <span class="k">true</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">mutable</span> <span class="n">value</span> <span class="o">=</span> <span class="n">i</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">mutable</span> <span class="n">bytes</span> <span class="o">=</span> <span class="n">ResizeArray</span><span class="o">&lt;</span><span class="n">int</span><span class="o">&gt;</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">more</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">mutable</span> <span class="kt">byte</span> <span class="o">=</span> <span class="n">value</span> <span class="o">&amp;&amp;&amp;</span> <span class="n">bitsOneToSevenMask</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span> <span class="o">&lt;-</span> <span class="n">value</span> <span class="o">&gt;&gt;&gt;</span> <span class="n">7</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">value</span> <span class="o">=</span> <span class="n">0</span> <span class="o">&amp;&amp;</span> <span class="o">(</span><span class="kt">byte</span> <span class="o">&amp;&amp;&amp;</span> <span class="n">bitSevenMask</span><span class="o">)</span> <span class="o">=</span> <span class="n">0</span> <span class="k">then</span> <span class="n">more</span> <span class="o">&lt;-</span> <span class="k">false</span>
</span></span><span class="line"><span class="cl">        <span class="k">elif</span> <span class="n">value</span> <span class="o">=</span> <span class="o">-</span><span class="n">1</span> <span class="o">&amp;&amp;</span> <span class="o">(</span><span class="kt">byte</span> <span class="o">&amp;&amp;&amp;</span> <span class="n">bitSevenMask</span><span class="o">)</span> <span class="o">&gt;</span> <span class="n">0</span> <span class="k">then</span> <span class="n">more</span> <span class="o">&lt;-</span> <span class="k">false</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span> <span class="kt">byte</span> <span class="o">&lt;-</span> <span class="kt">byte</span> <span class="o">|||</span> <span class="n">bitEightMask</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">bytes</span><span class="o">.</span><span class="n">Add</span><span class="o">(</span><span class="kt">byte</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nn">List</span><span class="p">.</span><span class="n">ofSeq</span> <span class="n">bytes</span>
</span></span></code></pre></div><p>Outputting an integer means choosing between the two LEB128 algorithms:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputInteger</span> <span class="o">(</span><span class="n">i</span><span class="o">:</span> <span class="n">int</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">0</span> <span class="k">then</span> <span class="n">outputSignedLEB128</span> <span class="n">i</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span> <span class="n">outputUnsignedLEB128</span> <span class="n">i</span>
</span></span></code></pre></div><p>As you might recall, the reason why we needed to output an integer was to output the length of the section&rsquo;s code. In WebAssembly, bytes prefixed by their length are referred to as a vector:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputVector</span> <span class="o">(</span><span class="n">bytes</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">length</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="n">bytes</span>
</span></span><span class="line"><span class="cl">        <span class="o">|&gt;</span> <span class="nn">List</span><span class="p">.</span><span class="n">length</span>
</span></span><span class="line"><span class="cl">        <span class="o">|&gt;</span> <span class="n">outputInteger</span>
</span></span><span class="line"><span class="cl">    <span class="n">length</span> <span class="o">@</span> <span class="n">bytes</span>
</span></span></code></pre></div><p>Outputting a section is then a simple combination of outputting its section index and its vector:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputSection</span> <span class="o">(</span><span class="n">section</span><span class="o">:</span> <span class="n">Section</span><span class="o">)</span> <span class="o">(</span><span class="n">bytes</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">outputSectionIndex</span> <span class="n">section</span> <span class="o">@</span> <span class="n">outputVector</span> <span class="n">bytes</span>
</span></span></code></pre></div><p>Now that we have the basics defined, let&rsquo;s move on to the output of the individual sections.</p>
<h4 id="type-section">Type section</h4>
<p>The <a href="https://webassembly.github.io/spec/core/binary/modules.html#binary-typesec">type section</a> encodes the function types of the functions defined in the module (of which we only have one). A function type is defined as the vector of a vector for the parameter types and a vector for the result (return) types:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputValueType</span> <span class="o">(</span><span class="n">valueType</span><span class="o">:</span> <span class="n">WebAssemblyValueType</span><span class="o">):</span> <span class="n">int</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">valueType</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32</span> <span class="o">-&gt;</span> <span class="n">0x7f</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputResult</span> <span class="o">(</span><span class="n">resultType</span><span class="o">:</span> <span class="n">WebAssemblyValueType</span><span class="o">):</span> <span class="n">int</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">outputValueType</span> <span class="n">resultType</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputFunctionTypes</span> <span class="o">(</span><span class="k">function&#39;</span><span class="o">:</span> <span class="n">WebAssemblyFunction</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">parametersCount</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x00</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">resultsCount</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x01</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">resultType</span> <span class="o">=</span> <span class="n">outputResult</span> <span class="k">function&#39;</span><span class="o">.</span><span class="n">Result</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">functionType</span> <span class="o">=</span> <span class="n">0x60</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">functionType</span> <span class="o">::</span> <span class="n">parametersCount</span> <span class="o">@</span> <span class="n">resultsCount</span> <span class="o">@</span> <span class="o">[</span> <span class="n">resultType</span> <span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputTypeSection</span> <span class="o">(</span><span class="k">function&#39;</span><span class="o">:</span> <span class="n">WebAssemblyFunction</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">functionCount</span> <span class="o">=</span> <span class="n">outputUnsignedLEB128</span> <span class="n">0x01</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">functionTypes</span> <span class="o">=</span> <span class="n">outputFunctionTypes</span> <span class="k">function&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">functionCount</span> <span class="o">@</span> <span class="n">functionTypes</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">outputSection</span> <span class="nn">Section</span><span class="p">.</span><span class="n">Type</span>
</span></span></code></pre></div><h4 id="function-section">Function section</h4>
<p>The function section links a function&rsquo;s index to the function type. We have only one function, and thus only one function type, so we can hardcode the number of functions and the function index:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputFunctionSection</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">functionsCount</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x01</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">firstFunctionSignatureIndex</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x00</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">functionsCount</span> <span class="o">@</span> <span class="n">firstFunctionSignatureIndex</span> <span class="o">|&gt;</span> <span class="n">outputSection</span> <span class="nn">Section</span><span class="p">.</span><span class="n">Function</span>
</span></span></code></pre></div><h4 id="export-section">Export section</h4>
<p>In the export section, everything is listed that should be exposed to the &ldquo;outside world.&rdquo; When running WebAssembly in the browser, this means the exported values can be accessed from JavaScript. As we want to call our RPN solving function from JavaScript, we have to export our function.</p>
<p>As we only have one type we want to export (our function), we can use the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">ExportType</span> <span class="o">=</span> <span class="n">FunctionExport</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputExportType</span> <span class="o">(</span><span class="n">exportType</span><span class="o">:</span> <span class="n">ExportType</span><span class="o">):</span> <span class="n">int</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">exportType</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">FunctionExport</span> <span class="o">-&gt;</span> <span class="n">0x00</span>
</span></span></code></pre></div><p>Next, we&rsquo;ll define a function to output a string, which we&rsquo;ll use in a moment to define the exported function&rsquo;s name:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputString</span> <span class="o">(</span><span class="n">str</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">str</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">toList</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">outputVector</span>
</span></span></code></pre></div><p>Finally, we can glue these things together:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputExportSection</span> <span class="o">(</span><span class="k">function&#39;</span><span class="o">:</span> <span class="n">WebAssemblyFunction</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">exportsCount</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x01</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">exportName</span> <span class="o">=</span> <span class="n">outputString</span> <span class="k">function&#39;</span><span class="o">.</span><span class="n">Name</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">exportType</span> <span class="o">=</span> <span class="n">outputExportType</span> <span class="n">FunctionExport</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">exportFunctionIndex</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x00</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">exportsCount</span> <span class="o">@</span> <span class="n">exportName</span> <span class="o">@</span> <span class="o">[</span> <span class="n">exportType</span> <span class="o">]</span> <span class="o">@</span> <span class="n">exportFunctionIndex</span> <span class="o">|&gt;</span> <span class="n">outputSection</span> <span class="n">Export</span>
</span></span></code></pre></div><h4 id="code-section">Code section</h4>
<p>The final section is the code section, which contains (as you might have guessed) the code that a function will execute.</p>
<p>First, we&rsquo;ll add a mapping from a WebAssembly instruction to its bytes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputInstruction</span> <span class="o">(</span><span class="n">instruction</span><span class="o">:</span> <span class="n">WebAssemblyInstruction</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">instruction</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Const</span> <span class="n">i</span> <span class="o">-&gt;</span> <span class="n">0x41</span><span class="o">:</span> <span class="n">outputInteger</span> <span class="n">i</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Add</span> <span class="o">-&gt;</span> <span class="o">[</span> <span class="n">0x6a</span> <span class="o">]</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Sub</span> <span class="o">-&gt;</span> <span class="o">[</span> <span class="n">0x6b</span> <span class="o">]</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Mul</span> <span class="o">-&gt;</span> <span class="o">[</span> <span class="n">0x6c</span> <span class="o">]</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">I32Div</span> <span class="o">-&gt;</span> <span class="o">[</span> <span class="n">0x6e</span> <span class="o">]</span>
</span></span></code></pre></div><p>Next, the body is defined as number of local declarations (of which we have none), the actual instructions, and finally a special marker for the end of the body:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputBody</span> <span class="o">(</span><span class="n">instructions</span><span class="o">:</span> <span class="n">WebAssemblyInstruction</span> <span class="kt">list</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">localDeclarationsCount</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x00</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">instructions</span> <span class="o">=</span> <span class="nn">List</span><span class="p">.</span><span class="n">collect</span> <span class="n">outputInstruction</span> <span class="n">instructions</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">bodyEnd</span> <span class="o">=</span> <span class="n">0x0b</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">localDeclarationsCount</span> <span class="o">@</span> <span class="n">instructions</span> <span class="o">@</span> <span class="o">[</span> <span class="n">bodyEnd</span> <span class="o">]</span> <span class="o">|&gt;</span> <span class="n">outputVector</span>
</span></span></code></pre></div><p>The final code to output the code section is then simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputCodeSection</span> <span class="o">(</span><span class="k">function&#39;</span><span class="o">:</span> <span class="n">WebAssemblyFunction</span><span class="o">):</span> <span class="n">int</span> <span class="kt">list</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">functionCount</span> <span class="o">=</span> <span class="n">outputInteger</span> <span class="n">0x01</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">body</span> <span class="o">=</span> <span class="n">outputBody</span> <span class="k">function&#39;</span><span class="o">.</span><span class="n">Body</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">functionCount</span> <span class="o">@</span> <span class="n">body</span> <span class="o">|&gt;</span> <span class="n">outputSection</span> <span class="n">Code</span>
</span></span></code></pre></div><h4 id="output-module">Output module</h4>
<p>Outputting a module is now a case of appending the outputs of the different sections:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">outputModule</span> <span class="o">(</span><span class="k">module&#39;</span><span class="o">:</span> <span class="n">WebAssemblyModule</span><span class="o">):</span> <span class="n">WebAssemblyBinary</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">typeSection</span> <span class="o">=</span> <span class="n">outputTypeSection</span> <span class="k">module&#39;</span><span class="o">.</span><span class="n">Function</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">functionSection</span> <span class="o">=</span> <span class="n">outputFunctionSection</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">exportSection</span> <span class="o">=</span> <span class="n">outputExportSection</span> <span class="k">module&#39;</span><span class="o">.</span><span class="n">Function</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">codeSection</span> <span class="o">=</span> <span class="n">outputCodeSection</span> <span class="k">module&#39;</span><span class="o">.</span><span class="n">Function</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">outputMagicHeader</span> <span class="o">@</span> <span class="n">outputVersion</span> <span class="o">@</span> <span class="n">typeSection</span> <span class="o">@</span> <span class="n">functionSection</span> <span class="o">@</span> <span class="n">exportSection</span> <span class="o">@</span> <span class="n">codeSection</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">WebAssemblyBinary</span>
</span></span></code></pre></div><p>And we&rsquo;re done! We can now compiling any RPN equation to its WebAssembly format. Let&rsquo;s start building the website now.</p>
<h2 id="building-the-website">Building the website</h2>
<p>To build the website using only F#, we can use the fabulous (pun intended) <a href="https://fable.io/">Fable</a> compiler. Fable is a compiler that can compile F# code to JavaScript code. Precisely what we need!</p>
<p>Our website will use a particular flavor of Fable called <a href="https://elmish.github.io/elmish/">Elmish</a>. With Elmish, one can build applications using the <a href="https://guide.elm-lang.org/architecture/">Model-View-Update architecture</a> that was popularized by <a href="https://guide.elm-lang.org/">Elm</a>.</p>
<p>Our first step in building our Elmish application is to define the application&rsquo;s model. In an Elmish application, the model is used as input to render the website. As such, the model should contain everything that we want to display on our website, which for our application looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">EvaluationResult</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Result</span><span class="o">:</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">      <span class="n">Wasm</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span>
</span></span><span class="line"><span class="cl">      <span class="n">Wat</span><span class="o">:</span> <span class="kt">string</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">EvaluationError</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">WebAssemblyException</span> <span class="k">of</span> <span class="kt">exn</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EmptyEquation</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">InvalidEquation</span> <span class="k">of</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">UnbalancedEquation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Model</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Evaluation</span><span class="o">:</span> <span class="n">Result</span><span class="o">&lt;</span><span class="n">EvaluationResult</span><span class="o">,</span> <span class="n">EvaluationError</span><span class="o">&gt;</span> <span class="n">option</span>
</span></span><span class="line"><span class="cl">      <span class="n">Equation</span><span class="o">:</span> <span class="kt">string</span> <span class="o">}</span>
</span></span></code></pre></div><p>The types are relative simple. There is an evaluation result that contains the result of the evaluation, as well as the generated WASM (binary format) and WAT (text format). The evaluation result itself is an optional part of the model (there is no evaluation initially). The other part of the model is the equation to solve.</p>
<p>For the first render of the website, Elmish requires us to provide a function that returns the initial model:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">init</span><span class="bp">()</span><span class="o">:</span> <span class="n">Model</span> <span class="o">*</span> <span class="n">Cmd</span><span class="o">&lt;</span><span class="k">&#39;</span><span class="n">a</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">{</span> <span class="n">Evaluation</span> <span class="o">=</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">      <span class="n">Equation</span> <span class="o">=</span> <span class="s">&#34;&#34;</span> <span class="o">},</span> <span class="nn">Cmd</span><span class="p">.</span><span class="n">none</span>
</span></span></code></pre></div><p>Of course, we need to be able to update the model if we are to have any interactivity on our website. In the Elmish model, updating the model means sending a message. These messages are defined as a regular discriminated union:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Msg</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">UpdateEquation</span> <span class="k">of</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EvaluateEquation</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EquationEvaluatedSuccessfully</span> <span class="k">of</span> <span class="n">Evaluation</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EquationEvaluatedWithError</span> <span class="k">of</span> <span class="n">EvaluationError</span>
</span></span></code></pre></div><p>The next step is to define a function that takes a message and a model, and then returns a model and a command (we&rsquo;ll get to what a command is):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">update</span> <span class="o">(</span><span class="n">msg</span><span class="o">:</span> <span class="n">Msg</span><span class="o">)</span> <span class="o">(</span><span class="n">model</span><span class="o">:</span> <span class="n">Model</span><span class="o">):</span> <span class="n">Model</span> <span class="o">*</span> <span class="n">Cmd</span><span class="o">&lt;</span><span class="k">&#39;</span><span class="n">a</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">msg</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">UpdateEquation</span> <span class="n">newEquation</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">{</span> <span class="n">model</span> <span class="k">with</span> <span class="n">Equation</span> <span class="o">=</span> <span class="n">newEquation</span> <span class="o">},</span> <span class="nn">Cmd</span><span class="p">.</span><span class="n">none</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EvaluateEquation</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="n">evaluate</span> <span class="n">model</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EquationEvaluatedSuccessfully</span> <span class="n">evaluation</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">{</span> <span class="n">model</span> <span class="k">with</span> <span class="n">Evaluation</span> <span class="o">=</span> <span class="n">Some</span><span class="o">(</span><span class="n">Ok</span> <span class="n">evaluation</span><span class="o">)</span> <span class="o">},</span> <span class="nn">Cmd</span><span class="p">.</span><span class="n">none</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">EquationEvaluatedWithError</span> <span class="n">error</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="o">{</span> <span class="n">model</span> <span class="k">with</span> <span class="n">Evaluation</span> <span class="o">=</span> <span class="n">Some</span><span class="o">(</span><span class="n">Error</span> <span class="n">error</span><span class="o">)</span> <span class="o">},</span> <span class="nn">Cmd</span><span class="p">.</span><span class="n">none</span>
</span></span></code></pre></div><p>The <code>UpdateEquation</code>, <code>EquationEvaluatedSuccessfully</code> and <code>EquationEvaluatedWithError</code> paths are relatively straightforward. They take a message with a payload and then update the model with that payload and return the model. These paths also return <code>Cmd.none</code> to indicate that there is no new message that needs to be processed.</p>
<p>The interesting path is the one where the user has requested that the equation be evaluated. The <code>evaluate</code> function calls the <code>convert</code> method, which takes an equation as input and returns the compiled WebAssembly:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">evaluate</span> <span class="o">(</span><span class="n">model</span><span class="o">:</span> <span class="n">Model</span><span class="o">):</span> <span class="n">Model</span> <span class="o">*</span> <span class="n">Cmd</span><span class="o">&lt;</span><span class="k">&#39;</span><span class="n">a</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">convert</span> <span class="n">model</span><span class="o">.</span><span class="n">Equation</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Ok</span> <span class="n">webAssembly</span> <span class="o">-&gt;</span> <span class="n">equationEvaluatedSuccessfully</span> <span class="n">model</span> <span class="n">webAssembly</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Error</span> <span class="n">error</span> <span class="o">-&gt;</span> <span class="n">equationEvaluatedWithError</span> <span class="n">model</span> <span class="n">error</span>
</span></span></code></pre></div><p>In the error case, we map the <code>EquationError</code> to an <code>EvaluationError</code> and then return the (unchanged) model and a new message indicating that the model should be updated with the error:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationEvaluatedWithError</span> <span class="o">(</span><span class="n">model</span><span class="o">:</span> <span class="n">Model</span><span class="o">)</span> <span class="o">(</span><span class="n">error</span><span class="o">:</span> <span class="n">EvaluationError</span><span class="o">):</span> <span class="n">Model</span> <span class="o">*</span> <span class="n">Cmd</span><span class="o">&lt;</span><span class="k">&#39;</span><span class="n">a</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">evaluationError</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="k">match</span> <span class="n">error</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="n">Empty</span> <span class="o">-&gt;</span> <span class="n">EmptyEquation</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="n">Invalid</span> <span class="n">token</span> <span class="o">-&gt;</span> <span class="n">InvalidEquation</span> <span class="n">token</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="n">Unbalanced</span> <span class="o">-&gt;</span> <span class="n">UnbalancedEquation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">model</span><span class="o">,</span> <span class="nn">Cmd</span><span class="p">.</span><span class="n">ofMsg</span> <span class="o">(</span><span class="n">EquationEvaluatedWithError</span> <span class="n">evaluationError</span><span class="o">)</span>
</span></span></code></pre></div><p>This code shows that instead of just updating the model and returning <code>Cmd.none</code>, one could also choose to send a new command with a new message, deferring the actual updating of the model to the message handler.</p>
<p>For the success case, where an equation was successfully compiled to WebAssembly, we want to execute the WebAssembly in the browser. This means interacting with browser API&rsquo;s. Many API&rsquo;s have type-safe wrappers in Fable, but with the WebAssembly stuff being fairly new, we have to add those wrappers ourselves. Luckily, this is extremely easy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">AutoOpen</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">module</span> <span class="nn">WebAssembly</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">type</span> <span class="nc">Instance</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="o">{</span> <span class="n">exports</span><span class="o">:</span> <span class="kt">obj</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">type</span> <span class="nc">ResultObject</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="o">{</span> <span class="n">instance</span><span class="o">:</span> <span class="n">Instance</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">[&lt;</span><span class="n">Emit</span><span class="o">(</span><span class="s">&#34;WebAssembly.instantiate($0)&#34;</span><span class="o">)&gt;]</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">instantiate</span> <span class="o">(</span><span class="n">bufferSource</span><span class="o">:</span> <span class="n">ArrayBuffer</span><span class="o">):</span> <span class="nn">JS</span><span class="p">.</span><span class="n">Promise</span><span class="o">&lt;</span><span class="n">ResultObject</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">jsNative</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">AutoOpen</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">module</span> <span class="nn">Uint8Array</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">[&lt;</span><span class="n">Emit</span><span class="o">(</span><span class="s">&#34;Uint8Array.from($0)&#34;</span><span class="o">)&gt;]</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">from</span> <span class="o">(</span><span class="n">bytes</span><span class="o">:</span> <span class="n">int</span> <span class="kt">list</span><span class="o">):</span> <span class="n">ArrayBuffer</span> <span class="o">=</span> <span class="n">jsNative</span>
</span></span></code></pre></div><p>As you can see, we define the browser API&rsquo;s as regular functions, but with a special <code>Emit</code> attribute that Fable will use when converting the F# to JavaScript.</p>
<p>We now have all the infrastructure we need to execute our compiled WebAssembly:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationEvaluatedSuccessfully</span> <span class="n">model</span> <span class="n">webAssembly</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="o">(</span><span class="n">WebAssemblyText</span><span class="o">(</span><span class="n">wat</span><span class="o">))</span> <span class="o">=</span> <span class="n">webAssembly</span><span class="o">.</span><span class="n">Text</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="o">(</span><span class="n">WebAssemblyBinary</span><span class="o">(</span><span class="n">wasm</span><span class="o">))</span> <span class="o">=</span> <span class="n">webAssembly</span><span class="o">.</span><span class="n">Binary</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">onSuccess</span> <span class="n">webAssemblyInBrowser</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="n">EquationEvaluatedSuccessfully</span>
</span></span><span class="line"><span class="cl">            <span class="o">({</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">webAssemblyInBrowser</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">exports</span><span class="o">?</span><span class="n">evaluate</span> <span class="bp">()</span>
</span></span><span class="line"><span class="cl">               <span class="n">Wasm</span> <span class="o">=</span> <span class="n">wasm</span>
</span></span><span class="line"><span class="cl">               <span class="n">Wat</span> <span class="o">=</span> <span class="n">wat</span> <span class="o">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">onError</span> <span class="n">ex</span> <span class="o">=</span> <span class="n">EquationEvaluatedWithError</span><span class="o">(</span><span class="n">WebAssemblyException</span> <span class="n">ex</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">cmd</span> <span class="o">=</span> <span class="nn">Cmd</span><span class="p">.</span><span class="nn">OfPromise</span><span class="p">.</span><span class="n">either</span> <span class="nn">WebAssembly</span><span class="p">.</span><span class="n">instantiate</span> <span class="o">(</span><span class="nn">Uint8Array</span><span class="p">.</span><span class="n">from</span> <span class="n">wasm</span><span class="o">)</span> <span class="n">onSuccess</span> <span class="n">onError</span>
</span></span><span class="line"><span class="cl">    <span class="n">model</span><span class="o">,</span> <span class="n">cmd</span>
</span></span></code></pre></div><p>Running our WebAssembly function is done through the interop code we just wrote: <code>webAssemblyInBrowser.instance.exports?evaluate()</code>. The <code>evaluate()</code> call is actually our compiled and exported WebAssembly function.</p>
<p>The last part of this function is instructing Fable to execute a function that returns a JavaScript promise (<code>WebAssembly.instantiate</code>), and call one of the two passed callbacks when the promise completed successfully or with an error.</p>
<p>The final step in building our website is to write functions to render our UI. With Elmish, rendering HTML is not done in a regular templating language, but using plain F# functions. Consider the following function to output the evaluation output contents:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationOutputContent</span> <span class="o">(</span><span class="n">resultClass</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">(</span><span class="n">text</span><span class="o">:</span> <span class="kt">string</span><span class="o">):</span> <span class="n">ReactElement</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">p</span> <span class="bp">[]</span>
</span></span><span class="line"><span class="cl">        <span class="o">[</span> <span class="n">mark</span>
</span></span><span class="line"><span class="cl">            <span class="o">[</span> <span class="n">Name</span> <span class="s">&#34;result&#34;</span>
</span></span><span class="line"><span class="cl">              <span class="n">Class</span> <span class="n">resultClass</span> <span class="o">]</span> <span class="o">[</span> <span class="n">str</span> <span class="n">text</span> <span class="o">]</span> <span class="o">]</span>
</span></span></code></pre></div><p>Calling <code>equationOutputContent &quot;tertiary&quot; &quot;3&quot;</code> will render the following HTML:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;&lt;</span><span class="nt">mark</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;result&#34;</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;tertiary&#34;</span><span class="p">&gt;</span>3<span class="p">&lt;/</span><span class="nt">mark</span><span class="p">&gt;&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Did you note that the return type of the <code>equationOutputContent</code> function was of type <code>ReactElement</code>? This gives away the fact that Fable (by default) compiles to <a href="https://reactjs.org/">React</a> code, in order to actually render the website.</p>
<p>In Elmish, rendering a UI is not much more than just composing functions. We&rsquo;ll skip over the other functions, but if you&rsquo;re interested in this bit you can just <a href="https://github.com/ErikSchierboom/krakow/blob/master/src/Krakow.Website/src/View.fs">check out the source code</a>.</p>
<p>And with that we now have a website where we can solve RPN equations using WebAssembly:</p>
<p><img src="/images/posts/reverse-polish-notation-in-web-assembly-using-fable/website.png" alt="RPN solver website"></p>
<h1 id="conclusion">Conclusion</h1>
<p>Using F# to parse and solve RPN equations was almost trivial. Modelling the domain using F#&rsquo;s expressive and low-ceremony type system was an absolute joy. If you are interested in domain modeling using functional techniques, I highly recommend Scott Wlaschin&rsquo;s <a href="https://fsharpforfunandprofit.com/books/#domain-modeling-made-functional-ebook-and-paper">Domain Modeling made Functional book</a>.</p>
<p>Generating WebAssembly to solve RPN equations was not very hard. This was helped by the well-written WebAssembly specification. Building the website in F# using Fable was a first for me, but I absolutely loved it. The Elmish part especially was conceptually very appealing, with its simple, functional architecture. Defining HTML output using functions took some time to get used to, but when it did, I really liked it.</p>
<p>The source code of everything described in this blog post can be found at
<a href="https://github.com/erikschierboom/krakow">https://github.com/erikschierboom/krakow</a>. You can try out the website at <a href="https://krakow-98706.firebaseapp.com/">https://krakow-98706.firebaseapp.com/</a>.</p>
]]></content>
		</item>
		
		<item>
			<title>Continuous integration of .NET Core applications</title>
			<link>https://www.erikschierboom.com/2017/03/21/continuous-integration-of-dotnet-core-applications/</link>
			<pubDate>Tue, 21 Mar 2017 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2017/03/21/continuous-integration-of-dotnet-core-applications/</guid>
			<description>On March 7, 2017, the .NET Core SDK was released. It consists of two parts: the .NET Core runtime and the .NET CLI. The runtime allows you to run .NET Core applications, whereas the CLI is a command-line interface that allows you to develop .NET Core applications.
In this blog post, we&amp;rsquo;ll see how we can use the .NET CLI to build a small .NET Core console application. We then show how easy it is to setup a continuous integration pipeline using AppVeyor, Travis and CircleCI.</description>
			<content type="html"><![CDATA[<p>On March 7, 2017, the <a href="https://www.microsoft.com/net/download/core">.NET Core SDK</a> was released. It consists of two parts: the <a href="https://docs.microsoft.com/en-us/dotnet/articles/core/">.NET Core runtime</a> and the <a href="https://docs.microsoft.com/en-us/dotnet/articles/core/tools/">.NET CLI</a>. The runtime allows you to run .NET Core applications, whereas the CLI is a command-line interface that allows you to develop .NET Core applications.</p>
<p>In this blog post, we&rsquo;ll see how we can use the .NET CLI to build a small .NET Core console application. We then show how easy it is to setup a continuous integration pipeline using AppVeyor, Travis and CircleCI.</p>
<p>Note: we will assume that we already have an existing account for AppVeyor, Travis and CircleCI.</p>
<h2 id="installing-the-net-core-sdk">Installing the .NET Core SDK</h2>
<p>Our first step is to install the .NET Core SDK. This is surprisingly simple. Just go to the <a href="https://www.microsoft.com/net/download/core">download</a> page and follow the on-screen instructions.</p>
<p>Once the installation has completed, open a command prompt and run:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dotnet --version
</span></span></code></pre></div><p>If the installation was successful, the .NET CLI&rsquo;s version number will be displayed, which for me was:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">1.0.1
</span></span></code></pre></div><h2 id="creating-the-application">Creating the application</h2>
<p>The application we&rsquo;ll build will be a small console application. Although we could use Visual Studio (2017) to build the application, we&rsquo;ll use the .NET CLI exclusively.</p>
<p>First, we&rsquo;ll create a directory for our application and navigate to that directory:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir dotnetcore-ci
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> dotnetcore-ci
</span></span></code></pre></div><p>To quickly generate a basic console application, we can use the .NET CLI:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dotnet new console
</span></span></code></pre></div><p>This will output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Content generation time: 47.7522 ms
</span></span><span class="line"><span class="cl">The template <span class="s2">&#34;Console Application&#34;</span> created successfully.
</span></span></code></pre></div><p>Once finished, the CLI will have created two files in the current directory:</p>
<ul>
<li><code>Program.cs</code>: the C# source file for our application.</li>
<li><code>dotnetcore-ci.csproj</code>: a C# project for our application.</li>
</ul>
<p>These two files is all the .NET CLI needs to build and run our application. Before we can run our application though, we need to restore its dependencies:</p>
<pre tabindex="0"><code>dotnet restore
</code></pre><p>This command will resolve our project&rsquo;s dependencies:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Restoring packages <span class="k">for</span> /Users/erikschierboom/Programming/dotnetcore-ci/dotnetcore-ci.csproj...
</span></span><span class="line"><span class="cl">  Generating MSBuild file /Users/erikschierboom/Programming/dotnetcore-ci/obj/dotnetcore-ci.csproj.nuget.g.props.
</span></span><span class="line"><span class="cl">  Generating MSBuild file /Users/erikschierboom/Programming/dotnetcore-ci/obj/dotnetcore-ci.csproj.nuget.g.targets.
</span></span><span class="line"><span class="cl">  Writing lock file to disk. Path: /Users/erikschierboom/Programming/dotnetcore-ci/obj/project.assets.json
</span></span><span class="line"><span class="cl">  Restore completed in 841.1 ms <span class="k">for</span> /Users/erikschierboom/Programming/dotnetcore-ci/dotnetcore-ci.csproj.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  NuGet Config files used:
</span></span><span class="line"><span class="cl">      /Users/erikschierboom/.nuget/NuGet/NuGet.Config
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Feeds used:
</span></span><span class="line"><span class="cl">      https://api.nuget.org/v3/index.json
</span></span></code></pre></div><p>Having restored our project&rsquo;s dependencies, we can now build our application:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dotnet build
</span></span></code></pre></div><p>This will output some diagnostic information:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Microsoft <span class="o">(</span>R<span class="o">)</span> Build Engine version 15.1.548.43366
</span></span><span class="line"><span class="cl">Copyright <span class="o">(</span>C<span class="o">)</span> Microsoft Corporation. All rights reserved.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  dotnetcore-ci -&gt; /Users/erikschierboom/Programming/dotnetcore-ci/bin/Debug/netcoreapp1.1/dotnetcore-ci.dll
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Build succeeded.
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Warning<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Error<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Time Elapsed 00:00:02.14
</span></span></code></pre></div><p>We can see that the build was successful, so let&rsquo;s run our application using the .NET CLI:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dotnet run
</span></span></code></pre></div><p>Our application will now be run (using the .NET Core runtime) and will output a familiar message:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Hello World!
</span></span></code></pre></div><p>The output may not be that exciting, but what <em>is</em> exciting is that we scaffolded, restored, built <em>and</em> ran our application using just the .NET CLI! No IDE was involved! Additionally, we did all this on our MacBook, showing the fully cross-platform nature of the .NET CLI.</p>
<h2 id="building-on-a-continuous-integration-server">Building on a continuous integration server</h2>
<p>Now that we have our software building locally, let&rsquo;s try to setup a continuous integration pipeline. For that, we need to create a <a href="https://github.com/ErikSchierboom/dotnetcore-ci">public repository</a> on GitHub for our application. Having pushed our local files to the public repository, we are ready to add continuous integration to our application.</p>
<h3 id="appveyor">AppVeyor</h3>
<p>The first CI server we&rsquo;ll look at is <a href="https://www.appveyor.com/">AppVeyor</a>, which is a CI server that runs on Windows.</p>
<p>To configure our application, we add an <code>appveyor.yml</code> file to our root directory. Its contents are very simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">Visual Studio 2017</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">DOTNET_CLI_TELEMETRY_OPTOUT</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">DOTNET_SKIP_FIRST_TIME_EXPERIENCE</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">before_build</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">cmd</span><span class="p">:</span><span class="w"> </span><span class="l">dotnet restore</span><span class="w">
</span></span></span></code></pre></div><p>In the first line, we specify that we want to use the Visual Studio 2017 image, which is the AppVeyor image that has the .NET Core SDK pre-installed.</p>
<p>Next, we set two environment variables:</p>
<ol>
<li><code>DOTNET_CLI_TELEMETRY_OPTOUT: true</code>: don&rsquo;t send any telemetry data.</li>
<li><code>DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true</code>: this will prevent the CLI from pre-populating the packages cache.</li>
</ol>
<p>We then indicate that <code>dotnet restore</code> should be executed before the application is built. Note that we don&rsquo;t have to call <code>dotnet build</code>, as AppVeyor will automatically do that for us. You can see this when we examine the build output in AppVeyor:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Build started
</span></span><span class="line"><span class="cl">git clone -q --branch<span class="o">=</span>master https://github.com/ErikSchierboom/dotnetcore-ci.git C:<span class="se">\p</span>rojects<span class="se">\d</span>otnetcore-ci
</span></span><span class="line"><span class="cl">git checkout -qf c6a418e057f44d9604e95429ec273239ef8c01bc
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dotnet restore
</span></span><span class="line"><span class="cl">  Restoring packages <span class="k">for</span> C:<span class="se">\p</span>rojects<span class="se">\d</span>otnetcore-ci<span class="se">\d</span>otnetcore-ci.csproj...
</span></span><span class="line"><span class="cl">  Generating MSBuild file
</span></span><span class="line"><span class="cl">   ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">msbuild <span class="s2">&#34;C:\projects\dotnetcore-ci\dotnetcore-ci.csproj&#34;</span> /logger:<span class="s2">&#34;C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll&#34;</span>
</span></span><span class="line"><span class="cl">Microsoft <span class="o">(</span>R<span class="o">)</span> Build Engine version 15.1.548.43366
</span></span><span class="line"><span class="cl">Copyright <span class="o">(</span>C<span class="o">)</span> Microsoft Corporation. All rights reserved.
</span></span><span class="line"><span class="cl">Build started 3/20/2017 2:21:46 PM.
</span></span><span class="line"><span class="cl">Project <span class="s2">&#34;C:\projects\dotnetcore-ci\dotnetcore-ci.csproj&#34;</span> on node <span class="m">1</span> <span class="o">(</span>default targets<span class="o">)</span>.
</span></span><span class="line"><span class="cl">PrepareForBuild:
</span></span><span class="line"><span class="cl">  ...
</span></span><span class="line"><span class="cl">CoreCompile:
</span></span><span class="line"><span class="cl">  ...
</span></span><span class="line"><span class="cl">CopyFilesToOutputDirectory:
</span></span><span class="line"><span class="cl">  ...
</span></span><span class="line"><span class="cl">Done Building Project <span class="s2">&#34;C:\projects\dotnetcore-ci\dotnetcore-ci.csproj&#34;</span> <span class="o">(</span>default targets<span class="o">)</span>.
</span></span><span class="line"><span class="cl">Build succeeded.
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Warning<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Error<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">Time Elapsed 00:00:03.27
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Discovering tests...OK
</span></span><span class="line"><span class="cl">Build success
</span></span></code></pre></div><p>And with that, we have our .NET Core application building on AppVeyor using the .NET CLI.</p>
<h3 id="travis">Travis</h3>
<p>Our second CI server is <a href="https://travis-ci.org/">Travis</a>, which runs on Linux.</p>
<p>Just like AppVeyor, we need to add a configuration file to our root directory, this time named <code>.travis.yml</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l">csharp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">dist</span><span class="p">:</span><span class="w"> </span><span class="l">trusty</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">dotnet</span><span class="p">:</span><span class="w"> </span><span class="m">1.0.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">mono</span><span class="p">:</span><span class="w"> </span><span class="l">none</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">env</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">global</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">DOTNET_SKIP_FIRST_TIME_EXPERIENCE</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">DOTNET_CLI_TELEMETRY_OPTOUT</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">dotnet restore</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">dotnet build</span><span class="w">
</span></span></span></code></pre></div><p>This config file has a bit more going on, but nothing complicated. First, we define the language we&rsquo;ll be using, C# in our case. Next, we define the Linux distro it runs on, for which we&rsquo;ll use Ubunty trusty.</p>
<p>We then get to the .NET specific bits, in which we indicate that we want version 1.0.1 of the .NET Core SDK to be installed. We also explicitly specify that we don&rsquo;t require Mono, which would otherwise be automatically installed due to the language specified being <code>csharp</code>.</p>
<p>Once again, we specify the two .NET CLI specific environment variables.</p>
<p>Finally, we specify the commands to execute, and this time we do need both the <code>dotnet restore</code> and <code>dotnet build</code> commands.</p>
<p>The Travis output log will look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Installing .NET Core
</span></span><span class="line"><span class="cl">..
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">git clone --depth<span class="o">=</span><span class="m">50</span> --branch<span class="o">=</span>master https://github.com/ErikSchierboom/dotnetcore-ci.git
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Setting environment variables from .travis.yml
</span></span><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">DOTNET_SKIP_FIRST_TIME_EXPERIENCE</span><span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">DOTNET_CLI_TELEMETRY_OPTOUT</span><span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dotnet restore
</span></span><span class="line"><span class="cl">  Restoring packages <span class="k">for</span> C:<span class="se">\p</span>rojects<span class="se">\d</span>otnetcore-ci<span class="se">\d</span>otnetcore-ci.csproj...
</span></span><span class="line"><span class="cl">  Generating MSBuild file
</span></span><span class="line"><span class="cl">   ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dotnet build
</span></span><span class="line"><span class="cl">Copyright <span class="o">(</span>C<span class="o">)</span> Microsoft Corporation. All rights reserved.
</span></span><span class="line"><span class="cl">e/travis/build/ErikSchierboom/dotnetcore-ci/bin/Debug/netcoreapp1.1/dotnetcore-ci.dll
</span></span><span class="line"><span class="cl">Build succeeded.
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Warning<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Error<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">Time Elapsed 00:00:05.60
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">The <span class="nb">command</span> <span class="s2">&#34;dotnet build&#34;</span> exited with 0.
</span></span><span class="line"><span class="cl">Done. Your build exited with 0.
</span></span></code></pre></div><p>The output is very similar to AppVeyor, with only minor differences. Our continuous integration pipeline now verifies that our application builds both on Windows (AppVeyor) and Linux (Travis).</p>
<h3 id="circleci">CircleCI</h3>
<p>The last CI server we&rsquo;ll look at is <a href="https://circleci.com">CircleCI</a>, which is also Linux-based.</p>
<p>Once again, configuration is done by adding a file to the root directory, this time named <code>circle.yml</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="m">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">build</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">working_directory</span><span class="p">:</span><span class="w"> </span><span class="l">/temp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">docker</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">microsoft/dotnet:sdk</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">DOTNET_SKIP_FIRST_TIME_EXPERIENCE</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">DOTNET_CLI_TELEMETRY_OPTOUT</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">checkout</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">dotnet restore</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">dotnet build</span><span class="w">
</span></span></span></code></pre></div><p>In the first line, we specify that we want to use version 2 of CircleCI, which is currently in beta. With version 2, builds are based on Docker images. That allows us to use the official .NET Core SDK <a href="https://store.docker.com/images/6c038a68-be47-4d7e-bfd2-33a6fe75b9ac?tab=description">Docker image</a> to build our application.</p>
<p>Once again, we also set the .NET CLI environment variables.</p>
<p>Finally, we specify the steps to execute. First, we checkout our repository and then we run <code>dotnet restore</code> and <code>dotnet build</code>.</p>
<p>The build output is similar to that of the other two CI servers:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Build-agent version 0.0.2792-4fbb67c <span class="o">(</span>2017-03-20T15:14:26+0000<span class="o">)</span>
</span></span><span class="line"><span class="cl">Starting container microsoft/dotnet:sdk
</span></span><span class="line"><span class="cl">  image not cached, downloading microsoft/dotnet:sdk
</span></span><span class="line"><span class="cl">sdk: Pulling from microsoft/dotnet
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">Status: Downloaded newer image <span class="k">for</span> microsoft/dotnet:sdk
</span></span><span class="line"><span class="cl">  using image microsoft/dotnet@sha256:3f87a7b7873ced0110a35aee48591f8b4aea3ccb94bf433a80388886bdbd3076
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">git fetch --force origin master:remotes/origin/master
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">Cloning into <span class="s1">&#39;.&#39;</span>...
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">HEAD is now at df83619 Add CircleCI support
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dotnet restore
</span></span><span class="line"><span class="cl">Shell: /bin/bash -eo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Restoring packages <span class="k">for</span> /tmp/dotnetcore-ci.csproj...
</span></span><span class="line"><span class="cl">  Generating MSBuild file /tmp/obj/dotnetcore-ci.csproj.nuget.g.props.
</span></span><span class="line"><span class="cl">  ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dotnet build
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Microsoft <span class="o">(</span>R<span class="o">)</span> Build Engine version 15.1.548.43366
</span></span><span class="line"><span class="cl">Copyright <span class="o">(</span>C<span class="o">)</span> Microsoft Corporation. All rights reserved.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  dotnetcore-ci -&gt; /tmp/bin/Debug/netcoreapp1.1/dotnetcore-ci.dll
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Build succeeded.
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Warning<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="m">0</span> Error<span class="o">(</span>s<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Time Elapsed 00:00:01.94
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Creating, building and running a .NET Core application using the .NET CLI is incredibly easy. It it also quite convenient, as it is cross-platform and you can build your application using the same CLI both locally and remotely.</p>
<p>We used the CLI locally to create a simple .NET Core console application. We then used the CLI remotely to setup three continuous integration servers, AppVeyor, Travis and CircleCI, to build our application.</p>
<p>Configuring the CI servers was very simple: they all required only a single, simple YAML configuration file to be added to the root of our project.</p>
<p>The source code of this test application, which includes the three CI server configuration files, can be found <a href="https://github.com/ErikSchierboom/dotnetcore-ci">here</a>.</p>
]]></content>
		</item>
		
		<item>
			<title>Parsing text in F#</title>
			<link>https://www.erikschierboom.com/2016/12/10/parsing-text-in-fsharp/</link>
			<pubDate>Sat, 10 Dec 2016 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2016/12/10/parsing-text-in-fsharp/</guid>
			<description>Note: this post is part of the F# Advent Calendar 2016.
To hone my programming skills, I&amp;rsquo;ve been using exercism.io a lot. With Exercism, you can work on problems in over 30 different languages. In this blog post, we&amp;rsquo;ll be solving exercism&amp;rsquo;s wordy problem, which focuses on text-parsing. We&amp;rsquo;ll be using F# as our language of choice and use various approaches to solve the problem. In the process, we&amp;rsquo;ll do lots of refactoring.</description>
			<content type="html"><![CDATA[<p>Note: this post is part of the <a href="https://sergeytihon.wordpress.com/2016/10/23/f-advent-calendar-in-english-2016/">F# Advent Calendar 2016</a>.</p>
<p>To hone my programming skills, I&rsquo;ve been using <a href="http://exercism.io/">exercism.io</a> a lot. With Exercism, you can work on problems in over <a href="http://exercism.io/languages">30 different languages</a>. In this blog post, we&rsquo;ll be solving exercism&rsquo;s <a href="http://exercism.io/exercises/fsharp/wordy/readme">wordy</a> problem, which focuses on text-parsing. We&rsquo;ll be using F# as our language of choice and use various approaches to solve the problem. In the process, we&rsquo;ll do lots of refactoring.</p>
<h2 id="setting-up-exercism">Setting up Exercism</h2>
<p>Setting up Exercism is simple. It involves three steps:</p>
<ol>
<li>Create an account by <a href="http://exercism.io/login">logging in</a> to Exercism with your GitHub credentials.</li>
<li>Install the Exercism <a href="http://exercism.io/cli">command-line client</a>, which is available for Windows, MacOS and Linux.</li>
<li>Configure the command-line client with your account&rsquo;s <a href="http://exercism.io/account/key">API key</a>:</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">exercism configure --key<span class="o">=</span>&lt;your API key&gt;
</span></span></code></pre></div><p>Once these steps have been completed, you can use the CLI to fetch and submit problems. If you&rsquo;d like more detailed instructions on how to setup Exercism, please follow their <a href="http://exercism.io/how-it-works/newbie">detailed tutorial</a>.</p>
<h2 id="problem-1-wordy">Problem 1: Wordy</h2>
<p>To start working on the wordy problem with F#, we use this CLI command:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">exercism fetch fsharp wordy
</span></span></code></pre></div><p>This command will fetch the wordy exercise&rsquo;s <a href="http://exercism.io/exercises/fsharp/wordy/readme">README</a> and <a href="http://exercism.io/exercises/fsharp/wordy/test-suite">test suite</a>, and write them to the file system:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Not Submitted:            <span class="m">1</span> problem
</span></span><span class="line"><span class="cl">fsharp <span class="o">(</span>Wordy<span class="o">)</span> /Users/erikschierboom/exercism/fsharp/wordy
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">New:                      <span class="m">1</span> problem
</span></span><span class="line"><span class="cl">fsharp <span class="o">(</span>Wordy<span class="o">)</span> /Users/erikschierboom/exercism/fsharp/wordy
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">unchanged: 0, updated: 0, new: <span class="m">1</span>
</span></span></code></pre></div><p>If we examine the contents of the <code>wordy</code> directory, we&rsquo;ll find two files:</p>
<ol>
<li><code>README.md</code>: a textual description of the exercise.</li>
<li><code>WordyTest.fs</code>: the test suite, to verify the correctness of the implementation.</li>
</ol>
<p>As said, the <code>README</code> file describes the problem we should solve:</p>
<blockquote>
<p>Write a program that takes a word problem and returns the answer as an integer.</p>
</blockquote>
<p>It also lists some sample word problems, such as:</p>
<blockquote>
<p>What is 5 plus 13?</p>
</blockquote>
<p>Now that we know the problem to solve, let&rsquo;s try to solve it. We&rsquo;ll go at it one test at a time, slowly building up a correct implementation that passes all tests (which are defined in the <code>WordyTest.fs</code> test suite). In the process, we&rsquo;ll do lots of refactoring, to try to improve the quality of our code. Let&rsquo;s start!</p>
<h3 id="test-1-single-digit-numbers">Test 1: single digit numbers</h3>
<p>The first test is defined as followed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can parse and solve addition problems``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is 1 plus 1?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="n">2</span><span class="o">))</span>
</span></span></code></pre></div><p>From this code we can infer that we need to define a <code>solve</code> function that takes a <code>string</code> parameter (the equation) and returns an <code>int option</code> value (the equation&rsquo;s result).</p>
<p>Let&rsquo;s implement a very simple equation solver that removes all non-digit characters and then parses the two remaining digits to calculate the sum:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="n">question</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;What is &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34; plus &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;?&#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">left</span>  <span class="o">=</span> <span class="nn">Convert</span><span class="p">.</span><span class="n">ToInt32</span><span class="o">(</span><span class="n">equation</span><span class="o">.</span><span class="n">Substring</span><span class="o">(</span><span class="n">0</span><span class="o">,</span> <span class="n">1</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="nn">Convert</span><span class="p">.</span><span class="n">ToInt32</span><span class="o">(</span><span class="n">equation</span><span class="o">.</span><span class="n">Substring</span><span class="o">(</span><span class="n">1</span><span class="o">,</span> <span class="n">1</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>If we run the test with this code, it passes.</p>
<p>Note that we aligned the <code>Convert.ToInt</code> calls. Aligning these statements has two advantages:</p>
<ol>
<li>As the statements are so alike, they give users a clue that they probably have similar functionality.</li>
<li>It helps us compare the statements. With this alignment, it becomes easy to see which parts of the strings they convert.</li>
</ol>
<h4 id="refactoring-simplify-integer-conversion">Refactoring: simplify integer conversion</h4>
<p>Our first refactoring is to use the <code>int</code> function instead of <code>Convert.ToInt32</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="n">question</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;What is &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34; plus &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;?&#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">left</span>  <span class="o">=</span> <span class="n">int</span> <span class="o">&lt;|</span> <span class="n">equation</span><span class="o">.</span><span class="n">Substring</span><span class="o">(</span><span class="n">0</span><span class="o">,</span> <span class="n">1</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">int</span> <span class="o">&lt;|</span> <span class="n">equation</span><span class="o">.</span><span class="n">Substring</span><span class="o">(</span><span class="n">1</span><span class="o">,</span> <span class="n">1</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>A quick check verifies that our code still passes the test.</p>
<p>We can also replace the <code>Substring</code> calls with array slice syntax:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="n">question</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;What is &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34; plus &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">            <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;?&#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">left</span>  <span class="o">=</span> <span class="n">int</span> <span class="n">equation</span><span class="o">.[</span><span class="n">0</span><span class="o">..</span><span class="n">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">int</span> <span class="n">equation</span><span class="o">.[</span><span class="n">1</span><span class="o">..</span><span class="n">1</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><h4 id="refactoring-extract-helper-functions">Refactoring: extract helper functions</h4>
<p>Next, we can make the <code>solve</code> function a bit easier to read by extracting some helper functions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">question</span>
</span></span><span class="line"><span class="cl">        <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;What is &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34; plus &#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="o">.</span><span class="n">Replace</span><span class="o">(</span><span class="s">&#34;?&#34;</span><span class="o">,</span> <span class="s">&#34;&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseLeft</span>  <span class="o">(</span><span class="n">equation</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span> <span class="n">int</span> <span class="n">equation</span><span class="o">.[</span><span class="n">0</span><span class="o">..</span><span class="n">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseRight</span> <span class="o">(</span><span class="n">equation</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span> <span class="n">int</span> <span class="n">equation</span><span class="o">.[</span><span class="n">1</span><span class="o">..</span><span class="n">1</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equation</span> <span class="o">=</span> <span class="n">parseEquation</span> <span class="n">question</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">left</span>  <span class="o">=</span> <span class="n">parseLeft</span> <span class="n">equation</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">parseRight</span> <span class="n">equation</span>
</span></span><span class="line"><span class="cl">    <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>The refactored code looks cleaner to me, and it still passes the test! On to the second test.</p>
<h3 id="test-2-double-digit-numbers">Test 2: double digit numbers</h3>
<p>In the second test, we have to parse double digit numbers:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can add double digit numbers``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is 53 plus 2?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="n">55</span><span class="o">))</span>
</span></span></code></pre></div><p>If we run this test, it fails. This is due to us hard-coding the <code>int</code> parsing to single digits. To support double digit numbers, we&rsquo;ll rewrite our code to use regular expressions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">pattern</span> <span class="o">=</span> <span class="s">&#34;What is (</span><span class="err">\</span><span class="s">d+) plus (</span><span class="err">\</span><span class="s">d+)</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">matched</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Match</span><span class="o">(</span><span class="n">question</span><span class="o">,</span> <span class="n">pattern</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">left</span>  <span class="o">=</span> <span class="n">int</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="n">1</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">int</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="n">2</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">    <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>This time, the double digit test passes. Although regular expressions can easily become complicated and hard to read, ours is quite simple and understandable. In this case, I feel that using a regular expression does improve the code&rsquo;s readability.</p>
<p>Note that we assume the regular expression always matches. We&rsquo;ll defer adding proper error handling until later, when the tests force us to.</p>
<h4 id="refactoring-using-named-expressions">Refactoring: using named expressions</h4>
<p>Although the regular expression is quite simple, I don&rsquo;t like how we extract the matched digit values using integer indexing. We can improve this by using <a href="https://msdn.microsoft.com/en-us/library/bs2twtah(v=vs.110).aspx#named_matched_subexpression">named expressions</a>. This regular expression feature lets us attach a name to an expression, which we can then use to retrieve the matched value:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">pattern</span> <span class="o">=</span> <span class="s">&#34;What is (?&lt;left&gt;</span><span class="err">\</span><span class="s">d+) plus (?&lt;right&gt;</span><span class="err">\</span><span class="s">d+)</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">matched</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Match</span><span class="o">(</span><span class="n">question</span><span class="o">,</span> <span class="n">pattern</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">left</span>  <span class="o">=</span> <span class="n">int</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;left&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">int</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;right&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">    <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>You can see that the <code>(\d+) plus (\d+)</code> part of the regular expression has been replaced with <code>(?&lt;left&gt;\d+) plus (?&lt;right&gt;\d+)</code>. The <code>?&lt;left&gt;</code> and <code>?&lt;right&gt;</code> parts specify the names of the expressions. We then use these names to index into the matched groups, instead of using integer indexers.</p>
<p>Re-running our tests verifies that everything still works.</p>
<h3 id="test-3-negative-numbers">Test 3: negative numbers</h3>
<p>The third test haves us work with negative numbers:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can add negative numbers``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is -1 plus -10?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="o">-</span><span class="n">11</span><span class="o">))</span>
</span></span></code></pre></div><p>Once again, we have to fix our code to make this test pass. Luckily, the fix is as simple as adding an optional minus (<code>-</code>) prefix to the digit matching expressions in our regular expression:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">pattern</span> <span class="o">=</span> <span class="s">&#34;What is (?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) plus (?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+)</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span></code></pre></div><h3 id="test-4-large-numbers">Test 4: large numbers</h3>
<p>Our current implementation passes this test, so let&rsquo;s move on.</p>
<h3 id="test-5-subtraction">Test 5: subtraction</h3>
<p>In test number 5, we have to deal with a new operator, the minus operator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can parse and solve subtraction problems``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is 4 minus -12?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="n">16</span><span class="o">))</span>
</span></span></code></pre></div><p>To support the new operator, we first capture it in our regular expression:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">pattern</span> <span class="o">=</span> <span class="s">&#34;What is (?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator&gt;plus|minus) (?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+)</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span></code></pre></div><p>The final step is to replace the <code>Some (left + right)</code> expression with a match on the operator&rsquo;s value to determine what value to return:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">match</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;operator&#34;</span><span class="o">].</span><span class="n">Value</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;plus&#34;</span>  <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;minus&#34;</span> <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">-</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>Running the tests again verifies that they all pass.</p>
<h4 id="refactoring-using-active-patterns">Refactoring: using Active Patterns</h4>
<p>If we look at our current code, it consists of three simple steps:</p>
<ol>
<li>Match the question with our regular expression.</li>
<li>Convert the <code>&quot;left&quot;</code> and <code>&quot;right&quot;</code> groups to <code>int</code> values.</li>
<li>Based on the matched <code>&quot;operator&quot;</code>, combine the left and right values and return it as an <code>int option</code> value.</li>
</ol>
<p>This combination of matching and transforming is so commonplace, that F# created a special construct for it: <a href="https://fsharpforfunandprofit.com/posts/convenience-active-patterns/">Active Patterns</a>. Let&rsquo;s create an Active Pattern that will match an equation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="o">(|</span><span class="n">Equation</span><span class="o">|)</span> <span class="n">question</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">pattern</span> <span class="o">=</span> <span class="s">&#34;What is (?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator&gt;plus|minus) (?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+)</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">matched</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Match</span><span class="o">(</span><span class="n">question</span><span class="o">,</span> <span class="n">pattern</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">left</span>  <span class="o">=</span> <span class="n">int</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;left&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">int</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;right&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;operator&#34;</span><span class="o">].</span><span class="n">Value</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;plus&#34;</span>  <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;minus&#34;</span> <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">-</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>The main thing to note is that the function&rsquo;s body is just literally copy-pasted from the <code>solve</code> method. What&rsquo;s different though, is the function&rsquo;s identifier. An Active Pattern&rsquo;s identifier is defined between pipe (<code>|</code>) characters, placed within parentheses.</p>
<p>We can use this Active Pattern in our <code>solve</code> function as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">question</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Equation</span> <span class="n">result</span> <span class="o">-&gt;</span> <span class="n">result</span>
</span></span></code></pre></div><p>You can see that we can <code>match</code> the question <code>string</code> using our <code>Equation</code> Active Pattern, with the value returned from the Active Pattern being bound to the <code>result</code> identifer.</p>
<p>Re-running the tests confirms that everything still works. Looking at our code though, I don&rsquo;t think the Active Pattern gives us much in terms of readability our functionality, so we&rsquo;ll revert our code to the previous iteration (which didn&rsquo;t use an Active Pattern).</p>
<h3 id="test-6-multiplication">Test 6: multiplication</h3>
<p>In test 6, multiplication is added to the list of supported operations:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can parse and solve multiplication problems``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is -3 multiplied by 25?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="o">-</span><span class="n">75</span><span class="o">))</span>
</span></span></code></pre></div><p>This is trivial to add. We simply add the <code>&quot;multiplied by&quot;</code> string to the operator part of our regular expression, and then handle this operator in our <code>match</code> clause:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">match</span> <span class="n">matched</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;operator&#34;</span><span class="o">].</span><span class="n">Value</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">-</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span> <span class="o">*</span> <span class="n">right</span><span class="o">)</span>
</span></span></code></pre></div><p>With that, the test passes.</p>
<h3 id="test-7-division">Test 7: division</h3>
<p>Test 7 adds supports for division:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can parse and solve division problems``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is 33 divided by -3?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="o">-</span><span class="n">11</span><span class="o">))</span>
</span></span></code></pre></div><p>Once again, this is trivial to add, so let&rsquo;s skip the implementation details.</p>
<h3 id="test-8-add-twice">Test 8: add twice</h3>
<p>Things start getting more interesting in test 8, where we have to add not once, but twice!</p>
<pre tabindex="0"><code>[&lt;Test&gt;]
let ``Can add twice`` () =
    Assert.That(solve &#34;What is 1 plus 1 plus 1?&#34;, Is.EqualTo(Some 3))
</code></pre><p>So far, we have only considered simple expressions with two integers and one operand. However this time, we start with the leftmost number and then apply two of operations. The most hacky solution would be to just match an optional second operation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">pattern</span> <span class="o">=</span> <span class="s">&#34;What is (?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator1&gt;plus|minus|multiplied by|divided by) (?&lt;right1&gt;-?</span><span class="err">\</span><span class="s">d+)( (?&lt;operator2&gt;plus|minus|multiplied by|divided by) (?&lt;right2&gt;-?</span><span class="err">\</span><span class="s">d+))</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span></code></pre></div><p>However, I don&rsquo;t think this is very readable, nor is it very future-proof (what if we want to support five operations?). Let&rsquo;s take a step back to figure out a better approach. Sometimes it helps to make the state transitions explicit, so let&rsquo;s try that for the <code>&quot;What is 1 plus 1 plus 1?&quot;</code> question:</p>
<ol>
<li>Set the current state to 1.</li>
<li>Add 1 to the current state (1). Returns 2.</li>
<li>Add 1 to the current state (2). Returns 3.</li>
</ol>
<p>I don&rsquo;t know about you, but this looks an awful lot like a left fold to me. To use a left fold in our implementation, we first have to ensure that we match the added second operation. Our initial attempt at this might look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">pattern</span> <span class="o">=</span> <span class="s">&#34;What is (?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+)(?&lt;operations&gt; (?&lt;operator&gt;plus|minus|multiplied by|divided by) (?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+))+</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span></code></pre></div><p>Here, we define a new capture group named <code>&quot;operations&quot;</code> that matches one or more operator/operand combinations. Unfortunately, this did not work. Let&rsquo;s try another approach where we split the operations matching part into its own pattern:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationPattern</span> <span class="o">=</span> <span class="s">&#34;What is (?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+)(?&lt;operations&gt;.+?)</span><span class="err">\</span><span class="s">?&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">operationsPattern</span> <span class="o">=</span> <span class="s">&#34; (?&lt;operator&gt;plus|minus|multiplied by|divided by) (?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+)&#34;</span>
</span></span></code></pre></div><p>Next, we&rsquo;ll do two matches:</p>
<ol>
<li>We match the equation (without matching the actual operations).</li>
<li>We match the operations using the matched <code>&quot;operations&quot;</code> part of the equation match:</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationMatch</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Match</span><span class="o">(</span><span class="n">question</span><span class="o">,</span> <span class="n">equationPattern</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">operationMatches</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Matches</span><span class="o">(</span><span class="n">equationMatch</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;operations&#34;</span><span class="o">].</span><span class="n">Value</span><span class="o">,</span> <span class="n">operationsPattern</span><span class="o">)</span>
</span></span></code></pre></div><p>We can then calculate the equation&rsquo;s result by folding on the matched operations, with the leftmost integer as the starting state:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">left</span> <span class="o">=</span> <span class="n">int</span> <span class="n">equationMatch</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;left&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">folder</span> <span class="n">result</span> <span class="o">(</span><span class="n">operation</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">int</span> <span class="n">operation</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;right&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">operation</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;operator&#34;</span><span class="o">].</span><span class="n">Value</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">folder</span> <span class="n">left</span> <span class="o">(</span><span class="nn">Seq</span><span class="p">.</span><span class="n">cast</span> <span class="n">operationMatches</span><span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="n">Some</span> <span class="n">result</span>
</span></span></code></pre></div><p>Note that we have to add a type annotation on the <code>operation</code> parameter and use <code>Seq.cast</code> on the <code>operationMatches</code> value, due to the <code>MatchCollection</code> type not implementing <code>IEnumerable&lt;Match&gt;</code>. The result is just your typical fold and is quite readable.</p>
<p>Let&rsquo;s run our tests to see if they now pass, which they do!</p>
<h3 id="test-9-add-then-subtract">Test 9: add then subtract</h3>
<p>The next test also involves multiple operations, but this time using two different operations:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can add then subtract``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is 1 plus 5 minus -2?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="n">8</span><span class="o">))</span>
</span></span></code></pre></div><p>Luckily for us, our fold solution already supports multiple different operations, so this test passes without any additional work.</p>
<h3 id="test-10-subtract-twice">Test 10: subtract twice</h3>
<p>A double subtraction is also no problem for our implementation, the test passes.</p>
<h3 id="test-11-subtract-then-add">Test 11: subtract then add</h3>
<p>Subtracting and then adding? Already working!</p>
<h3 id="test-12-multiply-twice">Test 12: multiply twice</h3>
<p>Our code also immediately passes the double multiplication test.</p>
<h3 id="test-13-add-then-multiply">Test 13: add then multiply</h3>
<p>In test 13, we first add a number and then multiply:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Can add then multiply``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is -3 plus 7 multiplied by -2?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">Some</span> <span class="o">-</span><span class="n">8</span><span class="o">))</span>
</span></span></code></pre></div><p>Although our test passes, there is something odd about this test. Shouldn&rsquo;t the result be <code>-17</code>? Well, yes and no. In mathematics, the multiplication operator has a higher precedence than the addition operator, so the equation should be evaluated as <code>-3 + (7 * -2)</code>, which equals <code>-17</code>. However, this does not hold for this exercise, as the README explicitly states:</p>
<blockquote>
<p>Remember, that these are verbal word problems, not treated as you normally would treat a written problem. This means that you calculate as you move forward each step. In other words, you should ignore order of operations. 3 + 2 * 3 = 15, not 9.</p>
</blockquote>
<p>Ignoring the order of operations is precisely what we do, hence the passing test.</p>
<h3 id="test-14-divide-twice">Test 14: divide twice</h3>
<p>This test passes.</p>
<h3 id="test-15-ignore-unsupported-operation">Test 15: ignore unsupported operation</h3>
<p>With test 15, we have our first test that is expected to &ldquo;fail&rdquo;, indicated by returning <code>None</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Cubed is too advanced``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;What is 53 cubed?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">None</span><span class="o">))</span>
</span></span></code></pre></div><p>At the moment, our code does not pass this test. Why is that? Well, the left part of the equation (<code>&quot;53&quot;</code>) matches. The operations regular expression does not match any operation, so it returns an empty sequence. If we fold on an empty sequence, the initial state (<code>53</code>), is returned, hence the value returned by our code equals <code>Some 53</code>, not <code>None</code>.</p>
<p>The fix is simple, we just return <code>None</code> if there are no matched operations:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">if</span> <span class="n">operationMatches</span><span class="o">.</span><span class="n">Count</span> <span class="o">=</span> <span class="n">0</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="n">None</span>
</span></span></code></pre></div><p>With this fix, the test passes.</p>
<h3 id="test-16-irrelevant-problems-are-not-valid">Test 16: irrelevant problems are not valid</h3>
<p>The final test also deals with invalid input:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">[&lt;</span><span class="n">Test</span><span class="o">&gt;]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="n">``Irrelevant problems are not valid``</span> <span class="bp">()</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">Assert</span><span class="p">.</span><span class="n">That</span><span class="o">(</span><span class="n">solve</span> <span class="s">&#34;Who is the president of the United States?&#34;</span><span class="o">,</span> <span class="nn">Is</span><span class="p">.</span><span class="n">EqualTo</span><span class="o">(</span><span class="n">None</span><span class="o">))</span>
</span></span></code></pre></div><p>As there are no matching operations, <code>None</code> is returned and this test passes. With that our implementation now passes all tests. Hurray!</p>
<p>Does this mean we&rsquo;re done? Well, we could use the CLI to submit our solution to Exercism and move on the next exercise. However, let&rsquo;s try to do some refactoring/cleanup, to see if we can improve the code even more.</p>
<h3 id="refactoring-fixing-compile-time-warning">Refactoring: fixing compile-time warning</h3>
<p>Those of your that know your F#, will have known that when we introduced the <code>match</code> statement, we introduced the following compile-time warning:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>What this error message tells us, is that our <code>match</code> statement doesn&rsquo;t handle all possible cases. This is true of course, as we only handle the four supported operators. We could ignore this warning (the code still compiles after all), but it is always a good idea to heed compiler warnings, so let&rsquo;s fix it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">match</span> <span class="n">operation</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;operator&#34;</span><span class="o">].</span><span class="n">Value</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl"><span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Unsupported operator&#34;</span>
</span></span></code></pre></div><p>The added default case simply throws an exception. If we now compile our code, the warning disappears.</p>
<h3 id="refactoring-regular-expression-matching-revisited">Refactoring: regular expression matching, revisited</h3>
<p>Previously, we had problems to match both the left <em>and</em> right part of an equation using a single regular expression. We then resorted to matching the equation in two parts: first the equation, then the operations. However, after some more searching, we came across a very interesting regular expressions feature: positive lookahead assertions. With that, we can actually get it all working in a single regex:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equationPattern</span> <span class="o">=</span> <span class="s">&#34;(?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator&gt;-?plus|minus|divided by|multiplied by) (?=(?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+))&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equationMatches</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Matches</span><span class="o">(</span><span class="n">question</span><span class="o">,</span> <span class="n">equationPattern</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">equationMatches</span><span class="o">.</span><span class="n">Count</span> <span class="o">=</span> <span class="n">0</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        <span class="n">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">left</span> <span class="o">=</span> <span class="n">int</span> <span class="n">equationMatches</span><span class="o">.[</span><span class="n">0</span><span class="o">].</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;left&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">folder</span> <span class="n">result</span> <span class="o">(</span><span class="n">operation</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">            <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">int</span> <span class="n">operation</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;right&#34;</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl">            <span class="k">match</span> <span class="n">operation</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="s">&#34;operator&#34;</span><span class="o">].</span><span class="n">Value</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Unsupported operator&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">folder</span> <span class="n">left</span> <span class="o">(</span><span class="nn">Seq</span><span class="p">.</span><span class="n">cast</span> <span class="n">equationMatches</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">Some</span> <span class="n">result</span>
</span></span></code></pre></div><h3 id="refactoring-extracting-functions">Refactoring: extracting functions</h3>
<p>At the moment, our <code>solve</code> function is quite big and has some repetition. Let&rsquo;s remove some of the regular expression group matching code duplication by extracting two helper functions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">regexGroupString</span> <span class="o">(</span><span class="n">groupName</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="n">groupName</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">regexGroupInt</span>    <span class="o">(</span><span class="n">groupName</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupString</span> <span class="n">groupName</span> <span class="n">m</span> <span class="o">|&gt;</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equationPattern</span> <span class="o">=</span> <span class="s">&#34;(?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator&gt;-?plus|minus|divided by|multiplied by) (?=(?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+))&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equationMatches</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Matches</span><span class="o">(</span><span class="n">question</span><span class="o">,</span> <span class="n">equationPattern</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">equationMatches</span><span class="o">.</span><span class="n">Count</span> <span class="o">=</span> <span class="n">0</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        <span class="n">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">left</span> <span class="o">=</span> <span class="n">regexGroupInt</span> <span class="s">&#34;left&#34;</span> <span class="n">equationMatches</span><span class="o">.[</span><span class="n">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">folder</span> <span class="n">result</span> <span class="o">(</span><span class="n">operation</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">            <span class="k">let</span> <span class="nv">right</span> <span class="o">=</span> <span class="n">regexGroupInt</span> <span class="s">&#34;right&#34;</span> <span class="n">operation</span>
</span></span><span class="line"><span class="cl">            <span class="k">match</span> <span class="n">regexGroupString</span> <span class="s">&#34;operator&#34;</span> <span class="n">operation</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">            <span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Unsupported operator&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">folder</span> <span class="n">left</span> <span class="o">(</span><span class="nn">Seq</span><span class="p">.</span><span class="n">cast</span> <span class="n">equationMatches</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">Some</span> <span class="n">result</span>
</span></span></code></pre></div><p>Better, but we still have to deal with the regular expressions groups in the <code>solve</code> function, which should be an implementation detail the <code>solve</code> function does not know about. Let&rsquo;s extract the parsing of the various parts into helper functions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseLeftOperand</span>  <span class="o">(</span><span class="n">matches</span><span class="o">:</span> <span class="n">MatchCollection</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupInt</span> <span class="s">&#34;left&#34;</span> <span class="n">matches</span><span class="o">.[</span><span class="n">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseRightOperand</span> <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupInt</span> <span class="s">&#34;right&#34;</span> <span class="n">m</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span>     <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupString</span> <span class="s">&#34;operator&#34;</span> <span class="n">m</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span>    <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="o">(</span><span class="n">parseOperator</span> <span class="n">m</span><span class="o">,</span> <span class="n">parseRightOperand</span> <span class="n">m</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperations</span> <span class="o">(</span><span class="n">matches</span><span class="o">:</span> <span class="n">MatchCollection</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">matches</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">cast</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="n">parseOperation</span>
</span></span></code></pre></div><p>The relevant part of the <code>solve</code> function already looks much cleaner without all the implementation details:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">left</span> <span class="o">=</span> <span class="n">parseLeftOperand</span> <span class="n">equationMatches</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">operations</span> <span class="o">=</span> <span class="n">parseOperations</span> <span class="n">equationMatches</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">folder</span> <span class="n">result</span> <span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">operator</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Unsupported operator&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">folder</span> <span class="n">left</span> <span class="n">operations</span>
</span></span><span class="line"><span class="cl"><span class="n">Some</span> <span class="n">result</span>
</span></span></code></pre></div><p>Our next step is to extract the equation result calculating code into its own function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solveEquation</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">folder</span> <span class="n">result</span> <span class="o">(</span><span class="n">operation</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">        <span class="k">match</span> <span class="n">operation</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">result</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">        <span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Unsupported operator&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">folder</span> <span class="n">left</span> <span class="n">operations</span>
</span></span></code></pre></div><p>The <code>folder</code> helper function is badly named, so let&rsquo;s extract it to a better-named function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">applyOperation</span> <span class="n">acc</span> <span class="o">(</span><span class="n">operation</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">operation</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Unsupported operator&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solveEquation</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">applyOperation</span> <span class="n">left</span> <span class="n">operations</span>
</span></span></code></pre></div><p>At the moment, the equation solving has been extracted to a separate function, but the parsing has not. So let&rsquo;s fix this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equationPattern</span> <span class="o">=</span> <span class="s">&#34;(?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator&gt;-?plus|minus|divided by|multiplied by) (?=(?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+))&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equationMatches</span> <span class="o">=</span> <span class="nn">Regex</span><span class="p">.</span><span class="n">Matches</span><span class="o">(</span><span class="n">question</span><span class="o">,</span> <span class="n">equationPattern</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">equationMatches</span><span class="o">.</span><span class="n">Count</span> <span class="o">=</span> <span class="n">0</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        <span class="n">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="n">Some</span> <span class="o">(</span><span class="n">parseLeftOperand</span> <span class="n">equationMatches</span><span class="o">,</span> <span class="n">parseOperations</span> <span class="n">equationMatches</span><span class="o">)</span>
</span></span></code></pre></div><p>Let&rsquo;s extract the equation matching into a separate <code>Regex</code> instance:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationRegex</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Regex</span><span class="o">(</span><span class="s">&#34;(?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator&gt;-?plus|minus|divided by|multiplied by) (?=(?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+))&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">let</span> <span class="nv">equationMatches</span> <span class="o">=</span> <span class="n">equationRegex</span><span class="o">.</span><span class="n">Matches</span> <span class="n">question</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">equationMatches</span><span class="o">.</span><span class="n">Count</span> <span class="o">=</span> <span class="n">0</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">        <span class="n">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="n">Some</span> <span class="o">(</span><span class="n">parseLeftOperand</span> <span class="n">equationMatches</span><span class="o">,</span> <span class="n">parseOperations</span> <span class="n">equationMatches</span><span class="o">)</span>
</span></span></code></pre></div><p>In general, using an <code>if</code>-statement is discouraged, so let&rsquo;s use a <code>match</code> expression:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">equationRegex</span><span class="o">.</span><span class="n">Matches</span> <span class="n">question</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">matches</span> <span class="k">when</span> <span class="n">matches</span><span class="o">.</span><span class="n">Count</span> <span class="o">=</span> <span class="n">0</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">matches</span> <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">parseLeftOperand</span> <span class="n">matches</span><span class="o">,</span> <span class="n">parseOperations</span> <span class="n">matches</span><span class="o">)</span>
</span></span></code></pre></div><p>The <code>solve</code> function then becomes quite simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">parseEquation</span> <span class="n">question</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Some</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="n">solveEquation</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">Some</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">None</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span></code></pre></div><p>Clearly, we don&rsquo;t need to (de)construct the equation tuple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">parseEquation</span> <span class="n">question</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Some</span> <span class="n">equation</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="k">let</span> <span class="nv">result</span> <span class="o">=</span> <span class="n">solveEquation</span> <span class="n">equation</span>
</span></span><span class="line"><span class="cl">        <span class="n">Some</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">None</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span></code></pre></div><p>Better, but this matching of the <code>parseEquation</code> result still looks a bit ugly. However, with the <code>Option.map</code> function and the pipe operator, we can rewrite this to:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">question</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">parseEquation</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Option</span><span class="p">.</span><span class="n">map</span> <span class="n">solveEquation</span>
</span></span></code></pre></div><p>Not only does this look very pretty, it also perfectly illustrates the pipeline like nature of our implementation:</p>
<ol>
<li>Parse the question into an equation.</li>
<li>Solve the equation, if it could be parsed</li>
</ol>
<p>Through a series of relatively small refactorings, we&rsquo;ve managed to create a relatively simple implementation that passes all tests. This is the complete, refactored implementation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">equationRegex</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Regex</span><span class="o">(</span><span class="s">&#34;(?&lt;left&gt;-?</span><span class="err">\</span><span class="s">d+) (?&lt;operator&gt;-?plus|minus|divided by|multiplied by) (?=(?&lt;right&gt;-?</span><span class="err">\</span><span class="s">d+))&#34;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">regexGroupString</span> <span class="o">(</span><span class="n">groupName</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">Groups</span><span class="o">.[</span><span class="n">groupName</span><span class="o">].</span><span class="n">Value</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">regexGroupInt</span>    <span class="o">(</span><span class="n">groupName</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupString</span> <span class="n">groupName</span> <span class="n">m</span> <span class="o">|&gt;</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseLeftOperand</span>  <span class="o">(</span><span class="n">matches</span><span class="o">:</span> <span class="n">MatchCollection</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupInt</span> <span class="s">&#34;left&#34;</span> <span class="n">matches</span><span class="o">.[</span><span class="n">0</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseRightOperand</span> <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupInt</span> <span class="s">&#34;right&#34;</span> <span class="n">m</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span>     <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="n">regexGroupString</span> <span class="s">&#34;operator&#34;</span> <span class="n">m</span>
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span>    <span class="o">(</span><span class="n">m</span><span class="o">:</span> <span class="n">Match</span><span class="o">)</span> <span class="o">=</span> <span class="o">(</span><span class="n">parseOperator</span> <span class="n">m</span><span class="o">,</span> <span class="n">parseRightOperand</span> <span class="n">m</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperations</span> <span class="o">(</span><span class="n">matches</span><span class="o">:</span> <span class="n">MatchCollection</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">matches</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">cast</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">map</span> <span class="n">parseOperation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">equationRegex</span><span class="o">.</span><span class="n">Matches</span> <span class="n">question</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">matches</span> <span class="k">when</span> <span class="n">matches</span><span class="o">.</span><span class="n">Count</span> <span class="o">=</span> <span class="n">0</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">matches</span> <span class="o">-&gt;</span> <span class="n">Some</span> <span class="o">(</span><span class="n">parseLeftOperand</span> <span class="n">matches</span><span class="o">,</span> <span class="n">parseOperations</span> <span class="n">matches</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">applyOperation</span> <span class="n">acc</span> <span class="o">(</span><span class="n">operation</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">operation</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">failwith</span> <span class="s">&#34;Unsupported operator&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solveEquation</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">applyOperation</span> <span class="n">left</span> <span class="n">operations</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">question</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="n">parseEquation</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Option</span><span class="p">.</span><span class="n">map</span> <span class="n">solveEquation</span>
</span></span></code></pre></div><p>While this implementation is not too bad, there is a fair amount of boilerplate code to handle the regular expression. Furthermore, we use a relatively obscure regular expression feature (positive lookahead assertions), which lessens its readability.</p>
<p>Is there anything we can do to fix these issues? Well, actually there is! Let&rsquo;s prepare ourselves for another big rewrite, this time using parser combinators.</p>
<h3 id="refactoring-parser-combinators">Refactoring: parser combinators</h3>
<p>If we look at our existing implementation, we can see that we parse an equation in several, small steps:</p>
<ol>
<li>Parse the left operand.</li>
<li>Parse the list of right operator/operand combinations:
<ul>
<li>Parse the right operator.</li>
<li>Parse the right operand.</li>
</ul>
</li>
</ol>
<p>This type of parsing setup is ideal for a specific type of text parsing library: a <a href="https://en.wikipedia.org/wiki/Parser_combinator">parser combinator</a>. At its core, a parser combinator is a collection of fairly basic text-parsing functions. The reason it is called a parser <em>combinator</em>, is that you can create complex parsers by combining those basic parsers. Let&rsquo;s convert our existing, regular expression-based implementation to one that uses a parser combinator library.</p>
<p>Let&rsquo;s start by installing the <a href="http://www.quanttec.com/fparsec/">FParsec</a> parser combinator library:</p>
<p><code>Install-Package FParsec</code></p>
<p>We are now ready to create our first parser.</p>
<h4 id="parser-left-operand">Parser: left operand</h4>
<p>First up: parsing the left operand, which parses a <code>string</code> into an <code>int</code>. As you might have expected, FParsec already has a function to do this for you: <a href="http://www.quanttec.com/fparsec/reference/charparsers.html#members.pint32"><code>pint32</code></a> (which you should read as: <em>parse an int32</em>).</p>
<p>To verify the <code>pint32</code> parser&rsquo;s behavior, open an F# interactive window and load the FParsec library references. We can then test the parser using the <a href="http://www.quanttec.com/fparsec/reference/charparsers.html#members.run"><code>run</code></a> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">open</span> <span class="nn">FParsec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">pint32</span> <span class="s">&#34;13&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">int32</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="n">13</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">pint32</span> <span class="s">&#34;789&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">int32</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="n">789</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">pint32</span> <span class="s">&#34;abc&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">int32</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Failure</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">Error</span> <span class="k">in</span> <span class="n">Ln</span><span class="o">:</span> <span class="n">1</span> <span class="n">Col</span><span class="o">:</span> <span class="n">1</span>
</span></span><span class="line"><span class="cl"> <span class="n">abc</span>
</span></span><span class="line"><span class="cl"> <span class="o">^</span>
</span></span><span class="line"><span class="cl"> <span class="n">Expecting</span><span class="o">:</span> <span class="n">integer</span> <span class="n">number</span> <span class="o">(</span><span class="n">32</span><span class="o">-</span><span class="n">bit</span><span class="o">,</span> <span class="n">signed</span><span class="o">)</span>
</span></span></code></pre></div><p>The first two inputs were valid <code>int32</code> values, so the <code>run</code> function returned a <code>Success</code> value containing the corresponding, parsed number. The third input was not a correct <code>int32</code> value, so a <code>Failure</code> value was returned containing an error message.</p>
<p>Defining our left operand parser is simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseLeftOperand</span> <span class="o">=</span> <span class="n">pint32</span>
</span></span></code></pre></div><h4 id="parser-right-operand">Parser: right operand</h4>
<p>Similarly, we can define our right operand parser as:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseRightOperand</span> <span class="o">=</span> <span class="n">pint32</span>
</span></span></code></pre></div><p>Hmmm, the <code>parseLeftOperand</code> and <code>parseRightOperand</code> functions are identical! We can safely merge them into a single function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperand</span> <span class="o">=</span> <span class="n">pint32</span>
</span></span></code></pre></div><p>Previously, this was not possible, as the operand values had to be retrieved from differently named regular expression groups.</p>
<h4 id="parser-right-operator">Parser: right operator</h4>
<p>Our right operator parser is one that matches one of the following string values:</p>
<ul>
<li>&ldquo;plus&rdquo;</li>
<li>&ldquo;minus&rdquo;</li>
<li>&ldquo;divided by&rdquo;</li>
<li>&ldquo;multiplied by&rdquo;</li>
</ul>
<p>Any other string value is considered invalid. We can create a parser to match a specific string using the <code>pstring</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">run</span> <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;abc&#34;</span><span class="o">)</span> <span class="s">&#34;abc&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="s">&#34;abc&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;abc&#34;</span><span class="o">)</span> <span class="s">&#34;abcde&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="s">&#34;abc&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;abc&#34;</span><span class="o">)</span> <span class="s">&#34;cde&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Failure</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">Error</span> <span class="k">in</span> <span class="n">Ln</span><span class="o">:</span> <span class="n">1</span> <span class="n">Col</span><span class="o">:</span> <span class="n">1</span>
</span></span><span class="line"><span class="cl"> <span class="n">cde</span>
</span></span><span class="line"><span class="cl"> <span class="o">^</span>
</span></span><span class="line"><span class="cl"> <span class="n">Expecting</span><span class="o">:</span> <span class="k">&#39;</span><span class="n">abc&#39;</span>
</span></span></code></pre></div><p>Okay, so we can create a parser to match a string, but how to create a parser that matches one of the four operators? Well, simple: we use the <a href="http://www.quanttec.com/fparsec/reference/primitives.html#members.:60::124::62:"><code>&lt;!&gt;</code></a> (read: or) parser:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;plus&#34;</span>          <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;minus&#34;</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;multiplied by&#34;</span>
</span></span></code></pre></div><p>Here, we use the <code>&lt;|&gt;</code> operator to specify that should its left hand parser fail to parse, it should try to parse its right hand parser. Let&rsquo;s send this function to the F# interactive to be able to test it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl">  <span class="n">Stopped</span> <span class="n">due</span> <span class="k">to</span> <span class="n">error</span>
</span></span><span class="line"><span class="cl"> <span class="nn">System</span><span class="p">.</span><span class="n">Exception</span><span class="o">:</span> <span class="n">Operation</span> <span class="n">could</span> <span class="ow">not</span> <span class="n">be</span> <span class="n">completed</span> <span class="n">due</span> <span class="k">to</span> <span class="n">earlier</span> <span class="n">error</span>
</span></span><span class="line"><span class="cl"> <span class="n">Value</span> <span class="n">restriction</span><span class="o">.</span> <span class="n">The</span> <span class="n">value</span> <span class="k">&#39;</span><span class="n">parseOperator&#39;</span> <span class="n">has</span> <span class="n">been</span> <span class="n">inferred</span> <span class="k">to</span> <span class="n">have</span> <span class="n">generic</span> <span class="k">type</span>
</span></span><span class="line"><span class="cl">     <span class="nc">val</span> <span class="n">parseOperator</span> <span class="o">:</span> <span class="n">Parser</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">,</span><span class="kt">obj</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"> <span class="n">Either</span> <span class="n">make</span> <span class="n">the</span> <span class="n">arguments</span> <span class="k">to</span> <span class="k">&#39;</span><span class="n">parseOperator&#39;</span> <span class="n">explicit</span> <span class="ow">or</span><span class="o">,</span> <span class="k">if</span> <span class="n">you</span> <span class="k">do</span> <span class="ow">not</span> <span class="n">intend</span> <span class="k">for</span> <span class="n">it</span> <span class="k">to</span> <span class="n">be</span> <span class="n">generic</span><span class="o">,</span> <span class="n">add</span> <span class="n">a</span> <span class="k">type</span> <span class="nc">annotation</span><span class="o">.</span>
</span></span></code></pre></div><p>Ouch, we get a very weird-looking error! What&rsquo;s going on? Well, don&rsquo;t worry, this is a <a href="http://www.quanttec.com/fparsec/tutorial.html#fs-value-restriction">common error</a> when using FParsec. The problem is that the <code>parseOperator</code> function is of type <code>Parser&lt;string,'_a&gt;</code>, but F# doesn&rsquo;t allow allow a generic type parameter here (<code>'_a</code> must be a concrete type). We can do two things to fix this:</p>
<ol>
<li>Add a type annotation.</li>
<li>Help the compiler infer the type.</li>
</ol>
<p>We&rsquo;ll go for the second option, by also sending a <code>run</code> call to the F# interactive window:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;plus&#34;</span>          <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;minus&#34;</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;multiplied by&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperator</span> <span class="s">&#34;plus&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="s">&#34;plus&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperator</span> <span class="s">&#34;divided by&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="s">&#34;divided by&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperator</span> <span class="s">&#34;div&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Failure</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">Error</span> <span class="k">in</span> <span class="n">Ln</span><span class="o">:</span> <span class="n">1</span> <span class="n">Col</span><span class="o">:</span> <span class="n">1</span>
</span></span><span class="line"><span class="cl"> <span class="n">div</span>
</span></span><span class="line"><span class="cl"> <span class="o">^</span>
</span></span><span class="line"><span class="cl"> <span class="n">Expecting</span><span class="o">:</span> <span class="k">&#39;</span><span class="n">divided</span> <span class="n">by&#39;</span><span class="o">,</span> <span class="k">&#39;</span><span class="n">minus&#39;</span><span class="o">,</span> <span class="k">&#39;</span><span class="n">multiplied</span> <span class="n">by&#39;</span> <span class="ow">or</span> <span class="k">&#39;</span><span class="n">plus&#39;</span>
</span></span></code></pre></div><p>As can be seen, the parser works as expected: it matches if the supplied input equals one of the four possible string values.</p>
<h4 id="parser-right-operatoroperand-combination">Parser: right operator/operand combination</h4>
<p>The parser for the right operator/operand combination has to do the following:</p>
<ol>
<li>Match the operator.</li>
<li>Match a single space.</li>
<li>Match the operand.</li>
<li>Return the operator/operand combination.</li>
</ol>
<p>Let&rsquo;s start with step 1, matching the operator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseOperator</span>
</span></span></code></pre></div><p>The next step is to match on a single space, which we can do using <code>pchar ' '</code>. So how do we combine these two parsers? We cannot use the <code>&lt;|&gt;</code> operator, as that is an <strong>or</strong> match, not an <strong>and</strong>. As it turns out, we can use several operators. To choose between these operators, we have to decide which parser results we want to retain. Obviously, the matched operator is important, but the single space is not. Therefore, we should use the parser operator that returns the first parser and ignores the second parser. For this purpose, we can use the <code>.&gt;&gt;</code> operator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">pchar</span> <span class="sc">&#39; &#39;</span>
</span></span></code></pre></div><p>The third and fourth step can be combined into a single call to the <code>.&gt;&gt;.</code> operator, which returns the results of both parsers:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">pchar</span> <span class="sc">&#39; &#39;</span> <span class="o">.&gt;&gt;.</span> <span class="n">parseOperand</span>
</span></span></code></pre></div><p>Let&rsquo;s test this parser:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperation</span> <span class="s">&#34;plus 7&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">),</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="o">(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span> <span class="n">7</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperation</span> <span class="s">&#34;minus 345&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">),</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="o">(</span><span class="s">&#34;minus&#34;</span><span class="o">,</span> <span class="n">345</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperation</span> <span class="s">&#34;minus plus&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">),</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Failure</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">Error</span> <span class="k">in</span> <span class="n">Ln</span><span class="o">:</span> <span class="n">1</span> <span class="n">Col</span><span class="o">:</span> <span class="n">7</span>
</span></span><span class="line"><span class="cl"> <span class="n">minus</span> <span class="n">plus</span>
</span></span><span class="line"><span class="cl">       <span class="o">^</span>
</span></span><span class="line"><span class="cl"> <span class="n">Expecting</span><span class="o">:</span> <span class="n">integer</span> <span class="n">number</span> <span class="o">(</span><span class="n">32</span><span class="o">-</span><span class="n">bit</span><span class="o">,</span> <span class="n">signed</span><span class="o">)</span>
</span></span></code></pre></div><p>You can see that the result of the parser is a tuple, with the first item being the result of the operator parser, and the second item the result of the operand parser.</p>
<h4 id="parser-list-of-right-operatoroperand-combinations">Parser: list of right operator/operand combinations</h4>
<p>Now that we have a parser for a right operator/operand combination, the next step is to create a parser that can match one or more of those combinations. Once again, there is an existing parser that can do that: the <a href="http://www.quanttec.com/fparsec/reference/primitives.html#members.many1">many1</a> parser. This parser function takes another parser, and matches one of more instances of the supplied parser argument.</p>
<p>Our initial attempt looked like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperations</span> <span class="o">=</span> <span class="n">many1</span> <span class="n">parseOperation</span>
</span></span></code></pre></div><p>Let&rsquo;s test this parser:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperations</span> <span class="s">&#34;plus 3 minus 4&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">)</span> <span class="kt">list</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="o">[(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">)]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperations</span> <span class="s">&#34;plus 7 multiplied by -2&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">)</span> <span class="kt">list</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="o">[(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span> <span class="n">7</span><span class="o">)]</span>
</span></span></code></pre></div><p>Hmmm, the parser does match successfully, but only the first combination. Why is that? Well, there is a very simple explanation for this. When parsing the <code>&quot;plus 3 minus 4&quot;</code> input, it finds a match (<code>&quot;plus 3&quot;</code>). It then tries to parse the remaining input: <code>&quot; minus 4&quot;</code>. Did you notice the leading space? That&rsquo;s what prevents the second combination from being matched, as the <code>parseOperations</code> parser expects the input to start with the operator, not a space.</p>
<p>To fix this, we can do two things:</p>
<ul>
<li>Modify the <code>parseOperation</code> to ignore leading and/or trailing spaces.</li>
<li>Use the <a href="http://www.quanttec.com/fparsec/reference/primitives.html#members.sepBy1"><code>sepBy1</code></a> parser, which matches a parser one or more times using another parser as a separator.</li>
</ul>
<p>We&rsquo;ll go with the second option:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperations</span> <span class="o">=</span> <span class="n">sepBy1</span> <span class="n">parseOperation</span> <span class="o">(</span><span class="n">pchar</span> <span class="sc">&#39; &#39;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperations</span> <span class="s">&#34;plus 3 minus 4&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">)</span> <span class="kt">list</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Success</span><span class="o">:</span> <span class="o">[(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">);</span> <span class="o">(</span><span class="s">&#34;minus&#34;</span><span class="o">,</span> <span class="n">4</span><span class="o">)]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperations</span> <span class="s">&#34;plus 7 multiplied by -2&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">)</span> <span class="kt">list</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Success</span><span class="o">:</span> <span class="o">[(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span> <span class="n">7</span><span class="o">);</span> <span class="o">(</span><span class="s">&#34;multiplied by&#34;</span><span class="o">,</span> <span class="o">-</span><span class="n">2</span><span class="o">)]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperations</span> <span class="s">&#34;multiplied by 6&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">)</span> <span class="kt">list</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Success</span><span class="o">:</span> <span class="o">[(</span><span class="s">&#34;multiplied by&#34;</span><span class="o">,</span> <span class="n">6</span><span class="o">)]</span>
</span></span></code></pre></div><p>The modified <code>parseOperations</code> parser now correctly parses a list of operator/operand tuples.</p>
<h4 id="parser-equation">Parser: equation</h4>
<p>The final step is to create the equation parser, which combines the left and right parsers and ignores the pre- and postfix strings:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span>
</span></span><span class="line"><span class="cl">     <span class="o">&gt;&gt;.</span> <span class="n">parseOperand</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">pchar</span> <span class="sc">&#39; &#39;</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">parseOperations</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span></code></pre></div><p>Let&rsquo;s test this parser:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseEquation</span> <span class="s">&#34;What is -12 divided by 2 divided by -3?&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">int32</span> <span class="o">*</span> <span class="o">(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">)</span> <span class="kt">list</span><span class="o">),</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Success</span><span class="o">:</span> <span class="o">(-</span><span class="n">12</span><span class="o">,</span> <span class="o">[(</span><span class="s">&#34;divided by&#34;</span><span class="o">,</span> <span class="n">2</span><span class="o">);</span> <span class="o">(</span><span class="s">&#34;divided by&#34;</span><span class="o">,</span> <span class="o">-</span><span class="n">3</span><span class="o">)])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseEquation</span> <span class="s">&#34;What is 17 minus 6 plus 3?&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;(</span><span class="kt">int32</span> <span class="o">*</span> <span class="o">(</span><span class="kt">string</span> <span class="o">*</span> <span class="kt">int32</span><span class="o">)</span> <span class="kt">list</span><span class="o">),</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Success</span><span class="o">:</span> <span class="o">(</span><span class="n">17</span><span class="o">,</span> <span class="o">[(</span><span class="s">&#34;minus&#34;</span><span class="o">,</span> <span class="n">6</span><span class="o">);</span> <span class="o">(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span> <span class="n">3</span><span class="o">)])</span>
</span></span></code></pre></div><h4 id="integrating-the-parser">Integrating the parser</h4>
<p>We can now use our FParsec-based equation parser in the <code>solve</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseToOption</span> <span class="n">parser</span> <span class="o">(</span><span class="n">input</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">run</span> <span class="n">parser</span> <span class="n">input</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Success</span><span class="o">(</span><span class="n">result</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span>   <span class="o">-&gt;</span> <span class="n">Some</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Failure</span><span class="o">(</span><span class="n">errorMsg</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseToOption</span> <span class="n">parseEquation</span> <span class="n">question</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Option</span><span class="p">.</span><span class="n">map</span> <span class="n">solveEquation</span>
</span></span></code></pre></div><p>Let&rsquo;s try to run our tests, and hurray, all tests pass! For reference, this is the full FParsec-based implementation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">open</span> <span class="nn">FParsec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperand</span> <span class="o">=</span> <span class="n">pint32</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;plus&#34;</span>          <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;minus&#34;</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;multiplied by&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">pchar</span> <span class="sc">&#39; &#39;</span> <span class="o">.&gt;&gt;.</span> <span class="n">parseOperand</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperations</span> <span class="o">=</span> <span class="n">sepBy1</span> <span class="n">parseOperation</span> <span class="o">(</span><span class="n">pchar</span> <span class="sc">&#39; &#39;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span>
</span></span><span class="line"><span class="cl">     <span class="o">&gt;&gt;.</span> <span class="n">parseOperand</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">pchar</span> <span class="sc">&#39; &#39;</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">parseOperations</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseToOption</span> <span class="n">parser</span> <span class="o">(</span><span class="n">input</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">run</span> <span class="n">parser</span> <span class="n">input</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Success</span><span class="o">(</span><span class="n">result</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span>   <span class="o">-&gt;</span> <span class="n">Some</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Failure</span><span class="o">(</span><span class="n">errorMsg</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">applyOperation</span> <span class="n">acc</span> <span class="o">(</span><span class="n">operation</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">operation</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;plus&#34;</span>          <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;minus&#34;</span>         <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="o">_</span>               <span class="o">-&gt;</span> <span class="n">acc</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solveEquation</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">applyOperation</span> <span class="n">left</span> <span class="n">operations</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseToOption</span> <span class="n">parseEquation</span> <span class="n">question</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Option</span><span class="p">.</span><span class="n">map</span> <span class="n">solveEquation</span>
</span></span></code></pre></div><p>The only slightly cryptic part of this implementation are the operators: <code>&lt;|&gt;</code>, <code>&gt;&gt;.</code>, <code>.&gt;&gt;</code> and <code>.&gt;&gt;.</code>. Someone new to FParsec will probably not intuitively understand what they do, but to me that&rsquo;s the only real hard part of this code. The rest is actually quite easy to read (and write).</p>
<h4 id="refactoring-using-an-abstract-syntax-tree">Refactoring: using an Abstract Syntax Tree</h4>
<p>At the moment, we parse an equation into very simple types: strings and integers. Ideally, one should define an <a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">Abstract Syntax Tree</a> (AST) to better describe the structure of our equation. As it turns out, this is a piece of cake in F#, so let&rsquo;s have a go!</p>
<p>First, we define types for each type of syntax node in our equation. This is a perfect use case for <a href="https://fsharpforfunandprofit.com/posts/discriminated-unions/">discriminated unions</a>. Let&rsquo;s start with an operand:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operand</span> <span class="o">=</span> <span class="n">Int</span> <span class="k">of</span> <span class="n">int</span>
</span></span></code></pre></div><p>Simple, an operand is a discriminated union with only a single case: <code>Int</code>, which contains an <code>int</code> value. Defining an operand this way allows us to easily add other types of operands later, like floating point numbers, booleans or variables.</p>
<p>Next, we define the type to represent the four supported operators:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span>
</span></span></code></pre></div><p>We then define an operation as an <code>Operator</code>/<code>Operand</code> tuple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operation</span> <span class="o">=</span> <span class="n">Operation</span> <span class="k">of</span> <span class="n">Operator</span> <span class="o">*</span> <span class="n">Operand</span>
</span></span></code></pre></div><p>Finally, we define the equation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Equation</span> <span class="o">=</span> <span class="n">Equation</span> <span class="k">of</span> <span class="n">Operand</span> <span class="o">*</span> <span class="n">Operation</span> <span class="kt">list</span>
</span></span></code></pre></div><p>Note that we haven&rsquo;t specified types for the leading and trailing strings, nor for the spaces, as they are not relevant to our problem.</p>
<p>The following step is to use these types in our implementation.</p>
<h5 id="use-ast-types-in-parseoperand">Use AST types in parseOperand</h5>
<p>Let&rsquo;s start with the <code>parseOperand</code> function, which should wrap the parsed <code>int</code> value in an <code>Operand</code> type. We can do this using the <a href="http://www.quanttec.com/fparsec/reference/primitives.html#interface.:124::62::62::B:"><code>|&gt;&gt;</code></a> (read: pipe) operator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperand</span> <span class="o">=</span> <span class="n">pint32</span> <span class="o">|&gt;&gt;</span> <span class="n">Int</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperand</span> <span class="s">&#34;54&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operand</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="n">Operand</span> <span class="n">54</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperand</span> <span class="s">&#34;123&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operand</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="n">Operand</span> <span class="n">123</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperand</span> <span class="s">&#34;ab&#34;</span><span class="o">;;</span>
</span></span><span class="line"><span class="cl"><span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operand</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Failure</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">Error</span> <span class="k">in</span> <span class="n">Ln</span><span class="o">:</span> <span class="n">1</span> <span class="n">Col</span><span class="o">:</span> <span class="n">1</span>
</span></span><span class="line"><span class="cl"> <span class="n">ab</span>
</span></span><span class="line"><span class="cl"> <span class="o">^</span>
</span></span><span class="line"><span class="cl"> <span class="n">Expecting</span><span class="o">:</span> <span class="n">integer</span> <span class="n">number</span> <span class="o">(</span><span class="n">32</span><span class="o">-</span><span class="n">bit</span><span class="o">,</span> <span class="n">signed</span><span class="o">)</span>
</span></span></code></pre></div><p>Perfect.</p>
<h5 id="use-ast-types-in-parseoperator">Use AST types in parseOperator</h5>
<p>Next up: the <code>parseOperator</code> parser:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;plus&#34;</span>         <span class="o">|&gt;&gt;</span> <span class="o">(</span><span class="k">fun</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">Plus</span><span class="o">))</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;minus&#34;</span>        <span class="o">|&gt;&gt;</span> <span class="o">(</span><span class="k">fun</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">Minus</span><span class="o">))</span>        <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;divided by&#34;</span>   <span class="o">|&gt;&gt;</span> <span class="o">(</span><span class="k">fun</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">DividedBy</span><span class="o">))</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;multiplied by&#34;</span><span class="o">|&gt;&gt;</span> <span class="o">(</span><span class="k">fun</span> <span class="o">_</span> <span class="o">-&gt;</span> <span class="n">MultipliedBy</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperator</span> <span class="s">&#34;plus&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operator</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="n">Plus</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperator</span> <span class="s">&#34;divided by&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operator</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="n">DividedBy</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperator</span> <span class="s">&#34;power&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operator</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Failure</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">Error</span> <span class="k">in</span> <span class="n">Ln</span><span class="o">:</span> <span class="n">1</span> <span class="n">Col</span><span class="o">:</span> <span class="n">1</span>
</span></span><span class="line"><span class="cl"> <span class="n">power</span>
</span></span><span class="line"><span class="cl"> <span class="o">^</span>
</span></span><span class="line"><span class="cl"> <span class="n">Expecting</span><span class="o">:</span> <span class="k">&#39;</span><span class="n">divided</span> <span class="n">by&#39;</span><span class="o">,</span> <span class="k">&#39;</span><span class="n">minus&#39;</span><span class="o">,</span> <span class="k">&#39;</span><span class="n">multiplied</span> <span class="n">by&#39;</span> <span class="ow">or</span> <span class="k">&#39;</span><span class="n">plus&#39;</span>
</span></span></code></pre></div><p>Everything works, but the pipe operator usage looks a bit odd. This is due to the pipe operator expecting a <code>string -&gt; 'a</code> function as its argument. However, we&rsquo;re not interested in the matched <code>string</code> value, so we ignore it and return the appropriate operator. As it turns out, the <a href="http://www.quanttec.com/fparsec/reference/primitives.html#members.:62::62::37:"><code>&gt;&gt;%</code></a> operator simplifies this by not expecting a <code>string</code> parameter:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;plus&#34;</span>          <span class="o">&gt;&gt;%</span> <span class="n">Plus</span><span class="o">)</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;minus&#34;</span>         <span class="o">&gt;&gt;%</span> <span class="n">Minus</span><span class="o">)</span>        <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">&gt;&gt;%</span> <span class="n">DividedBy</span><span class="o">)</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="n">pstring</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">&gt;&gt;%</span> <span class="n">MultipliedBy</span><span class="o">)</span>
</span></span></code></pre></div><p>Much better, but there is an even better parser: <a href="http://www.quanttec.com/fparsec/reference/charparsers.html#members.stringReturn"><code>stringReturn</code></a>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;plus&#34;</span>          <span class="n">Plus</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;minus&#34;</span>         <span class="n">Minus</span>        <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;divided by&#34;</span>    <span class="n">DividedBy</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;multiplied by&#34;</span> <span class="n">MultipliedBy</span>
</span></span></code></pre></div><p>Excellent! Clean, simple and fully functional!</p>
<h5 id="use-ast-types-in-parseoperation">Use AST types in parseOperation</h5>
<p>With what we know now, modifying the <code>parseOperation</code> to return an <code>Operation</code> type is simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">pchar</span> <span class="sc">&#39; &#39;</span> <span class="o">.&gt;&gt;.</span> <span class="n">parseOperand</span> <span class="o">|&gt;&gt;</span> <span class="n">Operation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperation</span> <span class="s">&#34;plus 1&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operation</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span> <span class="n">Success</span><span class="o">:</span> <span class="n">Operation</span> <span class="o">(</span><span class="n">Plus</span><span class="o">,</span><span class="n">Operand</span> <span class="n">1</span><span class="o">)</span>
</span></span></code></pre></div><h5 id="use-ast-types-in-parseoperations">Use AST types in parseOperations</h5>
<p>The <code>parseOperations</code> function already returns the correct type (<code>Operation list</code>), so we don&rsquo;t need to modify it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseOperations</span> <span class="s">&#34;plus 4 minus 6&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Operation</span> <span class="kt">list</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Success</span><span class="o">:</span> <span class="o">[</span><span class="n">Operation</span> <span class="o">(</span><span class="n">Plus</span><span class="o">,</span><span class="n">Operand</span> <span class="n">4</span><span class="o">);</span> <span class="n">Operation</span> <span class="o">(</span><span class="n">Minus</span><span class="o">,</span><span class="n">Operand</span> <span class="n">6</span><span class="o">)]</span>
</span></span></code></pre></div><h5 id="use-ast-types-in-parseequation">Use AST types in parseEquation</h5>
<p>For the <code>parseEquation</code>, we can just pipe the result into the <code>Equation</code> type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span>
</span></span><span class="line"><span class="cl">     <span class="o">&gt;&gt;.</span> <span class="n">parseOperand</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">pchar</span> <span class="sc">&#39; &#39;</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">parseOperations</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;&gt;</span> <span class="n">Equation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">run</span> <span class="n">parseEquation</span> <span class="s">&#34;What is -12 divided by 2 divided by -3?&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="k">val</span> <span class="n">it</span> <span class="o">:</span> <span class="n">ParserResult</span><span class="o">&lt;</span><span class="n">Equation</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">   <span class="n">Success</span><span class="o">:</span> <span class="n">Equation</span>
</span></span><span class="line"><span class="cl">   <span class="o">(</span><span class="n">Operand</span> <span class="o">-</span><span class="n">12</span><span class="o">,</span>
</span></span><span class="line"><span class="cl">    <span class="o">[</span><span class="n">Operation</span> <span class="o">(</span><span class="n">DividedBy</span><span class="o">,</span><span class="n">Operand</span> <span class="n">2</span><span class="o">);</span> <span class="n">Operation</span> <span class="o">(</span><span class="n">DividedBy</span><span class="o">,</span><span class="n">Operand</span> <span class="o">-</span><span class="n">3</span><span class="o">)])</span>
</span></span></code></pre></div><p>As we now use the <code>pchar ' '</code> parser in several places, we should really define a separate parser for it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">space</span> <span class="o">=</span> <span class="n">pchar</span> <span class="sc">&#39; &#39;</span>
</span></span></code></pre></div><h5 id="use-ast-types-when-solving-the-solution">Use AST types when solving the solution</h5>
<p>The final step is to use the AST types when we solve the equation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">applyOperation</span> <span class="n">acc</span> <span class="o">(</span><span class="n">Operation</span> <span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">Operand</span><span class="o">(</span><span class="n">right</span><span class="o">)))</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">operator</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span>         <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span>        <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span> <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span>    <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="o">_</span>            <span class="o">-&gt;</span> <span class="n">acc</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solveEquation</span> <span class="o">(</span><span class="n">Equation</span> <span class="o">(</span><span class="n">Operand</span><span class="o">(</span><span class="n">left</span><span class="o">),</span> <span class="n">operations</span><span class="o">))</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">applyOperation</span> <span class="n">left</span> <span class="n">operations</span>
</span></span></code></pre></div><p>To simplify our code, we pattern-match directly in our parameters. At this point, we run our tests and they all pass! Hurray.</p>
<p>As we now use a discriminated union to represent an operator, the compiler is able to inform us that the catch-all clause will never be reached. We can thus safely remove it. The complete code then becomes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">open</span> <span class="nn">FParsec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operand</span> <span class="o">=</span> <span class="n">Operand</span> <span class="k">of</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Operation</span> <span class="o">=</span> <span class="n">Operation</span> <span class="k">of</span> <span class="n">Operator</span> <span class="o">*</span> <span class="n">Operand</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Equation</span> <span class="o">=</span> <span class="n">Equation</span> <span class="k">of</span> <span class="n">Operand</span> <span class="o">*</span> <span class="n">Operation</span> <span class="kt">list</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">space</span> <span class="o">=</span> <span class="n">pchar</span> <span class="sc">&#39; &#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperand</span> <span class="o">=</span> <span class="n">pint32</span> <span class="o">|&gt;&gt;</span> <span class="n">Operand</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;plus&#34;</span>          <span class="n">Plus</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;minus&#34;</span>         <span class="n">Minus</span>        <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;divided by&#34;</span>    <span class="n">DividedBy</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;multiplied by&#34;</span> <span class="n">MultipliedBy</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">space</span> <span class="o">.&gt;&gt;.</span> <span class="n">parseOperand</span> <span class="o">|&gt;&gt;</span> <span class="n">Operation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperations</span> <span class="o">=</span> <span class="n">sepBy1</span> <span class="n">parseOperation</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span>
</span></span><span class="line"><span class="cl">     <span class="o">&gt;&gt;.</span> <span class="n">parseOperand</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">parseOperations</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;&gt;</span> <span class="n">Equation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseToOption</span> <span class="n">parser</span> <span class="o">(</span><span class="n">input</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">run</span> <span class="n">parser</span> <span class="n">input</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Success</span><span class="o">(</span><span class="n">result</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span>   <span class="o">-&gt;</span> <span class="n">Some</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Failure</span><span class="o">(</span><span class="n">errorMsg</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">applyOperation</span> <span class="n">acc</span> <span class="o">(</span><span class="n">Operation</span> <span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">Operand</span><span class="o">(</span><span class="n">right</span><span class="o">)))</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">operator</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span>         <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">+</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span>        <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">-</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span> <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">*</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span>    <span class="o">-&gt;</span> <span class="n">acc</span> <span class="o">/</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solveEquation</span> <span class="o">(</span><span class="n">Equation</span> <span class="o">(</span><span class="n">Operand</span><span class="o">(</span><span class="n">left</span><span class="o">),</span> <span class="n">operations</span><span class="o">))</span> <span class="o">=</span> <span class="nn">Seq</span><span class="p">.</span><span class="n">fold</span> <span class="n">applyOperation</span> <span class="n">left</span> <span class="n">operations</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseToOption</span> <span class="n">parseEquation</span> <span class="n">question</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Option</span><span class="p">.</span><span class="n">map</span> <span class="n">solveEquation</span>
</span></span></code></pre></div><p>To me, what&rsquo;s remarkable is that we defined and implemented an AST for our equation with only very code and hardly any effort.</p>
<h4 id="refactoring-using-a-different-ast">Refactoring: using a different AST</h4>
<p>Our previous AST didn&rsquo;t look too bad, but it might not be the best way to describe an equation. Consider the expression <code>17 minus 6 plus 3</code>. At the moment, our corresponding AST looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">Equation</span><span class="o">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">Operand</span> <span class="n">17</span> <span class="o">*</span>
</span></span><span class="line"><span class="cl">        <span class="o">[</span> <span class="n">Operation</span><span class="o">(</span><span class="n">Minus</span><span class="o">,</span> <span class="n">Operand</span> <span class="n">6</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">          <span class="n">Operation</span><span class="o">(</span><span class="n">Plus</span><span class="o">,</span> <span class="n">Operand</span> <span class="n">3</span><span class="o">)</span> <span class="o">])</span>
</span></span></code></pre></div><p>What this AST fails to represent, is that our operators always operate on two operands: a left and right part. What we would like is <code>17 minus 6</code> to be defined as <code>Minus (Operand 17, Operand 6)</code>. The multiple operations in <code>17 minus 6 plus 3</code> should be defined as: <code>Plus (Minus (Operand 17, Operand 6), Operand 3)</code>. Note that this is an <em>inside-out</em> representation of an equation, the left-most part of the equation is the innermost part of the AST. Solving this AST is thus a recursive, <em>inside-out</em> algorithm:</p>
<ol>
<li><code>Plus (Minus (Operand 17, Operand 6), Operand 3)</code>,</li>
<li><code>Plus (Operand 11, Operand 3)</code>,</li>
<li><code>Operand 14</code></li>
</ol>
<p>As it turns out, defining this AST in our code is fantastically simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Expression</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Operand</span> <span class="k">of</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span></code></pre></div><h5 id="use-updated-ast-in-parseoperand">Use updated AST in parseOperand</h5>
<p>The <code>parseOperand</code> function does not need to be changed. The only difference is that its returned value (<code>Operand</code>) is now part of the <code>Expression</code> discriminated union.</p>
<h5 id="use-updated-ast-in-parseoperator">Use updated AST in parseOperator</h5>
<p>There is also no need to modify the <code>parseOperator</code> function.</p>
<h5 id="use-updated-ast-in-parseoperation-and-parseoperations">Use updated AST in parseOperation and parseOperations</h5>
<p>The <code>parseOperation</code> is where things start getting interesting. Previously, an operation was just an operator and an operand, but the operand can now also be another operation. Our initial attempt might look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseExpression</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">sepBy1</span> <span class="o">(</span><span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">space</span> <span class="o">.&gt;&gt;.</span> <span class="n">parseExpression</span><span class="o">)</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;&gt;</span> <span class="n">TODO</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseExpression</span> <span class="o">=</span> <span class="n">parseOperand</span> <span class="o">&lt;|&gt;</span> <span class="n">parseOperation</span>
</span></span></code></pre></div><p>In this modified <code>parseOperation</code> function, we use the new <code>parseExpression</code> parser to parse the left and right hand sides. This new parser then matches on either an operand, or an operation. Unfortunately, we have now introduced a cycle: <code>parseOperation</code> must know of <code>parseExpression</code>, but also the other way around. How can we solve this? Enter the <a href="http://www.quanttec.com/fparsec/reference/primitives.html#members.createParserForwardedToRef"><code>createParserForwardedToRef</code></a> function.</p>
<p>When you call <code>createParserForwardedToRef</code>, it returns two things:</p>
<ol>
<li>A parser <code>p</code> which type will be inferred depending on its usage.</li>
<li>A parser reference cell <code>pRef</code>, to which parser <code>p</code> forwards all calls.</li>
</ol>
<p>With this function, we can start using the parser <code>p</code>, but defer binding its actual implementation until after all required parsers have been defined. Our modified code looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">expr</span><span class="o">,</span> <span class="n">exprImpl</span> <span class="o">=</span> <span class="n">createParserForwardedToRef</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">expr</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">sepBy1</span> <span class="o">(</span><span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">space</span> <span class="o">.&gt;&gt;.</span> <span class="n">expr</span><span class="o">)</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;&gt;</span> <span class="n">TODO</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseExpression</span> <span class="o">=</span> <span class="n">parseOperand</span> <span class="o">&lt;|&gt;</span> <span class="n">parseOperation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">exprImpl</span> <span class="o">:=</span> <span class="n">parseExpression</span>
</span></span></code></pre></div><p>You can see that we use the <code>createParserForwardedToRef</code> to create a parser and its reference cell. We then use this parser in our <code>parseOperation</code> function, and later bind the <code>parseExpression</code> function to the reference cell&rsquo;s contents. The end result is precisely what we wanted to achieve.</p>
<p>We now have to decide how to process the parsed operation using the <code>|&gt;&gt;</code> operator. If you are starting to become more proficient at reading FParsec&rsquo;s operators, you will have guessed that we have to process a tuple. The first item of this tuple is the left expression, and the second item is the list of operator/right expression combinations. The first step is thus:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="o">|&gt;&gt;</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">TODO</span><span class="o">)</span>
</span></span></code></pre></div><p>So how can we merge these two parts into a single expression? Well, we can use a regular fold:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="nn">List</span><span class="p">.</span><span class="n">fold</span> <span class="o">(</span><span class="k">fun</span> <span class="n">acc</span> <span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">operator</span> <span class="o">(</span><span class="n">acc</span><span class="o">,</span> <span class="n">right</span><span class="o">))</span> <span class="n">left</span> <span class="n">operations</span>
</span></span></code></pre></div><p>The initial state is the left expression. We then process each operator in sequence, wrapping the previous expression in the new operator. The end result will be an <code>Expression</code> that is structured <em>inside-out</em>, precisely what we want.</p>
<p>It&rsquo;s probably best to extract the expression building code into its own function. This gives us the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">buildExpression</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">List</span><span class="p">.</span><span class="n">fold</span> <span class="o">(</span><span class="k">fun</span> <span class="n">acc</span> <span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">operator</span> <span class="o">(</span><span class="n">acc</span><span class="o">,</span> <span class="n">right</span><span class="o">))</span> <span class="n">left</span> <span class="n">operations</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">expr</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span>  <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">sepBy1</span> <span class="o">(</span><span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">space</span> <span class="o">.&gt;&gt;.</span> <span class="n">expr</span><span class="o">)</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;&gt;</span> <span class="n">buildExpression</span>
</span></span></code></pre></div><h5 id="use-updated-ast-in-parseequation">Use updated AST in parseEquation</h5>
<p>The <code>parseEquation</code> function is very simple, it just uses the <code>parseOperation</code> parser to parse the equation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span> <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span> <span class="o">&gt;&gt;.</span> <span class="n">parseOperation</span> <span class="o">.&gt;&gt;</span> <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span></code></pre></div><h5 id="use-updated-ast-in-solveexpression">Use updated AST in solveExpression</h5>
<p>The benefit of our modified AST becomes apparent when we work on our equation solving code. As an operator in our updated AST now knows about its operands, solving an expression is a simple, recursive function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">rec</span> <span class="n">solveExpression</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">function</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Operand</span> <span class="n">x</span> <span class="o">-&gt;</span> <span class="n">x</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>         <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">+</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>        <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">-</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>    <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">/</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">*</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span></code></pre></div><p>I think this function is very readable and elegant.</p>
<h5 id="use-updated-ast-in-solve">Use updated AST in solve</h5>
<p>The solve function does not need any modification, so we can now run all tests, which all pass!</p>
<p>This is the complete, updated implementation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">open</span> <span class="nn">FParsec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">type</span> <span class="nc">Expression</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Operand</span> <span class="k">of</span> <span class="n">int</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span> <span class="k">of</span> <span class="n">Expression</span> <span class="o">*</span> <span class="n">Expression</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">buildExpression</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="nn">List</span><span class="p">.</span><span class="n">fold</span> <span class="o">(</span><span class="k">fun</span> <span class="n">acc</span> <span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">operator</span> <span class="o">(</span><span class="n">acc</span><span class="o">,</span> <span class="n">right</span><span class="o">))</span> <span class="n">left</span> <span class="n">operations</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// We create a parser forwarder in order to allow us to
</span></span></span><span class="line"><span class="cl"><span class="c1">// define a recursive parser later on
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">let</span> <span class="nv">expr</span><span class="o">,</span> <span class="n">exprImpl</span> <span class="o">=</span> <span class="n">createParserForwardedToRef</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">space</span> <span class="o">=</span> <span class="n">pchar</span> <span class="sc">&#39; &#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperand</span> <span class="o">=</span> <span class="n">pint32</span> <span class="o">|&gt;&gt;</span> <span class="n">Operand</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperator</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;plus&#34;</span>          <span class="n">Plus</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;minus&#34;</span>         <span class="n">Minus</span>        <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;divided by&#34;</span>    <span class="n">DividedBy</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">stringReturn</span> <span class="s">&#34;multiplied by&#34;</span> <span class="n">MultipliedBy</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseOperation</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">expr</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">.&gt;&gt;.</span> <span class="n">sepBy1</span> <span class="o">(</span><span class="n">parseOperator</span> <span class="o">.&gt;&gt;</span> <span class="n">space</span> <span class="o">.&gt;&gt;.</span> <span class="n">expr</span><span class="o">)</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;&gt;</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">operations</span><span class="o">)</span> <span class="o">-&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nn">List</span><span class="p">.</span><span class="n">fold</span> <span class="o">(</span><span class="k">fun</span> <span class="n">acc</span> <span class="o">(</span><span class="n">operator</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">operator</span> <span class="o">(</span><span class="n">acc</span><span class="o">,</span> <span class="n">right</span><span class="o">))</span> <span class="n">left</span> <span class="n">operations</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseExpression</span> <span class="o">=</span> <span class="n">parseOperand</span> <span class="o">&lt;|&gt;</span> <span class="n">parseOperation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">exprImpl</span> <span class="o">:=</span> <span class="n">parseExpression</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span>  <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span> <span class="o">&gt;&gt;.</span> <span class="n">parseOperation</span> <span class="o">.&gt;&gt;</span> <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseToOption</span> <span class="n">parser</span> <span class="o">(</span><span class="n">input</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">run</span> <span class="n">parser</span> <span class="n">input</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Success</span><span class="o">(</span><span class="n">result</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span>   <span class="o">-&gt;</span> <span class="n">Some</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Failure</span><span class="o">(</span><span class="n">errorMsg</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">rec</span> <span class="n">solveExpression</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">function</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Operand</span> <span class="n">x</span> <span class="o">-&gt;</span> <span class="n">x</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Plus</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">+</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Minus</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">-</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">DividedBy</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">/</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">MultipliedBy</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">*</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">parseToOption</span> <span class="n">parseEquation</span> <span class="n">question</span>
</span></span><span class="line"><span class="cl">    <span class="o">|&gt;</span> <span class="nn">Option</span><span class="p">.</span><span class="n">map</span> <span class="n">solveExpression</span>
</span></span></code></pre></div><p>I think that this AST implementation is more elegant than our previous one, and also leads to more readable code.</p>
<h2 id="bonus-implementations-in-scala-and-haskell">Bonus: implementations in Scala and Haskell</h2>
<p>One of the great things about Exercism is that almost all exercises are availabe in more than one language. This also goes for the wordy exercise. We will list our Scala and Haskell implementations of the wordy exercise to allow you to compare them to our F# implementation.</p>
<h3 id="bonus-scala-implementation">Bonus: Scala implementation</h3>
<p>First up: our Scala implementation of the wordy problem:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scala" data-lang="scala"><span class="line"><span class="cl"><span class="k">import</span> <span class="nn">scala.util.parsing.combinator._</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">sealed</span> <span class="k">trait</span> <span class="nc">Expression</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">solve</span><span class="k">:</span> <span class="kt">Int</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">Operand</span><span class="o">(</span><span class="n">n</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Expression</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">solve</span> <span class="k">=</span> <span class="n">n</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">Sum</span><span class="o">(</span><span class="n">e1</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">,</span> <span class="n">e2</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Expression</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">solve</span> <span class="k">=</span> <span class="n">e1</span><span class="o">.</span><span class="n">solve</span> <span class="o">+</span> <span class="n">e2</span><span class="o">.</span><span class="n">solve</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">Subtract</span><span class="o">(</span><span class="n">e1</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">,</span> <span class="n">e2</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Expression</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">solve</span> <span class="k">=</span> <span class="n">e1</span><span class="o">.</span><span class="n">solve</span> <span class="o">-</span> <span class="n">e2</span><span class="o">.</span><span class="n">solve</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">Multiply</span><span class="o">(</span><span class="n">e1</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">,</span> <span class="n">e2</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Expression</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">solve</span> <span class="k">=</span> <span class="n">e1</span><span class="o">.</span><span class="n">solve</span> <span class="o">*</span> <span class="n">e2</span><span class="o">.</span><span class="n">solve</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="k">case</span> <span class="k">class</span> <span class="nc">Divide</span><span class="o">(</span><span class="n">e1</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">,</span> <span class="n">e2</span><span class="k">:</span> <span class="kt">Expression</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Expression</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">solve</span> <span class="k">=</span> <span class="n">e1</span><span class="o">.</span><span class="n">solve</span> <span class="o">/</span> <span class="n">e2</span><span class="o">.</span><span class="n">solve</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">object</span> <span class="nc">WordProblem</span> <span class="k">extends</span> <span class="nc">RegexParsers</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">operand</span><span class="k">:</span> <span class="kt">Parser</span><span class="o">[</span><span class="kt">Operand</span><span class="o">]</span> <span class="k">=</span> <span class="s">&#34;&#34;&#34;(0|-?[1-9]\d*)&#34;&#34;&#34;</span><span class="o">.</span><span class="n">r</span> <span class="o">^^</span> <span class="o">{</span> <span class="n">str</span> <span class="k">=&gt;</span> <span class="nc">Operand</span><span class="o">(</span><span class="n">str</span><span class="o">.</span><span class="n">toInt</span><span class="o">)</span> <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">operator</span><span class="k">:</span> <span class="kt">Parser</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span class="s">&#34;plus&#34;</span> <span class="o">|</span> <span class="s">&#34;minus&#34;</span> <span class="o">|</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">|</span> <span class="s">&#34;divided by&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">operation</span><span class="k">:</span> <span class="kt">Parser</span><span class="o">[</span><span class="kt">Expression</span><span class="o">]</span> <span class="k">=</span>
</span></span><span class="line"><span class="cl">    <span class="n">expression</span> <span class="o">~</span> <span class="o">(</span><span class="n">operator</span> <span class="o">~</span> <span class="n">expression</span><span class="o">).*</span> <span class="o">^^</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="n">expr</span> <span class="o">~</span> <span class="n">list</span> <span class="k">=&gt;</span> <span class="n">list</span><span class="o">.</span><span class="n">foldLeft</span><span class="o">(</span><span class="n">expr</span><span class="o">)</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="s">&#34;plus&#34;</span> <span class="o">~</span> <span class="n">right</span><span class="o">)</span>          <span class="k">=&gt;</span> <span class="nc">Sum</span><span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="s">&#34;minus&#34;</span> <span class="o">~</span> <span class="n">right</span><span class="o">)</span>         <span class="k">=&gt;</span> <span class="nc">Subtract</span><span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">~</span> <span class="n">right</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="nc">Multiply</span><span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="s">&#34;divided by&#34;</span> <span class="o">~</span> <span class="n">right</span><span class="o">)</span>    <span class="k">=&gt;</span> <span class="nc">Divide</span><span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">      <span class="o">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">expression</span><span class="k">:</span> <span class="kt">Parser</span><span class="o">[</span><span class="kt">Expression</span><span class="o">]</span> <span class="k">=</span> <span class="n">operand</span> <span class="o">|</span> <span class="n">operation</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">equation</span><span class="k">:</span> <span class="kt">Parser</span><span class="o">[</span><span class="kt">Expression</span><span class="o">]</span> <span class="k">=</span> <span class="s">&#34;What is &#34;</span> <span class="o">~&gt;</span> <span class="n">operation</span> <span class="o">&lt;~</span> <span class="s">&#34;?&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">input</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span><span class="k">:</span> <span class="kt">Option</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">parse</span><span class="o">(</span><span class="n">equation</span><span class="o">,</span> <span class="n">input</span><span class="o">)</span> <span class="k">match</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="nc">Success</span><span class="o">(</span><span class="n">expression</span><span class="o">,</span> <span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="nc">Some</span><span class="o">(</span><span class="n">expression</span><span class="o">.</span><span class="n">solve</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">      <span class="k">case</span> <span class="k">_</span> <span class="k">=&gt;</span> <span class="nc">None</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><p>This implementation is actually quite similar to our F#, which is in large part due to the fact that we use Scala&rsquo;s parser combinator library. There are two main differences:</p>
<ol>
<li>The case classes are Scala&rsquo;s implementation of discriminated unions. As such, the solution is more object-oriented.</li>
<li>The parser combinator library&rsquo;s operators are different (<code>^^</code> instead of <code>|&gt;&gt;</code>).</li>
</ol>
<h3 id="bonus-haskell-implementation">Bonus: Haskell implementation</h3>
<p>For Haskell, we use the <code>Attoparsec</code> parser combinator library:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-haskell" data-lang="haskell"><span class="line"><span class="cl"><span class="cm">{-# LANGUAGE OverloadedStrings #-}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">module</span> <span class="nn">WordProblem</span> <span class="p">(</span><span class="nf">answer</span><span class="p">)</span> <span class="kr">where</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nn">Control.Applicative</span> <span class="p">((</span><span class="o">&lt;|&gt;</span><span class="p">),</span> <span class="p">(</span><span class="o">&lt;$&gt;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nn">Data.Attoparsec.Text</span> <span class="p">(</span><span class="kt">Parser</span><span class="p">,</span> <span class="nf">parse</span><span class="p">,</span> <span class="nf">maybeResult</span><span class="p">,</span> <span class="nf">space</span><span class="p">,</span> <span class="nf">decimal</span><span class="p">,</span> <span class="nf">signed</span><span class="p">,</span> <span class="nf">string</span><span class="p">,</span> <span class="nf">sepBy1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nn">Data.Text</span> <span class="p">(</span><span class="nf">pack</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">data</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="ow">=</span> <span class="kt">Operand</span> <span class="kt">Int</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="kt">Plus</span> <span class="kt">Expression</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="kt">Minus</span> <span class="kt">Expression</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="kt">DividedBy</span> <span class="kt">Expression</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="kt">MultipliedBy</span> <span class="kt">Expression</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl">    <span class="kr">deriving</span> <span class="p">(</span><span class="kt">Show</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">buildExpression</span> <span class="ow">::</span> <span class="kt">Expression</span> <span class="ow">-&gt;</span> <span class="p">[(</span><span class="kt">Expression</span> <span class="ow">-&gt;</span> <span class="kt">Expression</span> <span class="ow">-&gt;</span> <span class="kt">Expression</span><span class="p">,</span> <span class="kt">Expression</span><span class="p">)]</span> <span class="ow">-&gt;</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl"><span class="nf">buildExpression</span> <span class="ow">=</span> <span class="n">foldl</span> <span class="p">(</span><span class="nf">\</span><span class="n">acc</span> <span class="p">(</span><span class="n">operator</span><span class="p">,</span> <span class="n">right</span><span class="p">)</span> <span class="ow">-&gt;</span> <span class="n">operator</span> <span class="n">acc</span> <span class="n">right</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">operandParser</span> <span class="ow">::</span> <span class="kt">Parser</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl"><span class="nf">operandParser</span> <span class="ow">=</span> <span class="kt">Operand</span> <span class="o">&lt;$&gt;</span> <span class="n">signed</span> <span class="n">decimal</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">operatorParser</span> <span class="ow">::</span> <span class="kt">Parser</span> <span class="p">(</span><span class="kt">Expression</span> <span class="ow">-&gt;</span> <span class="kt">Expression</span> <span class="ow">-&gt;</span> <span class="kt">Expression</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">operatorParser</span> <span class="ow">=</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="n">string</span> <span class="s">&#34;plus&#34;</span>          <span class="o">&gt;&gt;</span> <span class="n">return</span> <span class="kt">Plus</span><span class="p">)</span>         <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="n">string</span> <span class="s">&#34;minus&#34;</span>         <span class="o">&gt;&gt;</span> <span class="n">return</span> <span class="kt">Minus</span><span class="p">)</span>        <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="n">string</span> <span class="s">&#34;divided by&#34;</span>    <span class="o">&gt;&gt;</span> <span class="n">return</span> <span class="kt">DividedBy</span><span class="p">)</span>    <span class="o">&lt;|&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="n">string</span> <span class="s">&#34;multiplied by&#34;</span> <span class="o">&gt;&gt;</span> <span class="n">return</span> <span class="kt">MultipliedBy</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">operationParser</span> <span class="ow">::</span> <span class="kt">Parser</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl"><span class="nf">operationParser</span> <span class="ow">=</span> <span class="kr">do</span>
</span></span><span class="line"><span class="cl">    <span class="n">left</span>       <span class="ow">&lt;-</span> <span class="p">(</span><span class="n">operandParser</span> <span class="o">&lt;|&gt;</span> <span class="n">operationParser</span><span class="p">)</span> <span class="o">&lt;*</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="n">operations</span> <span class="ow">&lt;-</span> <span class="n">sepBy1</span> <span class="p">(</span><span class="kr">do</span>
</span></span><span class="line"><span class="cl">        <span class="n">operator</span>  <span class="ow">&lt;-</span> <span class="n">operatorParser</span> <span class="o">&lt;*</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">        <span class="n">operation</span> <span class="ow">&lt;-</span> <span class="n">operandParser</span> <span class="o">&lt;|&gt;</span> <span class="n">operationParser</span>
</span></span><span class="line"><span class="cl">        <span class="n">return</span> <span class="p">(</span><span class="n">operator</span><span class="p">,</span> <span class="n">operation</span><span class="p">))</span> <span class="n">space</span>
</span></span><span class="line"><span class="cl">    <span class="n">return</span> <span class="p">(</span><span class="n">buildExpression</span> <span class="n">left</span> <span class="n">operations</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">equationParser</span> <span class="ow">::</span> <span class="kt">Parser</span> <span class="kt">Expression</span>
</span></span><span class="line"><span class="cl"><span class="nf">equationParser</span> <span class="ow">=</span> <span class="n">string</span> <span class="s">&#34;What is &#34;</span> <span class="o">*&gt;</span> <span class="n">operationParser</span> <span class="o">&lt;*</span> <span class="n">string</span> <span class="s">&#34;?&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">solveExpression</span> <span class="ow">::</span> <span class="kt">Expression</span> <span class="ow">-&gt;</span> <span class="kt">Int</span>
</span></span><span class="line"><span class="cl"><span class="nf">solveExpression</span> <span class="p">(</span><span class="kt">Operand</span> <span class="n">x</span><span class="p">)</span> <span class="ow">=</span> <span class="n">x</span>
</span></span><span class="line"><span class="cl"><span class="nf">solveExpression</span> <span class="p">(</span><span class="kt">Plus</span> <span class="n">left</span> <span class="n">right</span><span class="p">)</span> <span class="ow">=</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">+</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl"><span class="nf">solveExpression</span> <span class="p">(</span><span class="kt">Minus</span> <span class="n">left</span> <span class="n">right</span><span class="p">)</span> <span class="ow">=</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">-</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl"><span class="nf">solveExpression</span> <span class="p">(</span><span class="kt">DividedBy</span> <span class="n">left</span> <span class="n">right</span><span class="p">)</span> <span class="ow">=</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="p">`</span><span class="n">div</span><span class="p">`</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl"><span class="nf">solveExpression</span> <span class="p">(</span><span class="kt">MultipliedBy</span> <span class="n">left</span> <span class="n">right</span><span class="p">)</span> <span class="ow">=</span> <span class="n">solveExpression</span> <span class="n">left</span> <span class="o">*</span> <span class="n">solveExpression</span> <span class="n">right</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">answer</span> <span class="ow">::</span> <span class="kt">String</span> <span class="ow">-&gt;</span> <span class="kt">Maybe</span> <span class="kt">Int</span>
</span></span><span class="line"><span class="cl"><span class="nf">answer</span> <span class="ow">=</span> <span class="n">fmap</span> <span class="n">solveExpression</span> <span class="o">.</span> <span class="n">maybeResult</span> <span class="o">.</span> <span class="n">parse</span> <span class="n">equationParser</span> <span class="o">.</span> <span class="n">pack</span>
</span></span></code></pre></div><p>Once again, there are some syntactic differences and some different operators, but the gist of it remains the same. The only significant difference is that we use <a href="http://learnyouahaskell.com/a-fistful-of-monads#do-notation">do notation</a>, a feature similar to Scala&rsquo;s <a href="http://docs.scala-lang.org/tutorials/FAQ/yield">for comprehensions</a> and F#&rsquo;s <a href="http://fsharpforfunandprofit.com/posts/computation-expressions-intro/">computation expressions</a>.</p>
<h2 id="bonus-operator-precedence">Bonus: operator precedence</h2>
<p>As a final bonus, we&rsquo;ll look at what we would have to do if the wordy problem <em>did</em> respect the <a href="https://en.wikipedia.org/wiki/Order_of_operations">standard operator precedence rules</a>. You might remember that we talked about this when we discussed test 13, which required us to solve <code>&quot;What is -3 plus 7 multiplied by -2?&quot;</code>. Due to the exercise ignoring the operator precedence, the result was <code>(-3 + 7) * -2</code> = <code>-8</code>. However, if we would use the standard convention that multiplication has a higher precedence than addition, the result should be <code>-3 + (7 * -2)</code> = <code>-17</code>. Let&rsquo;s modify our implementation to follow the standard operator precedence rules.</p>
<p>Luckily for us, we don&rsquo;t have to write any operator precedence handling code, FParsec has built-in capabilities for operator precedence handling. The basis is formed by the <a href="http://www.quanttec.com/fparsec/reference/operatorprecedenceparser.html"><code>OperatorPrecedenceParser</code></a> class. The first step is thus to create an <code>OperatorPrecedenceParser</code> instance, supplying it with the type we want it to return (<code>int</code>):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">opp</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OperatorPrecedenceParser</span><span class="o">&lt;</span><span class="n">int</span><span class="o">,</span><span class="kt">unit</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span><span class="bp">()</span>
</span></span></code></pre></div><p>Note: you can ignore the second and third type parameter, we won&rsquo;t be needing them.</p>
<p>The next step is to define how terms (which we referred to as operand) should be parsed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">TermParser</span> <span class="o">&lt;-</span> <span class="n">pint32</span> <span class="o">.&gt;&gt;</span> <span class="n">spaces</span>
</span></span></code></pre></div><p>For convenience purposes, we&rsquo;ve added the <code>spaces</code> parser to our parser, which allows us to just ignore any trailing spaces.</p>
<p>We can now specify the operators. There are four types of operators:</p>
<ul>
<li><a href="http://www.quanttec.com/fparsec/reference/operatorprecedenceparser.html#members.InfixOperator">InfixOperator</a></li>
<li><a href="http://www.quanttec.com/fparsec/reference/operatorprecedenceparser.html#members.PrefixOperator">PrefixOperator</a></li>
<li><a href="http://www.quanttec.com/fparsec/reference/operatorprecedenceparser.html#members.PostfixOperator">PostfixOperator</a></li>
<li><a href="http://www.quanttec.com/fparsec/reference/operatorprecedenceparser.html#members.TernaryOperator">TernaryOperator</a></li>
</ul>
<p>Our equation only has infix operators, so we will be using the <code>InfixOperator</code> type. In order to create an <code>InfixOperator</code>, we have to specify five parameters:</p>
<ul>
<li>The operator string.</li>
<li>The after-operator parser (which we&rsquo;ll use to skip trailing spaces).</li>
<li>The operator precedence.</li>
<li>The associativity: none, left or right.</li>
<li>The binary function used to combine terms.</li>
</ul>
<p>This is how we add the operators to represent our equation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span>          <span class="n">spaces</span><span class="o">,</span> <span class="n">1</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="o">-&gt;</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="o">))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;minus&#34;</span><span class="o">,</span>         <span class="n">spaces</span><span class="o">,</span> <span class="n">1</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="o">-&gt;</span> <span class="n">x</span> <span class="o">-</span> <span class="n">y</span><span class="o">))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;multiplied by&#34;</span><span class="o">,</span> <span class="n">spaces</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="o">-&gt;</span> <span class="n">x</span> <span class="o">*</span> <span class="n">y</span><span class="o">))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;divided by&#34;</span><span class="o">,</span>    <span class="n">spaces</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="o">-&gt;</span> <span class="n">x</span> <span class="o">/</span> <span class="n">y</span><span class="o">))</span>
</span></span></code></pre></div><p>Very simple. You can see that the <code>&quot;multiplied by&quot;</code> and <code>&quot;divided by&quot;</code> operators have a higher precedence (<code>2</code>) than the <code>&quot;plus&quot;</code> and <code>&quot;minus&quot;</code> operators (<code>1</code>).</p>
<p>We can of course simplify the term combination function by just passing the operator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span>          <span class="n">spaces</span><span class="o">,</span> <span class="n">1</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(+)))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;minus&#34;</span><span class="o">,</span>         <span class="n">spaces</span><span class="o">,</span> <span class="n">1</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(-)))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;multiplied by&#34;</span><span class="o">,</span> <span class="n">spaces</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(*)))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;divided by&#34;</span><span class="o">,</span>    <span class="n">spaces</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(/)))</span>
</span></span></code></pre></div><p>At this point, the <code>OperatorPrecedenceParser</code> instance has been correctly configured. We can then use its <code>ExpressionParser</code> property in our <code>parseEquation</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span> <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span> <span class="o">&gt;&gt;.</span> <span class="n">opp</span><span class="o">.</span><span class="n">ExpressionParser</span> <span class="o">.&gt;&gt;</span>  <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span></code></pre></div><p>If we now try to solve <code>&quot;What is -3 plus 7 multiplied by -2?&quot;</code>, the answer will be <code>-17</code>, exactly what we expect.</p>
<p>The updated source that uses the <code>OperatorPrecedenceParser</code> is listed below:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fsharp" data-lang="fsharp"><span class="line"><span class="cl"><span class="k">open</span> <span class="nn">FParsec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">opp</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OperatorPrecedenceParser</span><span class="o">&lt;</span><span class="n">int</span><span class="o">,</span><span class="kt">unit</span><span class="o">,</span><span class="kt">unit</span><span class="o">&gt;</span><span class="bp">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">TermParser</span> <span class="o">&lt;-</span> <span class="n">pint32</span> <span class="o">.&gt;&gt;</span> <span class="n">spaces</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;plus&#34;</span><span class="o">,</span>          <span class="n">spaces</span><span class="o">,</span> <span class="n">1</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(+)))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;minus&#34;</span><span class="o">,</span>         <span class="n">spaces</span><span class="o">,</span> <span class="n">1</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(-)))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;multiplied by&#34;</span><span class="o">,</span> <span class="n">spaces</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(*)))</span>
</span></span><span class="line"><span class="cl"><span class="n">opp</span><span class="o">.</span><span class="n">AddOperator</span><span class="o">(</span><span class="n">InfixOperator</span><span class="o">(</span><span class="s">&#34;divided by&#34;</span><span class="o">,</span>    <span class="n">spaces</span><span class="o">,</span> <span class="n">2</span><span class="o">,</span> <span class="nn">Associativity</span><span class="p">.</span><span class="n">Left</span><span class="o">,</span> <span class="o">(/)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseEquation</span> <span class="o">=</span> <span class="n">pstring</span> <span class="s">&#34;What is &#34;</span> <span class="o">&gt;&gt;.</span> <span class="n">opp</span><span class="o">.</span><span class="n">ExpressionParser</span> <span class="o">.&gt;&gt;</span>  <span class="n">pstring</span> <span class="s">&#34;?&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">parseToOption</span> <span class="n">parser</span> <span class="o">(</span><span class="n">input</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl">    <span class="k">match</span> <span class="n">run</span> <span class="n">parser</span> <span class="n">input</span> <span class="k">with</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Success</span><span class="o">(</span><span class="n">result</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span>   <span class="o">-&gt;</span> <span class="n">Some</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">    <span class="o">|</span> <span class="n">Failure</span><span class="o">(</span><span class="n">errorMsg</span><span class="o">,</span> <span class="o">_,</span> <span class="o">_)</span> <span class="o">-&gt;</span> <span class="n">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">let</span> <span class="nv">solve</span> <span class="o">(</span><span class="n">question</span><span class="o">:</span> <span class="kt">string</span><span class="o">)</span> <span class="o">=</span> <span class="n">parseToOption</span> <span class="n">parseEquation</span> <span class="n">question</span>
</span></span></code></pre></div><p>If we change the expected result for <code>&quot;What is -3 plus 7 multiplied by -2?&quot;</code> to <code>Some -17</code> and run the tests again, we&rsquo;ll see that all tests pass! Isn&rsquo;t that amazing for a grand total of 13 lines of code?</p>
<p>The fun thing is, if we set the operator precedence of all operators to the same value, we have a fully valid implementation of the wordy problem!</p>
<h2 id="building-a-parser-combinator-from-scratch">Building a parser combinator from scratch</h2>
<p>As we are really starting to appreciate parser combinators, let&rsquo;s build one from scratch!</p>
<p>Got you! You didn&rsquo;t <em>really</em> think we were going to do that, did you? If you are interested in how one would build a parser combinator library though, I highly recommend the <a href="http://fsharpforfunandprofit.com/posts/understanding-parser-combinators/">Understanding Parser Combinators</a> series on the fantastic <a href="http://fsharpforfunandprofit.com/">F# for fun and profit</a> website. In that series, Scott Wlaschin gradually builds a fully functional parser combinator library from scratch.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Solving the wordy problem was a very interesting exercise. The first few tests could be solved using just string replacing, splitting and converting. That approach quickly showed its defects, so we tried something else.</p>
<p>The second approach used regular expressions to parse the text. Using more advanced regular expression features (such as positive lookahead assertions), we could solve the problem using relatively little code. The readability was not great though, so it was time for another rewrite.</p>
<p>Our final approach used the FParsec parser combinator library. This resulted in a very elegant and concise solution. For fun, we then defined an Abstract Syntax Tree for the syntax being parsed, which was surprisingly easy and required very little code. We then showed how easy it is to define an expression parser with operator precedence rules in FParsec, further simplifying our implementation.</p>
<p>Of the three approaches we tried, the FParsec one was our favorite by far. It resulted in a simple, elegant implementation that was very readable. This was for a large part due to the many useful parsers FParsec includes out of the box. With these parser building blocks, we quickly and easily built our own, more complex parser. All in all, I can wholeheartedly recommend FParsec, whenever you have a text-parsing problem.</p>
]]></content>
		</item>
		
		<item>
			<title>Combining nested model lambda&#39;s in Razor</title>
			<link>https://www.erikschierboom.com/2016/11/04/razor-combining-lambdas/</link>
			<pubDate>Fri, 04 Nov 2016 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2016/11/04/razor-combining-lambdas/</guid>
			<description>In ASP.NET MVC, views are defined by Razor templates. One very useful feature of Razor is that it allows you to generate HTML using simple lambda expressions, strongly-typed to your view model. However, if you have a complex, nested model and want to combine lambda expressions, things stop working. In this post, we&amp;rsquo;ll see how to solve this problem.
Simple example Consider the following class that models user-related permissions:
public class UserPermissions { public bool Add { get; set; } public bool Edit { get; set; } public bool Delete { get; set; } } If we set the @model directive of a view to our UserPermissions class, the view&amp;rsquo;s HTML helper will be bound to this class.</description>
			<content type="html"><![CDATA[<p>In ASP.NET MVC, views are defined by Razor templates. One very useful feature of Razor is that it allows you to generate HTML using simple lambda expressions, strongly-typed to your view model. However, if you have a complex, nested model and want to combine lambda expressions, things stop working. In this post, we&rsquo;ll see how to solve this problem.</p>
<h2 id="simple-example">Simple example</h2>
<p>Consider the following class that models user-related permissions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">UserPermissions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">Add</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">Edit</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">Delete</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we set the <code>@model</code> directive of a view to our <code>UserPermissions</code> class, the view&rsquo;s HTML helper will be bound to this class. We can then specify the property to generate HTML for by passing a lamdba to the HTML helper&rsquo;s methods:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">@model UserPermissions
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">dl</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;dl-horizontal&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dt</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.Add)<span class="p">&lt;/</span><span class="nt">dt</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dd</span><span class="p">&gt;</span>@Html.DisplayFor(m =&gt; m.Add)<span class="p">&lt;/</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dt</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.Edit)<span class="p">&lt;/</span><span class="nt">dt</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dd</span><span class="p">&gt;</span>@Html.DisplayFor(m =&gt; m.Edit)<span class="p">&lt;/</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dt</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.Delete)<span class="p">&lt;/</span><span class="nt">dt</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dd</span><span class="p">&gt;</span>@Html.DisplayFor(m =&gt; m.Delete)<span class="p">&lt;/</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">dl</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>If we assume that <code>Add</code> is <code>true</code> and <code>Edit</code> and <code>Delete</code> are <code>false</code>, the following HTML output is rendered:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">dl</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;dl-horizontal&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dt</span><span class="p">&gt;</span>Add<span class="p">&lt;/</span><span class="nt">dt</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">input</span>
</span></span><span class="line"><span class="cl">      <span class="na">checked</span><span class="o">=</span><span class="s">&#34;checked&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">class</span><span class="o">=</span><span class="s">&#34;check-box&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">disabled</span><span class="o">=</span><span class="s">&#34;disabled&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="na">type</span><span class="o">=</span><span class="s">&#34;checkbox&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dt</span><span class="p">&gt;</span>Edit<span class="p">&lt;/</span><span class="nt">dt</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">input</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;check-box&#34;</span> <span class="na">disabled</span><span class="o">=</span><span class="s">&#34;disabled&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;checkbox&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dt</span><span class="p">&gt;</span>Delete<span class="p">&lt;/</span><span class="nt">dt</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">input</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;check-box&#34;</span> <span class="na">disabled</span><span class="o">=</span><span class="s">&#34;disabled&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;checkbox&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">dd</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">dl</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Clean and simple. Let&rsquo;s move to a more complex model.</p>
<h2 id="more-complex-example">More complex example</h2>
<p>For our more complex example, we&rsquo;ll create a model that stores the user permissions of several types of users:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">RolePermissions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">UserPermissions</span> <span class="n">User</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">UserPermissions</span> <span class="n">Moderator</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">UserPermissions</span> <span class="n">Administrator</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The following view allows us to edit these permissions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">@model RolePermissions @using (Html.BeginForm()) { @Html.AntiForgeryToken()
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">table</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.User)<span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.Moderator)<span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">th</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.Administrator)<span class="p">&lt;/</span><span class="nt">th</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">thead</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.User.Add)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.User.Add)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.Moderator.Add)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.Administrator.Add)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.User.Edit)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.User.Edit)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.Moderator.Edit)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.Administrator.Edit)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.DisplayNameFor(m =&gt; m.User.Delete)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.User.Delete)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.Moderator.Delete)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="p">&lt;</span><span class="nt">td</span><span class="p">&gt;</span>@Html.EditorFor(m =&gt; m.Administrator.Delete)<span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">table</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;submit&#34;</span><span class="p">&gt;</span>Save<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">}
</span></span></code></pre></div><p>Although this view is more complex, it&rsquo;s still quite readable. The rendered view looks something like this:</p>
<p><img src="/images/posts/razor-combining-lambdas/edit-model-view-rendered.png" alt="Edit model view rendered"></p>
<p>It&rsquo;s not the prettiest of GUI&rsquo;s, but it is fully functional. To verify that our model is bound properly, let&rsquo;s first examine the view&rsquo;s controller:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System.Web.Mvc</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">PermissionsController</span> <span class="p">:</span> <span class="n">Controller</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [HttpGet]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ActionResult</span> <span class="n">Index</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">View</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="na">
</span></span></span><span class="line"><span class="cl"><span class="na">    [HttpPost]</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ValidateAntiForgeryToken]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ActionResult</span> <span class="n">Index</span><span class="p">(</span><span class="n">RolePermissions</span> <span class="n">model</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">View</span><span class="p">(</span><span class="n">model</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Once again, nothing exciting happening here. If we submit our form and put a breakpoint on the <code>return View(model);</code> line, we can verify that model binding still works perfectly.</p>
<h2 id="removing-duplication">Removing duplication</h2>
<p>Although our view looks nice, it does have a fair amount of duplication. In particular, the rows in the <code>&lt;tbody&gt;</code> section all have the exact same structure:</p>
<ul>
<li>The first column contains the name of the permission.</li>
<li>The second column allows editing of that permission for the <code>User</code> role.</li>
<li>The third column allows editing of that permission for the <code>Moderator</code> role.</li>
<li>The fourth column allows editing of that permission for the <code>Administrator</code> role.</li>
</ul>
<p>If one or more user types are added, or new types of permissions introduced, we have to edit our template in multiple places. This is tedious and error-prone, so let&rsquo;s try to remove this repetition.</p>
<p>In Razor, you can extract shared functionality into reusable components using <a href="https://www.asp.net/web-pages/overview/ui-layouts-and-themes/creating-and-using-a-helper-in-an-aspnet-web-pages-site">Razor helpers</a>, which are functions that return HTML. What&rsquo;s great though, is that you use a Razor template to define the HTML it returns. You can think of Razor helpers as a parameterized Razor view.</p>
<p>A first, naive attempt to create such a helper for our <code>&lt;tbody&gt;</code> rows would look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">@helper</span> <span class="n">PermissionRow</span><span class="p">(</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;</span> <span class="n">permission</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="n">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">DisplayNameFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">User</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">EditorFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">User</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">EditorFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">Moderator</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">EditorFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">Administrator</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="n">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can then eliminate much of the duplication as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  @PermissionRow(permissions =&gt; permissions.Add) @PermissionRow(permissions =&gt;
</span></span><span class="line"><span class="cl">  permissions.Edit) @PermissionRow(permissions =&gt; permissions.Delete)
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">tbody</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Unfortunately, if we execute this code, we get the following runtime exception:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>What this error message tells us, is that the HTML helper methods only accept a very restricted set of expressions, namely ones that directly reference a property. In our example, we used a function to reference the property, which is not supported.</p>
<p>In our previous example, we did directly reference the property: <code>@Html.EditorFor(m =&gt; m.User.Delete)</code>, which worked fine. That lambda&rsquo;s expression is of type <code>Expression&lt;RolePermissions, bool&gt;</code>, so how can we convert the <code>Func&lt;UserPermissions, bool&gt;</code> parameter of our Razor helper to <code>Expression&lt;RolePermissions, bool&gt;</code>? Let&rsquo;s find out!</p>
<h2 id="solution">Solution</h2>
<p>To convert our <code>Func&lt;UserPermissions, bool&gt;</code> expression to <code>Expression&lt;RolePermissions, bool&gt;</code>, we&rsquo;ll start by wrapping it in an <code>Expression</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">@helper</span> <span class="n">PermissionRow</span><span class="p">(</span><span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;</span> <span class="n">permission</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="n">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">DisplayNameFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">User</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">EditorFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">User</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">EditorFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">Moderator</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">EditorFor</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">permission</span><span class="p">(</span><span class="n">m</span><span class="p">.</span><span class="n">Administrator</span><span class="p">))&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="n">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The reason we use an <code>Expression&lt;Func&lt;T&gt;&gt;</code> instead of a <code>Func&lt;T&gt;</code>, is that expressions can be transformed into other expressions. We&rsquo;ll see how we can use this feature shortly.</p>
<p>The next step is to extract the column rendering from our <code>PermissionRow</code> HTML helper to a separate HTML helper: <code>PermissionColumn</code>. This helper will receive two parameters:</p>
<ol>
<li>An expression describing a function from <code>UserPermission</code> to <code>bool</code>. This expression points to the permission property: <code>Add</code>, <code>Edit</code> or <code>Delete</code>.</li>
<li>An expression describing a function from <code>RolePermissions</code> to <code>UserPermission</code>. This expression points to the user permission property: <code>User</code>, <code>Moderator</code> or <code>Administrator</code>.</li>
</ol>
<p>The basic structure of this helper looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">@helper</span> <span class="n">PermissionColumn</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;</span> <span class="n">userPermission</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="n">UserPermissions</span><span class="p">&gt;&gt;</span> <span class="n">rolePermission</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">EditorFor</span><span class="p">(</span><span class="s">&#34;TODO: combine the two expressions&#34;</span><span class="p">)&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>At this point, we are almost there. If we could combine the two expressions into one expression, in which we pipe the output of <code>Func&lt;RolePermissions, UserPermissions&gt;</code> into <code>Func&lt;UserPermissions, bool&gt;</code>, we would end up with an expression of type <code>Expression&lt;Func&lt;RolePermissions, bool&gt;&gt;</code>, precisely what we need!</p>
<p>So how can we combine these two expressions into a single expression? Let&rsquo;s start with the basic skeleton of the combine method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="n">UserPermissions</span><span class="p">&gt;&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="n">Combine</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="n">UserPermissions</span><span class="p">&gt;&gt;</span> <span class="n">outer</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">         <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;</span> <span class="n">inner</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Expression</span><span class="p">.</span><span class="n">Lambda</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;(</span><span class="n">TODO</span><span class="p">,</span> <span class="n">TODO</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>In this method, we use the <code>Expression.Lambda</code> method to create a new expression. It takes two parameters:</p>
<ol>
<li>The body of the expression.</li>
<li>The parameters passed to the expression in the body.</li>
</ol>
<p>If you think about it, the second parameter must be equal to the outer expression&rsquo;s parameters. That&rsquo;s one step completed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Expression</span><span class="p">.</span><span class="n">Lambda</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;(</span><span class="n">body</span><span class="p">,</span> <span class="n">outer</span><span class="p">.</span><span class="n">Parameters</span><span class="p">);</span>
</span></span></code></pre></div><p>For the first parameter, we need to construct an expression that represents the body of the combined expression. What we want is to pass the output of the <code>Func&lt;RolePermissions, UserPermissions&gt;</code> expression to the input parameter of the <code>Func&lt;UserPermissions, bool&gt;</code> expression. If you think about this backwards, this is the same as replacing the input parameter of the <code>Func&lt;UserPermissions, bool&gt;</code> expression with the output of the body of the <code>Func&lt;RolePermissions, UserPermissions&gt;</code> expression.</p>
<p>To transform/rewrite an expression, the <code>ExpressionVisitor</code> class can be used. Surprisingly, we need very little code to create a visitor that replaces one expression with another:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">private</span> <span class="k">class</span> <span class="nc">SwapVisitor</span> <span class="p">:</span> <span class="n">ExpressionVisitor</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="k">readonly</span> <span class="n">Expression</span> <span class="n">_from</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="k">readonly</span> <span class="n">Expression</span> <span class="n">_to</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">SwapVisitor</span><span class="p">(</span><span class="n">Expression</span> <span class="k">from</span><span class="p">,</span> <span class="n">Expression</span> <span class="n">to</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">_from</span> <span class="p">=</span> <span class="k">from</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">_to</span> <span class="p">=</span> <span class="n">to</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">override</span> <span class="n">Expression</span> <span class="n">Visit</span><span class="p">(</span><span class="n">Expression</span> <span class="n">node</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">node</span> <span class="p">==</span> <span class="n">_from</span> <span class="p">?</span> <span class="n">_to</span> <span class="p">:</span> <span class="k">base</span><span class="p">.</span><span class="n">Visit</span><span class="p">(</span><span class="n">node</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The constructor takes two <code>Expression</code> parameters:</p>
<ol>
<li>The <code>from</code> parameter is the expression we want to replace.</li>
<li>The <code>to</code> parameter is the expression we want to replace it with.</li>
</ol>
<p>The actual rewriting happens in the <code>Visit()</code> method. There, we check if the node parameter equals the <code>from</code> expression. If so, we return the <code>to</code> expression; otherwise, we just continue visiting the node.</p>
<p>We can now use this class to create an expression visitor in which we replace the inner expression&rsquo;s parameter (which has one parameter) with the outer expression&rsquo;s body:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">swap</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SwapVisitor</span><span class="p">(</span><span class="n">inner</span><span class="p">.</span><span class="n">Parameters</span><span class="p">[</span><span class="m">0</span><span class="p">],</span> <span class="n">outer</span><span class="p">.</span><span class="n">Body</span><span class="p">);</span>
</span></span></code></pre></div><p>The final step is to use this swap visitor to create our target expression, which we do by calling its <code>Visit()</code> method with the inner expression&rsquo;s body:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System.Linq.Expressions</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">Expressions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Combine</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">RolePermissions</span><span class="p">,</span> <span class="n">UserPermissions</span><span class="p">&gt;&gt;</span> <span class="n">outer</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">             <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;</span> <span class="n">inner</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">swap</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SwapVisitor</span><span class="p">(</span><span class="n">inner</span><span class="p">.</span><span class="n">Parameters</span><span class="p">[</span><span class="m">0</span><span class="p">],</span> <span class="n">outer</span><span class="p">.</span><span class="n">Body</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">Expression</span><span class="p">.</span><span class="n">Lambda</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">TOuter</span><span class="p">,</span> <span class="n">TProperty</span><span class="p">&gt;&gt;(</span>
</span></span><span class="line"><span class="cl">            <span class="n">swap</span><span class="p">.</span><span class="n">Visit</span><span class="p">(</span><span class="n">inner</span><span class="p">.</span><span class="n">Body</span><span class="p">),</span> <span class="n">outer</span><span class="p">.</span><span class="n">Parameters</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>When the <code>Visit</code> method is called, the following happens:</p>
<ol>
<li>The <code>node</code> parameter of the <code>Visit()</code> method will equal the inner expression&rsquo;s body. As this expression does not equal the <code>inner.Parameters[0]</code> expression, the expression is passed to <code>base.Visit()</code>.</li>
<li>Within <code>base.Visit()</code>, the expression&rsquo;s children are visited. As the expression is a function, at some point it will visit the expression representing the function&rsquo;s parameters.</li>
<li>The <code>Visit()</code> method is now called with the <code>inner.Parameters[0]</code> expression, which it recognizes to be equal to the <code>from</code> expression, so the <code>to</code> expression (the outer expression&rsquo;s body) is returned.</li>
</ol>
<p>Finally, the <code>Visit</code> method will return the transformed expression, which has the type we were looking for: <code>Expression&lt;Func&lt;RolePermissions, bool&gt;&gt;</code>.</p>
<p>With our <code>PermissionColumn</code> helper is finished, we can use it in our <code>PermissionRow</code> helper:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">@helper</span> <span class="n">PermissionRow</span><span class="p">(</span><span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">UserPermissions</span><span class="p">,</span> <span class="kt">bool</span><span class="p">&gt;&gt;</span> <span class="n">permission</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">displayName</span> <span class="p">=</span> <span class="n">Expressions</span><span class="p">.</span><span class="n">Combine</span><span class="p">((</span><span class="n">RolePermissions</span> <span class="n">model</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">model</span><span class="p">.</span><span class="n">User</span><span class="p">,</span> <span class="n">permission</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="n">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@Html</span><span class="p">.</span><span class="n">DisplayNameFor</span><span class="p">(</span><span class="n">displayName</span><span class="p">)&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@PermissionColumn</span><span class="p">(</span><span class="n">permission</span><span class="p">,</span> <span class="n">m</span> <span class="p">=&gt;</span> <span class="n">m</span><span class="p">.</span><span class="n">User</span><span class="p">)&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@PermissionColumn</span><span class="p">(</span><span class="n">permission</span><span class="p">,</span> <span class="n">m</span> <span class="p">=&gt;</span> <span class="n">m</span><span class="p">.</span><span class="n">Moderator</span><span class="p">)&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="p">&lt;</span><span class="n">td</span><span class="p">&gt;</span><span class="n">@PermissionColumn</span><span class="p">(</span><span class="n">permission</span><span class="p">,</span> <span class="n">m</span> <span class="p">=&gt;</span> <span class="n">m</span><span class="p">.</span><span class="n">Administrator</span><span class="p">)&lt;/</span><span class="n">td</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="n">tr</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now run our application to verify that everything still works, which it does!</p>
<h3 id="making-the-extension-generic">Making the extension generic</h3>
<p>The final step is to make the <code>Combine</code> method generic, which is just a matter of replacing the concrete types with type parameters:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">TOuter</span><span class="p">,</span> <span class="n">TProperty</span><span class="p">&gt;&gt;</span> <span class="n">Combine</span><span class="p">&lt;</span><span class="n">TOuter</span><span class="p">,</span> <span class="n">TInner</span><span class="p">,</span> <span class="n">TProperty</span><span class="p">&gt;(</span>
</span></span><span class="line"><span class="cl">    <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">TOuter</span><span class="p">,</span> <span class="n">TInner</span><span class="p">&gt;&gt;</span> <span class="n">outer</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">Expression</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">TInner</span><span class="p">,</span> <span class="n">TProperty</span><span class="p">&gt;&gt;</span> <span class="n">inner</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">swap</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SwapVisitor</span><span class="p">(</span><span class="n">inner</span><span class="p">.</span><span class="n">Parameters</span><span class="p">[</span><span class="m">0</span><span class="p">],</span> <span class="n">outer</span><span class="p">.</span><span class="n">Body</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">Expression</span><span class="p">.</span><span class="n">Lambda</span><span class="p">&lt;</span><span class="n">Func</span><span class="p">&lt;</span><span class="n">TOuter</span><span class="p">,</span> <span class="n">TProperty</span><span class="p">&gt;&gt;(</span><span class="n">swap</span><span class="p">.</span><span class="n">Visit</span><span class="p">(</span><span class="n">inner</span><span class="p">.</span><span class="n">Body</span><span class="p">),</span> <span class="n">outer</span><span class="p">.</span><span class="n">Parameters</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>And there we have it: a fully generic method that can combine <code>Func&lt;TOuter, TInner&gt;</code> and <code>Func&lt;TInner, TProperty&gt;</code> expressions into an <code>Expression&lt;Func&lt;TOuter, TProperty&gt;&gt;</code> expression.</p>
<h2 id="conclusion">Conclusion</h2>
<p>HTML helpers in Razor views are a very convenient feature. In this post we showed how to use the <code>ExpressionVisitor</code> class to combine two expressions into a single expression. We used this feature to allow us to write small Razor helpers with which we were able to greatly reduce duplication in our view.</p>
]]></content>
		</item>
		
		<item>
			<title>Create an audio recorder app using Ionic 2</title>
			<link>https://www.erikschierboom.com/2016/09/02/ionic2-audio-recorder/</link>
			<pubDate>Thu, 22 Sep 2016 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2016/09/02/ionic2-audio-recorder/</guid>
			<description>Building mobile apps can be a daunting task. One of the biggest problems is that each platform has its own, specific ecosystem, which prevents you from reusing code between platforms. The Ionic 2 platform lets you build apps for multiple platforms from a single code base, using only HTML, CSS and JavaScript. Ionic 2 is built on the powerful Angular 2 framework.
In this post, we&amp;rsquo;ll build a native app using Ionic 2.</description>
			<content type="html"><![CDATA[<p>Building mobile apps can be a daunting task. One of the biggest problems is that each platform has its own, specific ecosystem, which prevents you from reusing code between platforms. The <a href="http://ionicframework.com/docs/v2/">Ionic 2</a> platform lets you build apps for multiple platforms from a single code base, using only HTML, CSS and JavaScript. Ionic 2 is built on the powerful <a href="http://learnangular2.com/components/">Angular 2</a> framework.</p>
<p>In this post, we&rsquo;ll build a native app using Ionic 2. To demonstrate that Ionic 2 apps are real, native mobile apps, we&rsquo;ll be accessing the device&rsquo;s hardware to record (and playback) audio.</p>
<h2 id="installation">Installation</h2>
<p>The first step to start building Ionic 2 apps is to <a href="http://ionicframework.com/docs/v2/getting-started/installation/">install</a> the Ionic 2 SDK (which is still in beta):</p>
<pre tabindex="0"><code>npm install -g ionic@beta
</code></pre><p>Once this command has completed, we can use the <a href="http://ionicframework.com/docs/v2/cli/">Ionic CLI</a> to scaffold our app:</p>
<pre tabindex="0"><code>ionic start ionic2-recorder blank --v2
</code></pre><p>With this command, the CLI will scaffold an Ionic 2 app named <code>ionic2-recorder</code> using the <code>blank</code> template:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>Note that scaffolding the app can take quite a while, so this might be a good time to check out the <a href="http://ionicframework.com/docs/v2/getting-started">getting started documentation</a>.</p>
<p>After some waiting, the CLI will finish and our app has been scaffolded:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h2 id="running-in-the-browser">Running in the browser</h2>
<p>Before we start building our app, let&rsquo;s see what the scaffolded app looks like. First, we go to the directory into which our app was scaffolded:</p>
<pre tabindex="0"><code>cd ionic2-recorder
</code></pre><p>Then we ask the CLI to show a preview of our app in the browser:</p>
<pre tabindex="0"><code>ionic serve
</code></pre><p>This will result in some <a href="http://gulpjs.com/">Gulp</a> tasks being run:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>When the Gulp tasks have completed, a browser window will open showing a preview of our app:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-preview-first-version.png" alt="Example image"></p>
<p>It may not look much, but consider this: we are previewing our app in a browser! Not on a device or simulator, but a browser! This means that you can develop apps just like you are developing a website. Let&rsquo;s see how that works.</p>
<h2 id="building-the-app---beginning">Building the app - beginning</h2>
<p>To start building our app, open the scaffolded app&rsquo;s directory in your favorite editor. Don&rsquo;t be daunted by the number of files and directories, we are only interested in the <code>app</code> directory&rsquo;s contents, which looks like this:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>Interestingly, this directory contains just three types of files:</p>
<ol>
<li>TypeScript files: the application&rsquo;s logic. Compiled to JavaScript.</li>
<li>SCSS files: the application&rsquo;s styling. Compiled to CSS.</li>
<li>HTML files: the application&rsquo;s interface. Not compiled.</li>
</ol>
<p>Clearly, as promised, an Ionic 2 app consists of only HTML, JavaScript and CSS, like any regular website.</p>
<p>At the moment, there is only one page in our app: the <code>home</code> page. Let&rsquo;s see what the (scaffolded) <code>home.html</code> file looks like:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ion-header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">ion-navbar</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ion-title</span><span class="p">&gt;</span> Ionic Blank <span class="p">&lt;/</span><span class="nt">ion-title</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">ion-navbar</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ion-header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ion-content</span> <span class="na">padding</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  The world is your oyster.
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    If you get lost, the
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;http://ionicframework.com/docs/v2&#34;</span><span class="p">&gt;</span>docs<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> will be your guide.
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ion-content</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Although there are some regular HTML tags like the <code>&lt;p&gt;</code> and <code>&lt;a&gt;</code> tags, there are also custom tags like <code>&lt;ion-header&gt;</code> and <code>&lt;ion-navbar&gt;</code>. These tags are specific to the Ionic framework and are known as <a href="http://ionicframework.com/docs/v2/components/#overview">components</a> (which is an <a href="https://angular.io/docs/ts/latest/guide/architecture.html#components">Angular 2 concept</a>). Using these components, you&rsquo;ll be able to quickly construct an interface for your app, without having to manually create and style them yourselves.</p>
<h3 id="modifying-the-app">Modifying the app</h3>
<p>As our first modification, let&rsquo;s change the contents of the <code>&lt;ion-title&gt;</code> tag:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ion-header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">ion-navbar</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ion-title</span><span class="p">&gt;</span> Ionic 2 Audio Recorder <span class="p">&lt;/</span><span class="nt">ion-title</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">ion-navbar</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ion-header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ion-content</span> <span class="na">padding</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  The world is your oyster.
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    If you get lost, the
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;http://ionicframework.com/docs/v2&#34;</span><span class="p">&gt;</span>docs<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> will be your guide.
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ion-content</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>If we save this file, the CLI will rebuild the app and automatically refresh the browser window to show our app with the modified title:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-preview-text-modification.png" alt="Browser preview of text modification"></p>
<p>As a first step towards implementing audio recording functionality, let&rsquo;s add a &ldquo;Start recording&rdquo; button:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ion-header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">ion-navbar</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ion-title</span><span class="p">&gt;</span> Ionic 2 Audio Recorder <span class="p">&lt;/</span><span class="nt">ion-title</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">ion-navbar</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ion-header</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ion-content</span> <span class="na">padding</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">button</span><span class="p">&gt;</span>Start recording<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ion-content</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Note that we just use a regular <code>&lt;button&gt;</code> tag, as there is no <code>&lt;ion-button&gt;</code> component.</p>
<p>The updated app looks like this:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-preview-button.png" alt="Added button"></p>
<h3 id="improved-device-preview">Improved device preview</h3>
<p>Although our browser preview looks fine, it does have fairly odd dimensions for a mobile device. If you are using Google Chrome, you can do one better. First, right-click in our app preview window and click on <code>Inspect</code>. This will open the Developer Tools window. If you look closely, you&rsquo;ll see an icon that looks like a mobile phone in front of a tablet next to the <code>Elements</code> tab:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-developer-tools.png" alt="Developer tools button"></p>
<p>If we click on that icon, Google Chrome will render the page <em>as if it was rendered on a mobile device</em>, correct screen proportions and all:<br>
<img src="/images/posts/ionic2-audio-recorder/browser-preview-device.png" alt="Device preview"></p>
<p>Note that you can also select other devices, change the dimensions, and much more.</p>
<h3 id="multi-platform-preview">Multi-platform preview</h3>
<p>One great feature of Ionic is that it will adjust the look and feel of your app depending on the platform it runs on. To easily see the differences between these platforms, you can start the <code>ionic serve</code> command with the <code>--lab</code> parameter:</p>
<pre tabindex="0"><code>ionic serve --lab
</code></pre><p>This results in the preview window showing all three platforms side-by-side:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-preview-compare-platforms.png" alt="Compare platforms"></p>
<p>Although the difference is not huge in this case, the buttons and headers do have a different look-and-feel for each platform, even though they all run the same code. Pretty neat, right?</p>
<p>Note: you should disable the device preview in the Developer Tools for this to display correctly.</p>
<h2 id="preparing-for-recording-audio">Preparing for recording audio</h2>
<p>Now it&rsquo;s time to start adding audio recording functionality to our app. Recording audio is a <em>native</em> capability: it requires access to a microphone. Therefore, we can&rsquo;t test our recording functionality in the browser, we&rsquo;ll have to use an actual device (or simulator).</p>
<p>To run our app on a device or simulator, Ionic uses <a href="http://ionicframework.com/docs/v2/resources/what-is/#cordova">Cordova</a>. The first step is thus to install Cordova:</p>
<pre tabindex="0"><code>npm install -g cordova
</code></pre><p>Now that Cordova has been installed, the next step is to install the <a href="http://ionicframework.com/docs/v2/native/"><code>ionic-native</code></a> plugin:</p>
<pre tabindex="0"><code>npm install ionic-native --save
</code></pre><p>The purpose of Ionic Native is to provide Ionic-friendly wrappers around Cordova plugins, which in turn allow access to the device&rsquo;s API&rsquo;s (such as the audio recording API). Schematically, it looks something like this:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>The next step is to find the Ionic Native component that allows us to record audio, which is the <code>MediaPlugin</code> component. According to its <a href="http://ionicframework.com/docs/v2/native/mediaplugin/">documentation</a>, it depends on the <code>cordova-plugin-media</code> <a href="https://github.com/apache/cordova-plugin-media">plugin</a>, which we can install using the CLI:</p>
<pre tabindex="0"><code>ionic plugin add cordova-plugin-media
</code></pre><p>We now have all the prerequisites to record audio in our app. But what file should contain our audio recording code? Let&rsquo;s recall the structure of the <code>app</code> directory:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>At the moment, we have only one page: the <code>home</code> page, which is defined by the three files in the <code>home</code> directory:</p>
<ul>
<li><code>home.html</code>: defines the interface of our home page.</li>
<li><code>home.scss</code>: defines any custom styling of our home page.</li>
<li><code>home.ts</code>: defines the logic of the home page.</li>
</ul>
<p>Clearly, we&rsquo;ll have to add our audio recording code to <code>home.ts</code>, which looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Component</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@angular/core&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">NavController</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;ionic-angular&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">@</span><span class="nx">Component</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">templateUrl</span><span class="o">:</span> <span class="s1">&#39;build/pages/home/home.html&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">HomePage</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">constructor</span><span class="p">(</span><span class="kr">public</span> <span class="nx">navCtrl</span><span class="o">:</span> <span class="nx">NavController</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>It turns out that an Ionic 2 page is just a regular <a href="https://angular.io/docs/ts/latest/guide/architecture.html#!#components">Angular 2 component</a>, nothing fancy.</p>
<p>Note that the template URL must be relative to the directory where the app&rsquo;s compiled HTML/JavaScript/CSS is located: the <code>build</code> directory.</p>
<h2 id="recording-audio">Recording audio</h2>
<p>To import the <code>MediaPlugin</code> component in our <code>home.ts</code> file, we add the following <code>import</code> statement:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">MediaPlugin</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;ionic-native&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>In the <code>MediaPlugin</code> component&rsquo;s <a href="http://ionicframework.com/docs/v2/native/mediaplugin/">documentation</a>, we noticed it had a <code>startRecord</code> function, exactly what we need!</p>
<p>Note: if you don&rsquo;t like to read documentation, most editors also have code-completion (due to Ionic 2 being written in TypeScript):</p>
<p><img src="/images/posts/ionic2-audio-recorder/vscode-code-completion.png" alt="Visual Studio Code code-completion"></p>
<p>Let&rsquo;s add a <code>startRecording</code> function to our <code>HomePage</code> class, in which we&rsquo;ll start recording audio:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">startRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">media</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MediaPlugin</span><span class="p">(</span><span class="s1">&#39;../Library/NoCloud/recording.wav&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="nx">media</span><span class="p">.</span><span class="nx">startRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The final step is to call the <code>startRecording</code> function when the &ldquo;Start recording&rdquo; button is clicked:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">button</span> <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startRecording</span><span class="err">()&#34;</span><span class="p">&gt;</span>Start recording<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>You might be tempted to try this new functionality in the browser, but unfortunately, there will be an error:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-record-error.png" alt="Browser recording error"></p>
<p>If you look at the error message more closely, it states that:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>Hmmm, it appears it cannot find an instance of <code>Media</code>. Although this error message is a bit cryptic, there is a very simple explanation: we are trying to use the native audio recording capability, which is not supported in the browser. The solution is simple: we should test this code on a physical device or simulator.</p>
<p>Silently failing is not very user-friendly though, so let&rsquo;s gracefully handle this error. First, we import the <code>AlertController</code> component:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">NavController</span><span class="p">,</span> <span class="nx">AlertController</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;ionic-angular&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>Next, we require an <code>AlertController</code> instance to be <a href="https://angular.io/docs/ts/latest/guide/dependency-injection.html">injected</a> into our constructor:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">constructor</span><span class="p">(</span><span class="kr">public</span> <span class="nx">navCtrl</span><span class="o">:</span> <span class="nx">NavController</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="kr">public</span> <span class="nx">alertCtrl</span><span class="o">:</span> <span class="nx">AlertController</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can then use this <code>AlertController</code> instance to create a helper method that will show an alert:</p>
<pre tabindex="0"><code>showAlert(message) {
  let alert = this.alertCtrl.create({
    title: &#39;Error&#39;,
    subTitle: message,
    buttons: [&#39;OK&#39;]
  });
  alert.present();
}
</code></pre><p>Finally, we&rsquo;ll add a <code>try/catch</code> block to our <code>startRecording</code> function and use the <code>showAlert</code> function to show an alert:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">startRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">let</span> <span class="nx">media</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MediaPlugin</span><span class="p">(</span><span class="s1">&#39;../Library/NoCloud/recording.wav&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">media</span><span class="p">.</span><span class="nx">startRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not start recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Now, if we run our application in the browser and click on the &ldquo;Start recording&rdquo; button, we&rsquo;ll see a nice alert:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-alert.png" alt="Browser recording error"></p>
<h2 id="running-in-a-simulator">Running in a simulator</h2>
<p>As said, to record audio we&rsquo;ll need to use a device our simulator. In both cases, we need to ensure our app supports the iOS platform. We can list the platforms our app currently supports using:</p>
<pre tabindex="0"><code>ionic platform
</code></pre><p>For our app, it outputs the following:</p>
<pre tabindex="0"><code>Installed platforms: ios 4.1.1
Available platforms: amazon-fireos, android, blackberry10, browser, firefoxos, osx, webos
</code></pre><p>Clearly, our app already supports iOS. Note: this was done automatically by the CLI due to us scaffolding the app on a MacBook.</p>
<p>If iOS platform support would not have been installed, we could have installed it manually:</p>
<pre tabindex="0"><code>ionic platform add ios
</code></pre><p>To run our app in the iOS simulator, first make sure you have <a href="https://developer.apple.com/xcode/">Xcode</a> and an <a href="https://developer.apple.com/library/ios/recipes/xcode_help-documentation_preferences/Articles/DownloadingandInstallingXcodeComponents.html">iOS simulator</a> installed. If you have those prerequisites installed, we can run our app in the simulator using:</p>
<pre tabindex="0"><code>ionic emulate ios
</code></pre><p>This time, there is far more going on in the background:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>The build script doesn&rsquo;t just compile our app to HTML, JavaScript and CSS files, but this time it compiles our app to a real, native iOS app. The reason for this is simple: you can only run native apps in the simulator.</p>
<p>Once the native app has been compiled, the simulator will pop-up and our app is shown:</p>
<p><img src="/images/posts/ionic2-audio-recorder/ios-simulator-preview.png" alt="Simulator preview"></p>
<p>Clicking on the &ldquo;Start recording&rdquo; button does not result in an error this time. However, we cannot verify if it actually recorded anything, so let&rsquo;s fix this.</p>
<h2 id="adding-audio-playback-support">Adding audio playback support</h2>
<p>To allow us to playback the recorded audio, we need to add several functions to the <code>HomePage</code> class:</p>
<ul>
<li>A function to stop recording (which will save the recorded audio to file).</li>
<li>A function to playback the saved recording.</li>
<li>A function to stop the playback of the saved recording.</li>
</ul>
<p>As all these functions need access to the same <code>MediaPlugin</code> instance, let&rsquo;s store it in a private field:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">HomePage</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">media</span><span class="o">:</span> <span class="nx">MediaPlugin</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MediaPlugin</span><span class="p">(</span><span class="s2">&#34;../Library/NoCloud/recording.wav&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Next, we modify the existing <code>startRecording</code> function to use this private field and add the other functions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">startRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">startRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not start recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">stopRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">stopRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not stop recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">startPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">play</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not play recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">stopPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">stop</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not stop playing recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Finally, we&rsquo;ll update <code>home.html</code> to have a button for each function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startRecording</span><span class="err">()&#34;</span><span class="p">&gt;</span>Start recording<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopRecording</span><span class="err">()&#34;</span><span class="p">&gt;</span>Stop recording<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startPlayback</span><span class="err">()&#34;</span><span class="p">&gt;</span>Start playback<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopPlayback</span><span class="err">()&#34;</span><span class="p">&gt;</span>Stop playback<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Let&rsquo;s run our app again:</p>
<p><img src="/images/posts/ionic2-audio-recorder/ios-simulator-error.png" alt="Simulator playback"></p>
<p>Unfortunately, the screen is blank, indicating that an error occured. As it turns out, this error is due to the <code>MediaPlugin</code> instance being created when the class is constructed. At that point, the native media plugin will not yet have been loaded, so creating the <code>MediaPlugin</code> instance throws an error.</p>
<p>So what <em>is</em> the right time to create our shared <code>MediaPlugin</code> instance? Well, let&rsquo;s look at the <a href="http://ionicframework.com/docs/v2/api/components/nav/NavController/#lifecycle-events">lifecycle events</a> for an Ionic component (in order of occurance):</p>
<ul>
<li><code>ionViewLoaded</code>: runs when the page has loaded.</li>
<li><code>ionViewWillEnter</code>: runs when the page is about to enter and become the active page.</li>
<li><code>ionViewDidEnter</code>: runs when the page has fully entered and is now the active page.</li>
<li><code>ionViewWillLeave</code>: runs when the page is about to leave and no longer be the active page.</li>
<li><code>ionViewDidLeave</code>: runs when the page has finished leaving and is no longer the active page.</li>
<li><code>ionViewWillUnload</code>: runs when the page is about to be destroyed and have its elements removed.</li>
<li><code>ionViewDidUnload</code>: runs after the page has been destroyed and its elements have been removed.</li>
</ul>
<p>Let&rsquo;s try to initialize the <code>MediaPlugin</code> in the <code>ionViewLoaded</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">HomePage</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">media</span><span class="o">:</span> <span class="nx">MediaPlugin</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">ionViewLoaded</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MediaPlugin</span><span class="p">(</span><span class="s1">&#39;../Library/NoCloud/recording.wav&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we run our app, the GUI is shown this time, but clicking on the &ldquo;Start recording&rdquo; button still issues an error:</p>
<p><img src="/images/posts/ionic2-audio-recorder/ios-simulator-playback-error.png" alt="Simulator playback"></p>
<p>Moving the initialization to <code>ionViewWillEnter</code> also results in the same error, but moving it to <code>ionViewDidEnter</code> solves our problem:</p>
<p><img src="/images/posts/ionic2-audio-recorder/ios-simulator-playback.png" alt="Simulator playback"></p>
<p>This time, everything works (provided we click on the buttons in the right order). We can record and playback audio in our Ionic 2 app, using just a couple of lines of JavaScript code!</p>
<p>As a funny side note, the official <a href="https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/iOS_Simulator_Guide/TestingontheiOSSimulator/TestingontheiOSSimulator.html#//apple_ref/doc/uid/TP40012848-CH4-SW1">iOS simulator documentation</a> explicitly states that the microphone <em>can&rsquo;t</em> be used in the simulator :)</p>
<h3 id="running-in-a-specific-simulator">Running in a specific simulator</h3>
<p>Each time we ran our app in the simulator, it opened the default simulator. However, it is also possible to specify the simulator that should be used.</p>
<p>The first step is to get a list of all (iOS) simulator device types. We can do this with the following command:</p>
<pre tabindex="0"><code>ios-sim showdevicetypes
</code></pre><p>This will output a list of device types that can be used in the simulator:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>We then specify the device type we want to use through the <code>--target</code> parameter:</p>
<pre tabindex="0"><code>ionic emulate ios --target=&#34;iPad-Air, 8.1&#34;
</code></pre><p>The emulator will now load our app in an iPad Air simulator running iOS 8.1:</p>
<p><img src="/images/posts/ionic2-audio-recorder/ios-simulator-ipad.png" alt="Simulator iPad"></p>
<h2 id="running-on-a-device">Running on a device</h2>
<p>Although running our app in a simulator is fine, the ultimate test would be to run our app on a physical device. As I want to run our app on my iPhone, I need to make sure our app supports the iOS platform. Luckily for us, we already allowed our app to run on iOS when we ran our app in the simulator.</p>
<p>After having connected our iPhone to our MacBook, we then run:</p>
<pre tabindex="0"><code>ionic run ios
</code></pre><p>This should run our app on our device, but even though my device <em>is</em> recognized, an error occurs:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>After some <a href="https://github.com/driftyco/ionic-cli/issues/1197">Googling</a>, I found that this problem can be fixed by appending <code>--device</code>:</p>
<pre tabindex="0"><code>ionic run ios --device
</code></pre><p>Similar to running our app on the simulator, our app is compiled to a native app:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>After a short while, our app will be displayed on our phone (make sure to have your phone unlocked):</p>
<p><img src="/images/posts/ionic2-audio-recorder/iphone-app.png" alt="App on iPhone"></p>
<p>Clicking on the &ldquo;Start recording&rdquo; button now issues the following prompt:</p>
<p><img src="/images/posts/ionic2-audio-recorder/iphone-app-request-microphone.png" alt="Request microphone access on iPhone"></p>
<p>If we click &ldquo;OK&rdquo;, we can now verify that our app also works on an iPhone.</p>
<h2 id="running-on-a-device-using-ionic-view">Running on a device using Ionic View</h2>
<p>Besides viewing our app in a browser, simulator or on a device, there is a fourth option: the <a href="http://view.ionic.io/">Ionic View</a> app. With this option, you install the Ionic View app on your iOS or Android device, which you can then use to test your apps with.</p>
<p>To do so, simply run:</p>
<pre tabindex="0"><code>ionic upload
</code></pre><p>Its output will look like this:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>To upload our app, we first had to login to our Ionic account. If you don&rsquo;t have one, you can create one <a href="https://apps.ionic.io/signup">here</a>. After signing in, the app is uploaded and can be accessed in the Ionic View app.</p>
<p>Before we&rsquo;ll see what that looks like, notice that the build output also issued a warning:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>This warning indicates that the <code>upload</code> Gulp task does not depend on any other task. If you want to be ensure that you&rsquo;ll always upload the latest version of your app, you need to make sure that the <code>upload</code> task depends on the <code>build</code> task. Fixing this is easy, just add the following line to <code>gulpfile.js</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;upload:before&#34;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&#34;build&#34;</span><span class="p">]);</span>
</span></span></code></pre></div><p>Having uploaded our app, let&rsquo;s open the Ionic View app to see what it looks like:</p>
<p><img src="/images/posts/ionic2-audio-recorder/iphone-ionic-view.png" alt="Ionic View"></p>
<p>We can see that we have access to one app: the one we just uploaded. If we click on it, we get the following menu:</p>
<p><img src="/images/posts/ionic2-audio-recorder/iphone-ionic-view-menu.png" alt="Ionic View app menu"></p>
<p>The available options are fairly straightforward. We&rsquo;ll use the &ldquo;View app&rdquo; button to run our app:</p>
<p><img src="/images/posts/ionic2-audio-recorder/iphone-ionic-view-running.png" alt="App running in Ionic View"></p>
<p>As you can see, running the app from the Ionic View app looks identical to running the app directly on our device. Furthermore, as Ionic View is a native app with access to all native capabilities, our app still perfectly records audio.</p>
<h3 id="sharing-with-other-people">Sharing with other people</h3>
<p>Up until now, we tested our app ourselves. But what if we want other people to test our app? Well, simple! Just use the <code>ionic share</code> command:</p>
<pre tabindex="0"><code>ionic share coworker@test.com
</code></pre><p>So what does this command do? Let&rsquo;s examine its output:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>You can see that an email invite was sent to the specified email address. This email contains instructions on how to preview our app. In short, what the user must do is:</p>
<ol>
<li>Create an Ionic account.</li>
<li>Install the Ionic View app.</li>
<li>Follow the instructions in the email invite.</li>
</ol>
<p>Having followed these three steps, the user will have access to our app from within their Ionic View app installation.</p>
<p>Note that the version of the app they will receive, will be the latest version that was uploaded through <code>ionic upload</code>.</p>
<h2 id="extracting-the-recording-functionality">Extracting the recording functionality</h2>
<p>At the moment, the audio recording and playback functionality was added directly to the <code>HomePage</code> class. As a consequence, if we want to use the audio functionality somewhere else in our app, we&rsquo;d have to either duplicate the code or extract the audio functionality into a separate class. Let&rsquo;s try the second option.</p>
<p>First, we&rsquo;ll create a <code>services</code> directory in our <code>app</code> directory. Within the <code>services</code> directory, create a TypeScript file named <code>audiorecorder.ts</code>, in which we&rsquo;ll define an <code>AudioRecorder</code> class. Extracting the audio recording functionality from our <code>HomePage</code> class, we end up with the following class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">MediaPlugin</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;ionic-native&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">AudioRecorder</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">media</span><span class="o">:</span> <span class="nx">MediaPlugin</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">constructor</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MediaPlugin</span><span class="p">(</span><span class="s2">&#34;../Library/NoCloud/recording.wav&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">startRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">startRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">stopRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">stopRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">startPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">play</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">stopPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">media</span><span class="p">.</span><span class="nx">stop</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Looks quite nice, agreed? There is another, obvious refactoring. The <code>MediaPlugin</code> instance only really needs to be created when it is first used, so let&rsquo;s delay creating the <code>MediaPlugin</code> instance:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">AudioRecorder</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">mediaPlugin</span><span class="o">:</span> <span class="nx">MediaPlugin</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">get</span> <span class="nx">MediaPlugin</span><span class="p">()</span><span class="o">:</span> <span class="nx">MediaPlugin</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">mediaPlugin</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">this</span><span class="p">.</span><span class="nx">mediaPlugin</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MediaPlugin</span><span class="p">(</span><span class="s2">&#34;../Library/NoCloud/recording.wav&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">mediaPlugin</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">startRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">startRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">stopRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">stopRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">startPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">play</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">stopPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">stop</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Finally, wouldn&rsquo;t it be nice if we could inject this class, just like we did with the <code>AlertController</code>? Easy. We just import the <code>Injectable</code> decorator and decorate our class with it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">Injectable</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@angular/core&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">@</span><span class="nx">Injectable</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">AudioRecorder</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>With all these changes, our <code>HomePage</code> class becomes a lot easier. First, we can replace the import of the <code>MediaPlugin</code> class with an import of our <code>AudioRecorder</code> class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">AudioRecorder</span> <span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;../../services/audiorecorder&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>If you are wondering how we arrived at this relative import path, consider the current layout of the <code>app</code> directory:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>You&rsquo;ll see that after moving up two directories from the <code>home.ts</code> file, we are in the <code>app</code> directory. Then it&rsquo;s into to the <code>services</code> directory and its <code>audiorecorder.ts</code> file (note that you should omit the file&rsquo;s extension).</p>
<p>Next, we&rsquo;ll add the <code>AudioRecorder</code> to the list of providers for our class (to ensure it can be <a href="http://www.joshmorony.com/an-in-depth-explanation-of-providers-in-ionic-2/">injected</a>) and add it as a parameter to our constructor:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="err">@</span><span class="nx">Component</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">templateUrl</span><span class="o">:</span> <span class="s1">&#39;build/pages/home/home.html&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">providers</span><span class="o">:</span> <span class="p">[</span><span class="nx">AudioRecorder</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">HomePage</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">constructor</span><span class="p">(</span><span class="kr">public</span> <span class="nx">navCtrl</span><span class="o">:</span> <span class="nx">NavController</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="kr">public</span> <span class="nx">alertCtrl</span><span class="o">:</span> <span class="nx">AlertController</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="kr">public</span> <span class="nx">audioRecorder</span><span class="o">:</span> <span class="nx">AudioRecorder</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Note that due to the lazy initialization of the <code>MediaPlugin</code> instance in the <code>AudioRecorder</code> class, we no longer have to defer creating the instance to the <code>ionViewLoaded</code> function.</p>
<p>Finally, we&rsquo;ll update the audio handling functions to use our <code>AudioRecorder</code> instance:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">startRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">audioRecorder</span><span class="p">.</span><span class="nx">startRecording</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not start recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">stopRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">audioRecorder</span><span class="p">.</span><span class="nx">stopRecording</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not stop recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">startPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">audioRecorder</span><span class="p">.</span><span class="nx">startPlayback</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not play recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">stopPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">audioRecorder</span><span class="p">.</span><span class="nx">stopPlayback</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">showAlert</span><span class="p">(</span><span class="s1">&#39;Could not stop playing recording.&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we test our refactored app, we&rsquo;ll find it still works as expected, but our code now has much better separation of concerns.</p>
<h2 id="updating-the-user-interface">Updating the user-interface</h2>
<p>Although we can record audio in our app, the interface could use some refinement. For example, we should only allow people to click on the &ldquo;Start playback&rdquo; button once something has actually been recorded. Similarly, we shouldn&rsquo;t allow people to stop recording when nothing is being recorded. The status of the buttons thus depends on the &ldquo;state&rdquo; of the audio recorder. We&rsquo;ll model this by adding the following enum to the <code>audiorecorder.ts</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">enum</span> <span class="nx">AudioRecorderState</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">Ready</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">Recording</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">Recorded</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">Playing</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We then add a <code>RecordingState</code> field to the <code>AudioRecorder</code> and update it in each function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">AudioRecorder</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">state</span><span class="o">:</span> <span class="nx">AudioRecorderState</span> <span class="o">=</span> <span class="nx">AudioRecorderState</span><span class="p">.</span><span class="nx">Ready</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">startRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">startRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">AudioRecorderState</span><span class="p">.</span><span class="nx">Recording</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">stopRecording</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">stopRecord</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">AudioRecorderState</span><span class="p">.</span><span class="nx">Recorded</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">startPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">play</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">AudioRecorderState</span><span class="p">.</span><span class="nx">Playing</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">stopPlayback</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">MediaPlugin</span><span class="p">.</span><span class="nx">stop</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">AudioRecorderState</span><span class="p">.</span><span class="nx">Ready</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The last step is to dynamically enable and disable buttons depending on the audio recorder&rsquo;s state. For that, we&rsquo;ll modify the <code>home.html</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startRecording</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Ready</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Start recording
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopRecording</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Recording</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Stop recording
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startPlayback</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Recorded</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Start playback
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopPlayback</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Playing</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Stop playback
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Unfortunately, when we try to run our app, we get an error:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>The problem is that our view doesn&rsquo;t know about the <code>AudioRecorderState</code> enum. To fix this, we&rsquo;ll also import the <code>AudioRecorderState</code> in our <code>home.ts</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">AudioRecorder</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">AudioRecorderState</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="nx">from</span> <span class="s2">&#34;../../services/audiorecorder&#34;</span><span class="p">;</span>
</span></span></code></pre></div><p>Then, we add it as a field to our <code>HomePage</code> class, which allows our view to access its values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">class</span> <span class="nx">HomePage</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">AudioRecorderState</span> <span class="o">=</span> <span class="nx">AudioRecorderState</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This time, things work as we expected them to:</p>
<p><img src="/images/posts/ionic2-audio-recorder/ios-simulator-improved-gui.png" alt="Dynamically enabled buttons"></p>
<p>At first, only the &ldquo;Start recording&rdquo; button is enabled. Once we press that, only the &ldquo;Stop recording&rdquo; button is enabled, and so on.</p>
<h3 id="adding-color-and-icons">Adding color and icons</h3>
<p>The finishing touch is to give each button its own color and icon. Let&rsquo;s start with the colors. First, we&rsquo;ll add classes to our buttons in <code>home.html</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startRecording</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-start-recording&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Ready</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Start recording
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopRecording</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-stop-recording&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Recording</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Stop recording
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startPlayback</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-start-playback&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Recorded</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Start playback
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopPlayback</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-stop-playback&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Playing</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Stop playback
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Next, we&rsquo;ll create the styles for these newly added classes. We&rsquo;ll do that in <code>home.scss</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-start-recording</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-start-recording</span><span class="p">.</span><span class="nc">activated</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="kc">red</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-start-recording</span><span class="p">:</span><span class="nd">hover</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="p">.</span><span class="nc">disable-hover</span><span class="o">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="mh">#ff6666</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-stop-recording</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-stop-recording</span><span class="p">.</span><span class="nc">activated</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="kc">orange</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-stop-recording</span><span class="p">:</span><span class="nd">hover</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="p">.</span><span class="nc">disable-hover</span><span class="o">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="mh">#ffc966</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-start-playback</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-start-playback</span><span class="p">.</span><span class="nc">activated</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="kc">green</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-start-playback</span><span class="p">:</span><span class="nd">hover</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="p">.</span><span class="nc">disable-hover</span><span class="o">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="mh">#80ff80</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-stop-playback</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-stop-playback</span><span class="p">.</span><span class="nc">activated</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="kc">blue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">buttton-stop-playback</span><span class="p">:</span><span class="nd">hover</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="p">.</span><span class="nc">disable-hover</span><span class="o">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">background-color</span><span class="p">:</span> <span class="mh">#387ef5</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we preview our app using these changes, the buttons will have different background colors:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-button-colors.png" alt="Button colors"></p>
<p>Our final improvement is to add <a href="http://ionicframework.com/docs/v2/ionicons/">icons</a> to the buttons. Adding an icon to our buttons is simple: just add an <code>&lt;ion-icon&gt;</code> component with the correct <code>name</code> attribute nested in the <code>&lt;button&gt;</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startRecording</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-start-recording&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Ready</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ion-icon</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;microphone&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">ion-icon</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Start recording
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopRecording</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-stop-recording&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Recording</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ion-icon</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;mic-off&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">ion-icon</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Stop recording
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">startPlayback</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-start-playback&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Recorded</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ion-icon</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;play&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">ion-icon</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Start playback
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span>
</span></span><span class="line"><span class="cl">    <span class="err">(</span><span class="na">click</span><span class="err">)=&#34;</span><span class="na">stopPlayback</span><span class="err">()&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="na">class</span><span class="o">=</span><span class="s">&#34;buttton-stop-playback&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="err">[</span><span class="na">disabled</span><span class="err">]=&#34;</span><span class="na">audioRecorder</span><span class="err">.</span><span class="na">state</span> <span class="err">!=</span> <span class="na">AudioRecorderState</span><span class="err">.</span><span class="na">Playing</span><span class="err">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">ion-icon</span> <span class="na">name</span><span class="o">=</span><span class="s">&#34;square&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">ion-icon</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    Stop playback
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Let&rsquo;s preview these changes using the multi-platform preview mode:</p>
<p><img src="/images/posts/ionic2-audio-recorder/browser-button-icons.png" alt="Button icons"></p>
<p>Looks much better, right? Those of you with a keen eye may have noticed that some icons will look different between platforms, which Ionic does automatically to better match each platform&rsquo;s look-and-feel.</p>
<h2 id="source-code">Source code</h2>
<p>If you&rsquo;d like to test the application yourself, the full source code can be found in my <a href="https://github.com/ErikSchierboom/ionic2-audio-recorder">ionic2-audio-recorder</a> repository.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Building native apps can be frustrating due to the lack of code sharing between the various platforms. With Ionic 2, you can build native mobile apps for multiple platforms from a single code base, using just HTML, JavaScript and CSS. This makes building an app quite similar to building a regular website.</p>
<p>Building our audio recorder app using Ionic 2 app turned out to be quite easy. Using just HTML and Ionic&rsquo;s custom components, we created an app that looks like a proper native app. Even building the audio recording code was not very hard, due to Ionic Native giving us an easy to use API to handle audio with.</p>
<p>With helpful tools such as the Ionic CLI, a browser preview mode and the Ionic View app, building and sharing mobile apps has never been as easy or fun!</p>
]]></content>
		</item>
		
		<item>
			<title>Property-based testing</title>
			<link>https://www.erikschierboom.com/2016/02/22/property-based-testing/</link>
			<pubDate>Mon, 22 Feb 2016 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2016/02/22/property-based-testing/</guid>
			<description>Writing unit tests helps verify the correctness of code. However, most unit tests only test a limited set of pre-defined input values, often just one. Testing with fixed input values is known as example-based tests.
The problem with example-based tests is that they only verify correctness for the pre-defined input values. This can easily lead to an implementation that passes the test for the pre-defined values, but fails for any other value.</description>
			<content type="html"><![CDATA[<p>Writing unit tests helps verify the correctness of code. However, most unit tests only test a limited set of pre-defined input values, often just one. Testing with fixed input values is known as example-based tests.</p>
<p>The problem with example-based tests is that they only verify correctness for the pre-defined input values. This can easily lead to an implementation that passes the test for the pre-defined values, but fails for any other value. The implementation could thus be (largely) incorrect, even though the test passes.</p>
<p>Let&rsquo;s demonstrate this through an example. Note that we&rsquo;ll use <a href="https://xunit.github.io/">xUnit.net</a> as the test framework in our examples.</p>
<h2 id="single-input-value">Single input value</h2>
<p>Suppose we want to write a method that calculates the <a href="https://en.wikipedia.org/wiki/MD5">MD5 hash</a> of a given string. Let&rsquo;s start by writing a unit test:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Fact]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsCorrectHash</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">input</span> <span class="p">=</span> <span class="s">&#34;foo&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">md5</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">expected</span> <span class="p">=</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="n">expected</span><span class="p">,</span> <span class="n">md5</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This test method use a single input value (<code>&quot;foo&quot;</code>) to verify the correctness of the <code>MD5()</code> method. Therefore, this is an example-based test. To make this test pass, we can implement the <code>MD5()</code> method as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Clearly, this implementation does <strong>not</strong> correctly implement the MD5 algorithm, but it passes our test! The danger of using one input value to verify correctness is that you can make the test pass by just hard-coding the expected result.</p>
<p>Note that in TDD, you actually <em>should</em> write the minimal amount of code to make the test pass, so the above implementation is perfectly reasonable when doing TDD.</p>
<p>In the next section, we&rsquo;ll see how to strengthen our test by using multiple input values.</p>
<h2 id="multiple-input-values">Multiple input values</h2>
<p>The obvious solution to strengten tests that use one input value, is to use several input values. One way to do this is to create copies of the existing test method, but with different input values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Fact]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ForFooInputReturnsCorrectHash</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">md5</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="s">&#34;foo&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">,</span> <span class="n">md5</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="na">
</span></span></span><span class="line"><span class="cl"><span class="na">[Fact]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ForBarInputReturnsCorrectHash</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">md5</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="s">&#34;bar&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">,</span> <span class="n">md5</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="na">
</span></span></span><span class="line"><span class="cl"><span class="na">[Fact]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ForBazInputReturnsCorrectHash</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">md5</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="s">&#34;baz&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">,</span> <span class="n">md5</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Although there is nothing wrong with these three tests, we have some code duplication. Luckily, xUnit has the concept of <em>parameterized tests</em>, which allows us to define a single test with more than one input value.</p>
<p>Here is the parameterized test equivalent of our previous three tests:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Theory]</span>
</span></span><span class="line"><span class="cl"><span class="na">[InlineData(&#34;foo&#34;, &#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="na">[InlineData(&#34;bar&#34;, &#34;37b51d194a7513e45b56f6524f2d51f2&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="na">[InlineData(&#34;baz&#34;, &#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsCorrectHash</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">,</span> <span class="kt">string</span> <span class="n">expected</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">md5</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="n">expected</span><span class="p">,</span> <span class="n">md5</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This test differs from our previous tests in several ways:</p>
<ul>
<li>The <code>[Fact]</code> attribute is replaced with the <code>[Theory]</code> attribute. This marks the test as a parameterized test.</li>
<li>The test method has two parameters: <code>input</code> and <code>expected</code>, which replace the hard-coded values in our test.</li>
<li>Three <code>[InlineData]</code> attributes have been added, one for each input value/expected hash combination.</li>
</ul>
<p>When xUnit runs this test, it will actually run it three times, with the <code>[InlineData]</code> attributes&rsquo; parameters used as the <code>input</code> and <code>expected</code> parameters. Therefore, running our parameterized test results in our test being called three times with the following arguments:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">MD5ReturnsCorrectHash</span><span class="p">(</span><span class="s">&#34;foo&#34;</span><span class="p">,</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">MD5ReturnsCorrectHash</span><span class="p">(</span><span class="s">&#34;bar&#34;</span><span class="p">,</span> <span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">MD5ReturnsCorrectHash</span><span class="p">(</span><span class="s">&#34;baz&#34;</span><span class="p">,</span> <span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>If we run our parameterized test, it will fail for the <code>&quot;bar&quot;</code> and <code>&quot;baz&quot;</code> input values. To make our test pass, we could again hard-code the expected values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;foo&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;bar&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;baz&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">input</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>With this modified implementation, the test passes for all three input values. Unfortunately, having multiple tests still allowed us to easily hard-code the implementation; it did not prevent us from incorrectly implementing the MD5 algorithm.</p>
<p>So although having multiple input values leads to stronger tests, it still remains a limited set of input values. Wouldn&rsquo;t it be great if we could run our tests using <em>all</em> possible input values? Enter property-based testing.</p>
<h2 id="property-based-testing">Property-based testing</h2>
<p>In property-based testing, we take a different approach to writing our tests. Instead of testing for specific input and output values, we test the <em>properties</em> of the code we are testing. You can think of properties as rules, invariants or requirements. For example, these are some essential properties of the MD5 algorithm:</p>
<ol>
<li>The hash is 32 characters long.</li>
<li>The hash only contains hexadecimal characters.</li>
<li>Equal inputs have the same hash.</li>
<li>The hash is different from its input.</li>
<li>Similar inputs have significantly different hashes.</li>
</ol>
<p>So how do we write tests for these properties? First, notice that these five properties are generic: they must be true for <em>all</em> possible input values. Unfortunately, writing tests that actually check all input values is not feasible, as running them would take ages. But if we can&rsquo;t test all input values, how can we write tests for our properties? Well, we use the next best thing: random input values.</p>
<p>If you test using random input values, hard-coding the expected values is no longer possible as you don&rsquo;t know beforehand which input values will be tested. This forces you to write a generic implementation that works for any (valid) input value.</p>
<p>Let&rsquo;s see how that works by writing property-based tests for all five properties we just defined.</p>
<h3 id="property-1-hash-is-32-characters-long">Property 1: hash is 32 characters long</h3>
<p>Our first property states that an MD5 hash is a string of length 32. If we would write this as a regular, example-based test, it would look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Fact]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringOfCorrectLength</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">input</span> <span class="p">=</span> <span class="s">&#34;foo&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="m">32</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We could strengthen our test by converting it to a parameterized test with several input values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Theory]</span>
</span></span><span class="line"><span class="cl"><span class="na">[InlineData(&#34;foo&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="na">[InlineData(&#34;bar&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="na">[InlineData(&#34;baz&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringOfCorrectLength</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="m">32</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>However, as said, property-based tests should work with <em>any</em> input value. A property-based test is thus a parameterized test, but with the pre-defined input values replaced by random input values. Our initial attempt at writing a property-based test might look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Theory]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringOfCorrectLength</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="m">32</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Unfortunately, if we run this test, we&rsquo;ll find that xUnit reports an error for parameterized tests without input.</p>
<p>To define a test that works with randomly generated input, we&rsquo;ll use the <a href="https://fscheck.github.io/FsCheck/">FsCheck</a> property-based testing framework. We&rsquo;ll also install the <a href="https://www.nuget.org/packages/FsCheck.Xunit/">FsCheck.Xunit</a> package, for easy integration of FsCheck with xUnit.</p>
<p>Having installed these libraries, we can convert our test to a property-based test by decorating it with the <code>[Property]</code> attribute:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Property]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringOfCorrectLength</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="m">32</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Note that we don&rsquo;t explicitly specify the input value(s) to use, FsCheck will (randomly) generate those. Let&rsquo;s run this test to see what happens:</p>
<pre tabindex="0"><code>MD5ReturnsStringOfCorrectLength [FAIL]

    FsCheck.Xunit.PropertyFailedException :
    Falsifiable, after 1 test (0 shrinks) (StdGen (766423555,296119444)):
    Original:
    &#34;&#34;

    ---- Assert.Equal() Failure
    Expected: 32
    Actual:   0
</code></pre><p>The test report indicates that our property-based test failed after one test, for the randomly generated empty string (<code>&quot;&quot;</code>) input value. To make our empty string pass the test, we&rsquo;ll pad unknown inputs to a length of 32:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;foo&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;bar&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;baz&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">input</span><span class="p">.</span><span class="n">PadRight</span><span class="p">(</span><span class="m">32</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This should fix the empty string problem, so let&rsquo;s run the test again:</p>
<pre tabindex="0"><code>MD5ReturnsStringOfCorrectLength [FAIL]

    FsCheck.Xunit.PropertyFailedException :
    Falsifiable, after 12 tests (0 shrinks) (StdGen (1087984417,296119448)):
    Original:
    &lt;null&gt;

    ---- System.NullReferenceException : Object reference not set to an instance of an object
</code></pre><p>Hmmm, our test still fails. This time though, the first 11 tests passed, so we made some progress. The test now failed when FsCheck generated the <code>null</code> input value. Let&rsquo;s fix this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;foo&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;bar&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;baz&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="n">input</span> <span class="p">??</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">).</span><span class="n">PadRight</span><span class="p">(</span><span class="m">32</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>And we run our test again:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">MD5ReturnsStringOfCorrectLength <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">    Falsifiable, after <span class="m">43</span> tests <span class="o">(</span><span class="m">34</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>964736467,296119643<span class="o">))</span>:
</span></span><span class="line"><span class="cl">    Original:
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;#e3n+[TC9[Jlbs,x=3U!f\~J&#39;i u+)-y&gt;4VLg]uA(&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    Shrunk:
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- Assert.Equal<span class="o">()</span> Failure
</span></span><span class="line"><span class="cl">    Expected: <span class="m">32</span>
</span></span><span class="line"><span class="cl">    Actual:   <span class="m">33</span>
</span></span></code></pre></div><p>Again, more progress, as it now took 43 tests before the test failed for the input value <code>&quot;#e3n+[TC9[Jlbs,x=3U!f\~J'i u+)-y&gt;4VLg]uA(&quot;</code>. There is something different about the test report this time though, as it mentions &ldquo;34 shrinks&rdquo; and a &ldquo;shrunk&rdquo; value, what is that about?</p>
<h4 id="shrinking">Shrinking</h4>
<p>In property-based testing, shrinking is used to find a minimal counter-example that proves the property does <strong>not</strong> hold for all possible input values. This minimal counter example is listed as the &ldquo;shrunk&rdquo; in our test report. Before we examine how shrinking works, try to figure out for yourself what&rsquo;s so special about the &ldquo;shrunk&rdquo; <code>&quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot;</code> input value mentioned in the test report.</p>
<p>If you guessed that the specified &ldquo;shrunk&rdquo; input was special for its length, you&rsquo;d be correct! The <code>&quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot;</code> string contains 33 characters, which significance becomes apparent if we look at the code in our implementation that processes this input value:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">return</span> <span class="p">(</span><span class="n">input</span> <span class="p">??</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">).</span><span class="n">PadRight</span><span class="p">(</span><span class="m">32</span><span class="p">);</span>
</span></span></code></pre></div><p>If we use <code>&quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot;</code> as our input, the <code>PadRight(32)</code> call doesn&rsquo;t do anything as our string is already greater than or equal to 32. Therefore, the input value is returned unmodified, which means that the string that is returned also has length 33, which fails our test.</p>
<p>The interesting thing about an input value of length 33 is that 33 is the <em>minimum</em> length for which the test fails; strings of length 32 or less all pass the test. As such, the listed &ldquo;shrunk&rdquo; value of length 33 is a minimal counter-example to our property.</p>
<p>The main benefit of having a minimal counter-example is that is helps you locate precisely where your implementation breaks down (in our case for strings of length 33 and greater). You thus spend less time debugging and more writing code.</p>
<h5 id="finding-the-shrunk-value">Finding the &ldquo;shrunk&rdquo; value</h5>
<p>So how does FsCheck find this shrunk value? To find out, we&rsquo;ll have FsCheck output the values it generates. Doing that is easy, we just set the <code>Verbose</code> property of our <code>[Property]</code> attribute to <code>true</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Property(Verbose = true)]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringOfCorrectLength</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="m">32</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Now if we run our test, we&rsquo;ll see exactly which values FsCheck generated as test input:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">MD5ReturnsStringOfCorrectLength <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">    Falsifiable, after <span class="m">50</span> tests <span class="o">(</span><span class="m">38</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>1153044621,296119646<span class="o">))</span>:
</span></span><span class="line"><span class="cl">    Original:
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;XqyW\O!Lr%ce3]4=H~=6lG, 5lT\aDz%n9&#34;</span>
</span></span><span class="line"><span class="cl">    Shrunk:
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- Assert.Equal<span class="o">()</span> Failure
</span></span><span class="line"><span class="cl">    Expected: <span class="m">32</span>
</span></span><span class="line"><span class="cl">    Actual:   <span class="m">33</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    Output:
</span></span><span class="line"><span class="cl">    0: <span class="s2">&#34;5z&#34;</span>
</span></span><span class="line"><span class="cl">    1: <span class="s2">&#34;Y&#34;</span>
</span></span><span class="line"><span class="cl">    2: <span class="s2">&#34;r&#34;</span>
</span></span><span class="line"><span class="cl">    3: <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    4: <span class="s2">&#34;t9[Q&#34;</span>
</span></span><span class="line"><span class="cl">    ...
</span></span><span class="line"><span class="cl">    45: &lt;null&gt;
</span></span><span class="line"><span class="cl">    46: <span class="s2">&#34;Qlbz?|perK&#34;</span>
</span></span><span class="line"><span class="cl">    47: <span class="s2">&#34;XP3vO</span><span class="nv">$-</span><span class="s2">`l&#34;</span>
</span></span><span class="line"><span class="cl">    48: Y<span class="o">{</span>q6oevZA7<span class="s2">&#34;0R
</span></span></span><span class="line"><span class="cl"><span class="s2">    49: &#34;</span>XqyW<span class="se">\O</span>!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG, 5lT<span class="se">\a</span>Dz%n9<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>qyW<span class="se">\O</span>!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG, 5lT<span class="se">\a</span>Dz%n9<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>yW<span class="se">\O</span>!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG, 5lT<span class="se">\a</span>Dz%n9<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>yW<span class="se">\O</span>!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dz%n9<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>W<span class="se">\O</span>!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dz%n9<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span><span class="se">\O</span>!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dz%n9<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dz%n9<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dz%n9a<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dz%naa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dz%aaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Dzaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>Daaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lT<span class="se">\a</span>aaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lTaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5lTaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5laaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5laaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,5aaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,aaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lG,aaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6lGaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6laaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>6aaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~<span class="o">=</span>aaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>H~aaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>Haaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span><span class="nv">4</span><span class="o">=</span>aaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span>4aaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3<span class="o">]</span>aaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ce3aaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%ceaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%caaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%caaaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lr%aaaaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Lraaaaaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!Laaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>O!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>Oaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    shrink: &#34;</span>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<span class="s2">&#34;
</span></span></span></code></pre></div><p>The test report starts with the 50 randomly generated input values (note: we omitted most for brevity). The last input value (<code>&quot;XqyW\O!Lr%ce3]4=H~=6lG, 5lT\aDz%n9&quot;</code>), listed as input #49, is the first for which the test failed. Having found an input value that fails the test, FsCheck then starts the shrinking process.</p>
<p>To see how shrinking works, let&rsquo;s list the failing input value and the first six subsequent shrinks:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">| #   |                                Input | Length | Passes test |
</span></span><span class="line"><span class="cl">| --- | -----------------------------------: | ------ | ----------- |
</span></span><span class="line"><span class="cl">| 0   | &#34;XqyW\O!Lr%ce3]4=H~=6lG, 5lT\aDz%n9&#34; | 33     | false       |
</span></span><span class="line"><span class="cl">| 1   |  &#34;qyW\O!Lr%ce3]4=H~=6lG, 5lT\aDz%n9&#34; | 32     | true        |
</span></span><span class="line"><span class="cl">| 2   |   &#34;yW\O!Lr%ce3]4=H~=6lG, 5lT\aDz%n9&#34; | 31     | true        |
</span></span><span class="line"><span class="cl">| 3   |    &#34;yW\O!Lr%ce3]4=H~=6lG,5lT\aDz%n9&#34; | 30     | true        |
</span></span><span class="line"><span class="cl">| 4   |     &#34;W\O!Lr%ce3]4=H~=6lG,5lT\aDz%n9&#34; | 29     | true        |
</span></span><span class="line"><span class="cl">| 5   |      &#34;\O!Lr%ce3]4=H~=6lG,5lT\aDz%n9&#34; | 28     | true        |
</span></span><span class="line"><span class="cl">| 6   |       &#34;O!Lr%ce3]4=H~=6lG,5lT\aDz%n9&#34; | 27     | true        |
</span></span></code></pre></div><p>The pattern here is quite obvious: with each shrinking step, the previous value is stripped of its first character, decreasing the length by one. Note that all strings of length 32 or less pass the test. FsCheck will use this fact later on.</p>
<p>The next six shrinks follow a different pattern:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">| #   |                           Input | Length | Passes test |
</span></span><span class="line"><span class="cl">| --- | ------------------------------: | ------ | ----------- |
</span></span><span class="line"><span class="cl">| 7   | &#34;O!Lr%ce3]4=H~=6lG,5lT\aDz%n9a&#34; | 28     | true        |
</span></span><span class="line"><span class="cl">| 8   | &#34;O!Lr%ce3]4=H~=6lG,5lT\aDz%naa&#34; | 28     | true        |
</span></span><span class="line"><span class="cl">| 9   | &#34;O!Lr%ce3]4=H~=6lG,5lT\aDz%aaa&#34; | 28     | true        |
</span></span><span class="line"><span class="cl">| 10  | &#34;O!Lr%ce3]4=H~=6lG,5lT\aDzaaaa&#34; | 28     | true        |
</span></span><span class="line"><span class="cl">| 11  | &#34;O!Lr%ce3]4=H~=6lG,5lT\aDaaaaa&#34; | 28     | true        |
</span></span><span class="line"><span class="cl">| 12  | &#34;O!Lr%ce3]4=H~=6lG,5lT\aaaaaaa&#34; | 28     | true        |
</span></span></code></pre></div><p>This time, each shrink step replaces one character with the <code>'a'</code> character. FsCheck uses this shrink strategy to check if replacing specific characters in the input string can make the test fail.</p>
<p>As changing characters in the input values did not make the test fail, FsCheck then uses the fact that the only input value that failed the test had a length of 33. It therefore modifies its shrinking strategy and starts generating longer input values, which will lead to generating a 33 length input. Besides generating longer input values, it will additionaly also use the one character modification shrinking strategy as an extra check. This leads to the following sequence of shrinks:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">| #   | Input                              | Length | Passes test |
</span></span><span class="line"><span class="cl">| --- | :--------------------------------- | ------ | ----------- |
</span></span><span class="line"><span class="cl">| 13  | &#34;O!Lr%ce3]4=H~=6lG,5lTaaaaaaaa&#34;    | 29     | true        |
</span></span><span class="line"><span class="cl">| 14  | &#34;O!Lr%ce3]4=H~=6lG,5lTaaaaaaaaa&#34;   | 30     | true        |
</span></span><span class="line"><span class="cl">| 15  | &#34;O!Lr%ce3]4=H~=6lG,5laaaaaaaaaa&#34;   | 30     | true        |
</span></span><span class="line"><span class="cl">| 16  | &#34;O!Lr%ce3]4=H~=6lG,5laaaaaaaaaaa&#34;  | 31     | true        |
</span></span><span class="line"><span class="cl">| 17  | &#34;O!Lr%ce3]4=H~=6lG,5aaaaaaaaaaaa&#34;  | 31     | true        |
</span></span><span class="line"><span class="cl">| 18  | &#34;O!Lr%ce3]4=H~=6lG,aaaaaaaaaaaaa&#34;  | 31     | true        |
</span></span><span class="line"><span class="cl">| 19  | &#34;O!Lr%ce3]4=H~=6lG,aaaaaaaaaaaaaa&#34; | 32     | true        |
</span></span><span class="line"><span class="cl">| 20  | &#34;O!Lr%ce3]4=H~=6lGaaaaaaaaaaaaaaa&#34; | 32     | true        |
</span></span></code></pre></div><p>The 11 shrinks that follow these shrinks are all 32 character strings with one character replaced, which all pass the test. Things start getting interesting from shrink #32, which is a string of length 33 and thus fails the test:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">| #   | Input                               | Length | Passes test |
</span></span><span class="line"><span class="cl">| --- | ----------------------------------- | ------ | ----------- |
</span></span><span class="line"><span class="cl">| 32  | &#34;O!Lr%caaaaaaaaaaaaaaaaaaaaaaaaaaa&#34; | 33     | false       |
</span></span></code></pre></div><p>At this point, FsCheck correctly infers that strings of length 33 form the minimal set of counter-examples to our property. The final shrinking steps again use the single character replacement shrinking strategy, to see if changing a single character in an input value of length 33 can make the test pass:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">| #   | Input                               | Length | Passes test |
</span></span><span class="line"><span class="cl">| --- | ----------------------------------- | ------ | ----------- |
</span></span><span class="line"><span class="cl">| 33  | &#34;O!Lr%aaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34; | 33     | false       |
</span></span><span class="line"><span class="cl">| 34  | &#34;O!Lraaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34; | 33     | false       |
</span></span><span class="line"><span class="cl">| 35  | &#34;O!Laaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34; | 33     | false       |
</span></span><span class="line"><span class="cl">| 36  | &#34;O!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34; | 33     | false       |
</span></span><span class="line"><span class="cl">| 37  | &#34;Oaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34; | 33     | false       |
</span></span><span class="line"><span class="cl">| 38  | &#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34; | 33     | false       |
</span></span></code></pre></div><p>Even with all characters changed, the input still fails the test. At this point, FsCheck considers the input value <code>&quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot;</code> to be the minimal counter-example (or &ldquo;shrunk&rdquo;) to our property-based test.</p>
<p>Now that we know our test fails for strings of length 33 (and greater), we can fix our implementation as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;foo&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;bar&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;baz&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="n">input</span> <span class="p">??</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">).</span><span class="n">PadRight</span><span class="p">(</span><span class="m">32</span><span class="p">).</span><span class="n">Substring</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">32</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Now, our test passes all generated inputs, and we have our first, working, property-based test!</p>
<p>Clearly, this single property test did not force us to write a correct implementation, but that is perfectly normal. With property-based testing, you usually need to write several property-based tests before you are finally forced to write a correct implementation, so let&rsquo;s move on to property two.</p>
<h3 id="property-2-hash-contains-only-hexadecimal-characters">Property 2: hash contains only hexadecimal characters</h3>
<p>Our second property states that the MD5 hash consists of only hexadecimal characters:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Property]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringWithOnlyAlphaNumericCharacters</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">allowed</span> <span class="p">=</span> <span class="s">&#34;0123456789abcdef&#34;</span><span class="p">.</span><span class="n">ToCharArray</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">All</span><span class="p">(</span><span class="n">hash</span><span class="p">,</span> <span class="n">c</span> <span class="p">=&gt;</span> <span class="n">Assert</span><span class="p">.</span><span class="n">Contains</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">allowed</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This test should fail for any input other than the <code>&quot;foo&quot;</code>, <code>&quot;bar&quot;</code> or <code>&quot;baz&quot;</code> strings, which indeed it does:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">MD5ReturnsStringWithOnlyAlphaNumericCharacters <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">    Falsifiable, after <span class="m">1</span> <span class="nb">test</span> <span class="o">(</span><span class="m">0</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>961984695,296121694<span class="o">))</span>:
</span></span><span class="line"><span class="cl">    Original:
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- Assert.All<span class="o">()</span> Failure: <span class="m">32</span> out of <span class="m">32</span> items in the collection did not pass.
</span></span><span class="line"><span class="cl">    <span class="o">[</span>31<span class="o">]</span>: Xunit.Sdk.ContainsException: Assert.Contains<span class="o">()</span> Failure
</span></span><span class="line"><span class="cl">        Not found: <span class="s1">&#39; &#39;</span>
</span></span><span class="line"><span class="cl">        In value:  Char<span class="o">[]</span> <span class="o">[</span><span class="s1">&#39;0&#39;</span>, <span class="s1">&#39;1&#39;</span>, <span class="s1">&#39;2&#39;</span>, <span class="s1">&#39;3&#39;</span>, <span class="s1">&#39;4&#39;</span>, ...<span class="o">]</span>
</span></span></code></pre></div><p>Let&rsquo;s fix this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;foo&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;bar&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;baz&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This implementation not only passes this test, but also all other tests. On to property three.</p>
<h3 id="property-3-same-hash-for-same-input">Property 3: same hash for same input</h3>
<p>This test verifies that when presented with the same input, the same hash is returned:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Property]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsSameHashForSameInput</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash1</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash2</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="n">hash1</span><span class="p">,</span> <span class="n">hash2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Simple enough, and the current implementation passes this test.</p>
<h3 id="property-4-hash-is-different-from-input">Property 4: hash is different from input</h3>
<p>Our next property verifies that the hash is different from the input value (which is an essential property of any hashing algorithm):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Property]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringDifferentFromInput</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">NotEqual</span><span class="p">(</span><span class="n">input</span><span class="p">,</span> <span class="n">hash</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>At the moment, this test will pass for every input string except <code>&quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot;</code>. That means that unless FsCheck randomly generates the <code>&quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot;</code> input value, the property-based test will pass and we would think our implementation was correct. Let&rsquo;s demonstrate this by adding an example-based test:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Fact]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringDifferentFromManyAsInput</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">input</span> <span class="p">=</span> <span class="s">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">NotEqual</span><span class="p">(</span><span class="n">input</span><span class="p">,</span> <span class="n">hash</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we run both the property-based and the example-based tests, only the example-based test fails:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">MD5ReturnsStringDifferentFromManyAsInput <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    Assert.NotEqual<span class="o">()</span> Failure
</span></span><span class="line"><span class="cl">    Expected: Not <span class="s2">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span>
</span></span><span class="line"><span class="cl">    Actual:   <span class="s2">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span>
</span></span></code></pre></div><p>This is one of the drawbacks of testing with random data: you can have tests that <em>sometimes</em> fail. In such cases, augmenting a property-based test with an example-based test can be quite useful.</p>
<p>The fix is simple of course:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;foo&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;acbd18db4cc2f85cedef654fccc4a4d8&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;bar&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;37b51d194a7513e45b56f6524f2d51f2&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;baz&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;73feffa4b7f6bb68e44cf984c85f6e88&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="s">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="s">&#34;bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s">&#34;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Let&rsquo;s move on to our last property.</p>
<h3 id="property-5-similar-inputs-have-non-similar-hashes">Property 5: similar inputs have non-similar hashes</h3>
<p>Our last property states a very important property of MD5 hashes: similar inputs should not return similar hashes. For example, the hash for the string <code>&quot;hello&quot;</code> should be completely different from the hash for the string <code>&quot;hello1&quot;</code>.</p>
<p>To write a test for this property, we have to define how we calculate the &ldquo;difference&rdquo; between two strings. In this case, we&rsquo;ll just use a simple algorithm that counts the number of positions where the strings have different characters. Obviously, this simple algorithm would normally not suffice, but it works for our purposes. Note that for previty we&rsquo;ll omit the actual implementation.</p>
<p>The property test looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Property]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5WithSimilarInputsInputsDoesNotReturnSimilarHashes</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">,</span> <span class="kt">char</span> <span class="n">addition</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">similar</span> <span class="p">=</span> <span class="n">input</span> <span class="p">+</span> <span class="n">addition</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash1</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash2</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">similar</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">difference</span> <span class="p">=</span> <span class="n">Difference</span><span class="p">(</span><span class="n">hash1</span><span class="p">,</span> <span class="n">hash2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">InRange</span><span class="p">(</span><span class="n">difference</span><span class="p">,</span> <span class="m">5</span><span class="p">,</span> <span class="m">32</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>In this test, we let FsCheck generate two input values: the input value and a character to append to the input value. We then calculate the hashes for the original and modified input, calculate the difference and verify that the difference is at least 5 characters (which is was chosen arbitrarily).</p>
<p>In we run our test again, it fails:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">MD5WithSimilarInputsInputsDoesNotReturnSimilarHashes <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">    Falsifiable, after <span class="m">1</span> <span class="nb">test</span> <span class="o">(</span><span class="m">2</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>1928700473,296121700<span class="o">))</span>:
</span></span><span class="line"><span class="cl">    Original:
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="s2">&#34;D&#34;</span>, <span class="s1">&#39;F&#39;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">    Shrunk:
</span></span><span class="line"><span class="cl">    <span class="o">(</span><span class="s2">&#34;&#34;</span>, <span class="s1">&#39;a&#39;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- Assert.InRange<span class="o">()</span> Failure
</span></span><span class="line"><span class="cl">    Range:  <span class="o">(</span><span class="m">5</span> - 32<span class="o">)</span>
</span></span><span class="line"><span class="cl">    Actual: <span class="m">0</span>
</span></span></code></pre></div><p>Modifying our implementation is still possible, but it becomes increasingly harder. At this point, we&rsquo;ll give in and correctly implement the MD5 algorithm:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">MD5</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">md5</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">Security</span><span class="p">.</span><span class="n">Cryptography</span><span class="p">.</span><span class="n">MD5</span><span class="p">.</span><span class="n">Create</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">inputBytes</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">Text</span><span class="p">.</span><span class="n">Encoding</span><span class="p">.</span><span class="n">ASCII</span><span class="p">.</span><span class="n">GetBytes</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">md5</span><span class="p">.</span><span class="n">ComputeHash</span><span class="p">(</span><span class="n">inputBytes</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">sb</span> <span class="p">=</span> <span class="k">new</span> <span class="n">StringBuilder</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="p">(</span><span class="kt">var</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">sb</span><span class="p">.</span><span class="n">Append</span><span class="p">(</span><span class="n">hash</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">ToString</span><span class="p">(</span><span class="s">&#34;x2&#34;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">sb</span><span class="p">.</span><span class="n">ToString</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Let&rsquo;s run all our test to verify they all pass:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">MD5WithSimilarInputsInputsDoesNotReturnSimilarHashes <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">      FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">      Falsifiable, after <span class="m">13</span> tests <span class="o">(</span><span class="m">1</span> shrink<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>1520259769,296121702<span class="o">))</span>:
</span></span><span class="line"><span class="cl">      Original:
</span></span><span class="line"><span class="cl">      <span class="o">(</span>null, <span class="s1">&#39;m&#39;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">      Shrunk:
</span></span><span class="line"><span class="cl">      <span class="o">(</span>null, <span class="s1">&#39;a&#39;</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- System.ArgumentNullException : String reference not <span class="nb">set</span> to an instance of a String.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">MD5ReturnsStringWithOnlyAlphaNumericCharacters <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">      FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">      Falsifiable, after <span class="m">8</span> tests <span class="o">(</span><span class="m">0</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>1521993499,296121702<span class="o">))</span>:
</span></span><span class="line"><span class="cl">      Original:
</span></span><span class="line"><span class="cl">      &lt;null&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- System.ArgumentNullException : String reference not <span class="nb">set</span> to an instance of a String.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">MD5ReturnsStringDifferentFromInput <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">      FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">      Falsifiable, after <span class="m">4</span> tests <span class="o">(</span><span class="m">0</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>1522075879,296121702<span class="o">))</span>:
</span></span><span class="line"><span class="cl">      Original:
</span></span><span class="line"><span class="cl">      &lt;null&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- System.ArgumentNullException : String reference not <span class="nb">set</span> to an instance of a String.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">MD5ReturnsSameHashForSameInput <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">    FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">    Falsifiable, after <span class="m">2</span> tests <span class="o">(</span><span class="m">0</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>1522087989,296121702<span class="o">))</span>:
</span></span><span class="line"><span class="cl">    Original:
</span></span><span class="line"><span class="cl">    &lt;null&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- System.ArgumentNullException : String reference not <span class="nb">set</span> to an instance of a String.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">MD5ReturnsStringOfCorrectLength <span class="o">[</span>FAIL<span class="o">]</span>
</span></span><span class="line"><span class="cl">    FsCheck.Xunit.PropertyFailedException :
</span></span><span class="line"><span class="cl">    Falsifiable, after <span class="m">28</span> tests <span class="o">(</span><span class="m">0</span> shrinks<span class="o">)</span> <span class="o">(</span>StdGen <span class="o">(</span>1522097819,296121702<span class="o">))</span>:
</span></span><span class="line"><span class="cl">    Original:
</span></span><span class="line"><span class="cl">    &lt;null&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ---- System.ArgumentNullException : String reference not <span class="nb">set</span> to an instance of a String.
</span></span></code></pre></div><p>Oh no, by correctly implementing the MD5 method, we made all our property-based tests fail! What happened? Well, previously, we correctly handled <code>null</code> input values in our implementation, but we don&rsquo;t anymore. If we think about it, <code>null</code> can be consider an invalid input value and throwing an <code>ArgumentNullException</code> is thus perfectly reasonable. We could write an example-based test to verify this behavior:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Fact]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5WithNullInputThrowsArgumentNullException</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Throws</span><span class="p">&lt;</span><span class="n">ArgumentNullException</span><span class="p">&gt;(()</span> <span class="p">=&gt;</span> <span class="n">MD5</span><span class="p">(</span><span class="kc">null</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>To fix our failing property-based tests, we should rephrase our properties to state that they only hold for valid (<em>non-null</em>) input values. Our next step is to make FsCheck only generate valid, non-null input values.</p>
<h4 id="customizing-input-value-generation">Customizing input value generation</h4>
<p>FsCheck generates values through a concept known as <em>arbitraries</em>. To fix our failing property tests, we&rsquo;ll define a function that returns a <code>Arbitrary&lt;string&gt;</code>, which FsCheck will use to generate strings with. Our custom <code>Arbitrary&lt;string&gt;</code> instance can generate <em>any</em> string, expect the <code>null</code> string.</p>
<p>To define our custom arbitrary, we create a class with a static method that returns an <code>Arbitrary&lt;string&gt;</code> instance:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">NonNullStringArbitrary</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">Arbitrary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">Strings</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">Arb</span><span class="p">.</span><span class="n">Default</span><span class="p">.</span><span class="n">String</span><span class="p">().</span><span class="n">Filter</span><span class="p">(</span><span class="n">x</span> <span class="p">=&gt;</span> <span class="n">x</span> <span class="p">!=</span> <span class="kc">null</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The <code>Strings()</code> method returns a modified <code>Arbitrary&lt;string&gt;</code> instance that filters out the <code>null</code> string. Note that the name of the method is arbitrary (pun intended), FsCheck will ignore the name and only look at the return type.</p>
<p>We can then use our custom arbitrary in our tests through the <code>Arbitrary</code> property of the <code>[Property]</code> attribute:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[Property(Arbitrary = new[]</span> <span class="p">{</span> <span class="k">typeof</span><span class="p">(</span><span class="n">NonNullStringArbitrary</span><span class="p">)</span> <span class="p">})]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringOfCorrectLength</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="m">32</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we now run our test, our custom arbitrary is used, which means the <code>null</code> input will not be generated and all our implementation passes all property-based tests!</p>
<p>To make using our custom arbitrary easier, we can create an attribute that derives from <code>PropertyAttribute</code> that automatically sets the <code>Arbitrary</code> property to our custom arbitrary:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">MD5PropertyAttribute</span> <span class="p">:</span> <span class="n">PropertyAttribute</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">MD5PropertyAttribute</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Arbitrary</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="k">typeof</span><span class="p">(</span><span class="n">NonNullStringArbitrary</span><span class="p">)</span> <span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now use this attribute instead of using a <code>[Property]</code> attribute:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[MD5Property]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">MD5ReturnsStringOfCorrectLength</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">MD5</span><span class="p">(</span><span class="n">input</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">Assert</span><span class="p">.</span><span class="n">Equal</span><span class="p">(</span><span class="m">32</span><span class="p">,</span> <span class="n">hash</span><span class="p">.</span><span class="n">Length</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Much better. The final step is to use this custom attribute on all our property-based tests. To verify we didn&rsquo;t break anything, we run all tests one more time and thankfully, they all still pass!</p>
<h2 id="regular-tests-or-property-tests">Regular tests or property tests?</h2>
<p>Now that we know how to write property-based tests, should we stop writing example-based tests? Well, probably not.</p>
<p>One problem with property-based tests is that it can be hard to identify a set of properties that completely cover the desired functionality. In those cases, it can be very useful to also define some example-based tests. This is what we did in our example. The five properties for which we wrote tests did not completely describe the MD5 algorithm though, which is why we also needed an additional parameterized example-based test to ensure the correctness of our implementation.</p>
<p>Furthermore, as example-based tests are less abstract, they are usually easier to understand. Defining some example-based tests in addition to your property-based tests, can thus help explain what you are testing.</p>
<h2 id="practicing">Practicing</h2>
<p>Propery-based testing is not easy to start with. Especially in the beginning, you&rsquo;ll probably struggle to identify properties. A good way to practice your property-based testing skills, is to solve the <a href="http://claysnow.co.uk/recycling-tests-in-tdd/">Diamond kata</a> using property-based testing.</p>
<p>If you&rsquo;d like to learn more about FsCheck and property-based testing, check out the following links:</p>
<ul>
<li><a href="http://fsharpforfunandprofit.com/posts/property-based-testing/">An introduction to property-based testing</a> (F#)</li>
<li><a href="http://blog.ploeh.dk/2015/01/10/diamond-kata-with-fscheck/">Diamond kata with FsCheck</a> (F#)</li>
<li><a href="https://blog.entelect.co.za/view/9742/a-gentle-introduction-to-property-based-testing">A (Gentle) Introduction to Property-based Testing</a> (C#)</li>
</ul>
<p>FsCheck is the most popular property-based framework for the .NET platform, but other platforms have their own implementation. The most well-known are <a href="https://wiki.haskell.org/Introduction_to_QuickCheck1">QuickCheck</a> (Haskell), and <a href="https://www.scalacheck.org/">ScalaCheck</a> (JVM), which both inspired FsCheck.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Although writing tests is important, the way you write your tests is equally important. To strengthen example-based tests, you should use as many inputs as possible. While multiple inputs are better than one input, property-based testing is even better as it works with <em>any</em> input value. It achieves this by randomly generating a large number of input values.</p>
<p>The random nature of property-based testing forces you to approach your tests differently. You don&rsquo;t focus on specific use cases, but on the general properties of the code you want to test. This helps you better understand the requirements of the code you want to test. Testing with random inputs also makes hard-coding an implementation using pre-defined input values extremely hard. Furthermore, the clever way in which property-based testing frameworks can provide minimal counter-examples, really helps identifying and fixing issues in your implementation.</p>
<p>The main problem with property-based testing is that it can be hard to get started with. In particular, figuring out what properties to test can be quite hard. Furthermore, property-based tests can fail to completely describe all aspects of the implementation. In those cases, you should augment property-based tests with regular example-based tests.</p>
]]></content>
		</item>
		
		<item>
			<title>C# 6 under the hood: nameof operator</title>
			<link>https://www.erikschierboom.com/2015/12/31/csharp6-under-the-hood-nameof/</link>
			<pubDate>Thu, 31 Dec 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/12/31/csharp6-under-the-hood-nameof/</guid>
			<description>In C# 6, the nameof operator allows you to retrieve the name of a variable, type or member.
Example The following example shows how you can use the nameof operator to retrieve the name of a namespace, class, method, parameter, property, field or variable:
using System; public class Program { private static DateTime Today = DateTime.Now; public string Name { get; set; } public static void Main(string[] args) { var localTime = DateTime.</description>
			<content type="html"><![CDATA[<p>In C# 6, the <code>nameof</code> operator allows you to retrieve the name of a variable, type or member.</p>
<h2 id="example">Example</h2>
<p>The following example shows how you can use the <code>nameof</code> operator to retrieve the name of a namespace, class, method, parameter, property, field or variable:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Program</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">static</span> <span class="n">DateTime</span> <span class="n">Today</span> <span class="p">=</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">string</span> <span class="n">Name</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">localTime</span> <span class="p">=</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">.</span><span class="n">ToLocalTime</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="err">åçéñøûß</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">localTime</span><span class="p">));</span>     <span class="c1">// &#34;localTime&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="err">åçéñøûß</span><span class="p">));</span>       <span class="c1">// &#34;åçéñøûß&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">args</span><span class="p">));</span>          <span class="c1">// &#34;args&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">));</span>     <span class="c1">// &#34;IO&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">Main</span><span class="p">));</span>          <span class="c1">// &#34;Main&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">Program</span><span class="p">));</span>       <span class="c1">// &#34;Program&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">Program</span><span class="p">.</span><span class="n">Today</span><span class="p">));</span> <span class="c1">// &#34;Today&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">Program</span><span class="p">.</span><span class="n">Name</span><span class="p">));</span>  <span class="c1">// &#34;Name&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="restrictions">Restrictions</h2>
<p>Although the <code>nameof</code> operator works with most language constructs, there are some restrictions. For example, you cannot use the <code>nameof</code> operator on open generic types or method return values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System.Collections.Generic</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Program</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">Main</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">List</span><span class="p">&lt;&gt;));</span> <span class="c1">// Compile-time error</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">Main</span><span class="p">()));</span> <span class="c1">// Compile-time error</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Furthermore, if you apply it to a generic type, the generic type parameter will be ignored:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System.Collections.Generic</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Program</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">Main</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;));</span>  <span class="c1">// &#34;List&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">List</span><span class="p">&lt;</span><span class="kt">bool</span><span class="p">&gt;));</span> <span class="c1">// &#34;List&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h2 id="when-to-use">When to use?</h2>
<p>So when should you use the <code>nameof</code> operator? The prime example are exceptions that take a parameter name as an argument. Consider the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">throw</span> <span class="k">new</span> <span class="n">ArgumentNullException</span><span class="p">(</span><span class="s">&#34;val&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If the <code>val</code> parameter is <code>null</code>, an <code>ArgumentNullException</code> is thrown with the parameter name (<code>&quot;val&quot;</code>) as a string argument. However, if we do a rename refactoring of the <code>val</code> parameter, the <code>&quot;val&quot;</code> string will not be modified. This results in the wrong parameter name being passed to the <code>ArgumentNullException</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">throw</span> <span class="k">new</span> <span class="n">ArgumentNullException</span><span class="p">(</span><span class="s">&#34;val&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Instead of hard-coding the parameter name as a string, we should use the <code>nameof</code> operator :</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">throw</span> <span class="k">new</span> <span class="n">ArgumentNullException</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">val</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As <code>nameof(val)</code> returns the string <code>&quot;val&quot;</code>, the functionality is unchanged. However, as the <code>nameof</code> operator references the <code>val</code> parameter, a rename refactoring of that parameter also changes the <code>nameof</code> operator&rsquo;s argument:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">input</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">input</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">throw</span> <span class="k">new</span> <span class="n">ArgumentNullException</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">input</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This time, the refactoring did not break anything - the correct parameter name is still passed to the <code>ArgumentNullException</code> constructor.</p>
<p>Now we know how to use the <code>nameof</code> operator, let&rsquo;s find out how it is implemented.</p>
<h2 id="under-the-hood">Under the hood</h2>
<p>One way to find out how a C# feature is implemented, is by looking at the <a href="https://en.wikipedia.org/wiki/Common_Intermediate_Language">Common Intermediate Language</a> (CIL) code the compiler generates. As a refresher, the following diagram describes how C# code is compiled:</p>
<p><img src="/images/posts/csharp6-under-the-hood-nameof/dotnet-compilation.svg" alt="Compilation of .NET code"></p>
<p>There are basically two steps:</p>
<ol>
<li>Compiling C# code to CIL code. This is done by the C# compiler and happens at <em>compile time</em>.</li>
<li>Compiling CIL code to native code. This is done by the CLR and happens at <em>runtime</em>.</li>
</ol>
<p>As C# code is compiled to CIL code, examining the generated CIL code gives us insight in how C# features are implemented by the compiler. As an example, C# properties are compiled to plain getter and setter methods at the CIL level.</p>
<p>Let&rsquo;s examine the CIL code that is generated for the aforementioned examples.</p>
<h3 id="cil-code-for-string-based-example">CIL code for string-based example</h3>
<p>To view the CIL code generated for our string-based example, we first have to compile it. Just as a reminder, this is the C# code for our string-based example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">throw</span> <span class="k">new</span> <span class="n">ArgumentNullException</span><span class="p">(</span><span class="s">&#34;val&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>To examine the CIL code the compiler generates, we compile our code. As this code is part of a console application, the C# compiler writes the CIL code to an executable.</p>
<p>To view the CIL code in the compiled executable, we can use a disassembler. We&rsquo;ll use <a href="https://msdn.microsoft.com/en-us/library/f7dy01k1(v=vs.110).aspx">ildasm</a>, which is a disassembler that comes pre-installed with Visual Studio. <code>ildasm</code> can be used both as a command-line and GUI tool, but we&rsquo;ll use the command-line functionality.</p>
<p>To use <code>ildasm</code> on our executable, we open a <a href="https://msdn.microsoft.com/en-us/library/ms229859(v=vs.110).aspx">Visual Studio Command Prompt</a>. Then, we navigate to the directory that contains the executable we just compiled. Finally, we call <code>ildasm</code> with our executable&rsquo;s name as its argument: <code>ildasm nameof.exe /text</code>.</p>
<p>This command will output all CIL code in the <code>nameof.exe</code> executable to the console (note: omit the <code>/text</code> modifier to open the <code>ildasm</code> GUI). Amongst the CIL code written to the console is the CIL code for our <code>DoSomething</code> method:</p>
<pre tabindex="0"><code>.method public hidebysig static void  DoSomething(string val) cil managed
{
  // Code size       22 (0x16)
  .maxstack  2
  .locals init ([0] bool V_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldnull
  IL_0003:  ceq
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  brfalse.s  IL_0015
  IL_0009:  nop
  IL_000a:  ldstr      &#34;val&#34;
  IL_000f:  newobj     instance void [mscorlib]System.ArgumentNullException::.ctor(string)
  IL_0014:  throw
  IL_0015:  ret
} // end of method Program::DoSomething
</code></pre><p>These instructions are the CIL representation of our C# code. If you are not familiar with CIL code, this may be a bit daunting. However, you don&rsquo;t have to know <a href="https://en.wikipedia.org/wiki/List_of_CIL_instructions">all CIL instructions</a> to understand what is happening. Let&rsquo;s walk through each instruction to see what is happening.</p>
<ul>
<li><code>.maxstack</code>: set the maximum number of items on the stack to 2.</li>
<li><code>.locals</code>: create a local variable of type <code>bool</code> at index 0.</li>
<li><code>IL_0000</code>: do nothing. This instruction allows a breakpoint to be placed on a non-executable piece of code; in this case, the method&rsquo;s opening curly brace.</li>
<li><code>IL_0001</code>: push the <code>val</code> parameter value (the argument at index 0) on the stack.</li>
<li><code>IL_0002</code>: push the <code>null</code> value on the stack.</li>
<li><code>IL_0003</code>: pop the top two stack parameters from the stack, compare them for equality, and push the comparison result on the stack.</li>
<li><code>IL_0005</code>: pop the top stack value (the equality comparison result) and store it in the local variable with index 0.</li>
<li><code>IL_0006</code>: push the local variable at index 0 (the equality comparison result) on the stack.</li>
<li><code>IL_0007</code>: pop top stack value (the equality comparison result) from stack. If this value is equal to 0 (<code>false</code>), jump to statement <code>IL_0015</code> (end of method). If not, do nothing.</li>
<li><code>IL_0009</code>: do nothing (allows breakpoint at opening curly brace inside <code>if</code> statement).</li>
<li><code>IL_000a</code>: push the string <code>&quot;val&quot;</code> on the stack.</li>
<li><code>IL_000f</code>: pop the top stack value (the <code>&quot;val&quot;</code> string) from the stack, and push a new <code>ArgumentNullException</code> instance on the stack by calling its constructor that takes the popped <code>&quot;val&quot;</code> string as its argument.</li>
<li><code>IL_0014</code>: pop the <code>ArgumentNullException</code> from the stack and throw it.</li>
<li><code>IL_0015</code>: return from the method.</li>
</ul>
<p>While there is certainly more CIL code than there was C# code, it is not that hard to grasp what is happening if you are familiar with <a href="https://en.wikipedia.org/wiki/Stack_(abstract_data_type)">stacks</a>.</p>
<h4 id="optimizing">Optimizing</h4>
<p>There is something odd about the generated CIL instructions though. For example, instructions <code>IL_0005</code> and <code>IL_0006</code> seem to be redundant, as the first instruction pops a value from the stack which the latter instruction then immediately pushes back on the stack. Removing these instructions would not change the behavior of the code and would improve its performance. So how can we instruct the compiler to omit these redundant instructions?</p>
<p>Well, note that we built our code using the default <code>Debug</code> build configuration. If you build code using the default <code>Debug</code> build configuration, the C# compiler will <strong>not</strong> apply optimizations to the CIL being output. This leads to valid, but often inefficient CIL code. However, if we switch to the <code>Release</code> build configuration and compile our code again, the compiler <em>will</em> optimize the CIL code. Let&rsquo;s see what the optimized CIL code for our example is.</p>
<h3 id="cil-code-for-string-based-example-optimized">CIL code for string-based example (optimized)</h3>
<p>To see the optimized CIL code for our example, we select the <code>Release</code> build configuration and rebuild our code. This time, the generated CIL code looks remarkably different:</p>
<pre tabindex="0"><code>.method public hidebysig static void  DoSomething(string val) cil managed
{
  // Code size       15 (0xf)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_000e
  IL_0003:  ldstr      &#34;val&#34;
  IL_0008:  newobj     instance void [mscorlib]System.ArgumentNullException::.ctor(string)
  IL_000d:  throw
  IL_000e:  ret
} // end of method Example::DoSomething
</code></pre><p>This optimized CIL code does the following things:</p>
<ul>
<li><code>.maxstack</code>: set the maximum number of items on the stack to 8.</li>
<li><code>IL_0000</code>: push the <code>val</code> parameter value (the argument at index 0) on the stack.</li>
<li><code>IL_0001</code>: pop the top stack value (the <code>val</code> parameter value) from the stack. If this value is equal to <code>true</code> (which is the same as: not <code>null</code>), jump to statement <code>IL_000e</code> (end of method).</li>
<li><code>IL_0003</code>: push the string <code>&quot;val&quot;</code> on the stack.</li>
<li><code>IL_0008</code>: pop the top stack value (the <code>&quot;val&quot;</code> string) from the stack, and push a new <code>ArgumentNullException</code> instance on the stack by calling its constructor that takes the popped <code>&quot;val&quot;</code> string as its argument.</li>
<li><code>IL_000d</code>: pop the <code>ArgumentNullException</code> from the stack and throw it.</li>
<li><code>IL_000e</code>: return from the method.</li>
</ul>
<p>As you can see, the functionality is still the same, but the number of CIL instructions has been drastically reduced. This not only leads to improved performance, but also makes it easier to see what is happening in the CIL code.</p>
<h3 id="cil-code-for-nameof-operator">CIL code for nameof operator</h3>
<p>Let&rsquo;s see what CIL code is generated for our example that uses the <code>nameof</code> operator. The C# code that uses the <code>nameof</code> operator looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">val</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">throw</span> <span class="k">new</span> <span class="n">ArgumentNullException</span><span class="p">(</span><span class="n">nameof</span><span class="p">(</span><span class="n">val</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we compile this code (using a <code>Release</code> build) and run <code>ildasm</code> again, the following optimized CIL is generated for the <code>DoSomething</code> method:</p>
<pre tabindex="0"><code>.method public hidebysig static void  DoSomething(string val) cil managed
{
  // Code size       15 (0xf)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_000e
  IL_0003:  ldstr      &#34;val&#34;
  IL_0008:  newobj     instance void [mscorlib]System.ArgumentNullException::.ctor(string)
  IL_000d:  throw
  IL_000e:  ret
} // end of method Example::DoSomething
</code></pre><p>Interestingly, the CIL generated for the <code>nameof</code> version is <em>exactly the same</em> as the string-based version! The <code>nameof</code> operator is thus just <a href="https://en.wikipedia.org/wiki/Syntactic_sugar"><em>syntactic sugar</em></a> for a plain CIL string - there is no <code>nameof</code> operator at the CIL level. This means that there is no runtime overhead to using the <code>nameof</code> operator over plain strings.</p>
<h3 id="cil-string-optimizations">CIL string optimizations</h3>
<p>As the <code>nameof</code> operator compiles to a plain string in CIL, do strings optimizations also apply when the <code>nameof</code> operator is used?</p>
<p>As an example of such an optimization, consider the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span> <span class="p">(</span><span class="s">&#34;Parameter name: &#34;</span> <span class="p">+</span> <span class="s">&#34;val&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Can you guess what CIL code will be generated for this C# code? If you figured there would be string concatenation, you&rsquo;d be wrong. Let&rsquo;s check the optimized CIL code the compiler outputs:</p>
<pre tabindex="0"><code>.method public static hidebysig default void DoSomething (string val)  cil managed
{
    // Method begins at RVA 0x2058
    // Code size 11 (0xb)
    .maxstack 8
    IL_0000:  ldstr &#34;Parameter name: val&#34;
    IL_0005:  call void class [mscorlib]System.Console::WriteLine(string)
    IL_000a:  ret
} //
</code></pre><p>You can clearly see that instead of using CIL instructions to concatenate the <code>&quot;Parameter name: &quot;</code> and <code>&quot;val&quot;</code> strings, the compiler just outputs the concatenated strings directly. Obviously, this compiler optimization saves both time and memory.</p>
<p>To find out if this optimization also applies when the <code>nameof</code> operator is used, we modify our example to use the <code>nameof</code> operator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DoSomething</span><span class="p">(</span><span class="kt">string</span> <span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span> <span class="p">(</span><span class="s">&#34;Parameter name: &#34;</span> <span class="p">+</span> <span class="n">nameof</span><span class="p">(</span><span class="n">val</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We then recompile and inspect the generated CIL code:</p>
<pre tabindex="0"><code>.method public static hidebysig default void DoSomething (string val)  cil managed
{
    // Method begins at RVA 0x2058
    // Code size 11 (0xb)
    .maxstack 8
    IL_0000:  ldstr &#34;Parameter name: val&#34;
    IL_0005:  call void class [mscorlib]System.Console::WriteLine(string)
    IL_000a:  ret
} //
</code></pre><p>As the generated CIL is the same as that of our string-based example, we have verified that existing string optimizations also apply when the <code>nameof</code> operator is used.</p>
<h3 id="backwards-compatibility">Backwards compatibility</h3>
<p>As we saw earlier, <code>nameof</code> operator calls are converted to strings in the generated CIL code; there is no <code>nameof</code> concept at the CIL level. This allows code that uses the <code>nameof</code> operator to run on older versions of the .NET framework, as far back as .NET framework 2.0 (and probably 1.0). The only restriction, of course, is that the compiler must be recent enough to know how to compile the <code>nameof</code> operator.</p>
<p>To verify this backwards compatibility, create a project that uses the <code>nameof</code> operator. Then, open the project properties page and change the <code>Target framework</code> to <code>.NET Framework 2.0</code>. At this point, you might get compile warnings for features not supported in .NET Framework 2.0. Remove all such features until the code compiles again. Note that the compiler did not complain about the <code>nameof</code> operator! Now recompile the application and run it. Everything should still work just fine.</p>
<h3 id="compiler">Compiler</h3>
<p>Previously we used a disassembler to see what CIL code was generated by the C# compiler. However, as the C# compiler (nicknamed <em>Roslyn</em>) is open-source, we can also examine its source code to find out how the <code>nameof</code> operator is compiled.</p>
<h4 id="preparing">Preparing</h4>
<p>To explore Roslyn&rsquo;s source code, we first get a local copy of the <a href="https://github.com/dotnet/roslyn">Roslyn repository</a>. We then follow the <a href="https://github.com/dotnet/roslyn/wiki/Building%20Testing%20and%20Debugging">build instructions</a> to build the <code>master</code> branch. Once the build script has finished (this can take a while), we open the <code>Compilers.sln</code> solution. In the <code>CSharp</code> solution folder, we then select the <code>csc</code> project as the startup project. This console application project builds <code>csc.exe</code>, the command-line version of the C# compiler. To see how <code>csc.exe</code> compiles C# code that uses the <code>nameof</code> operator, we specify the following command line arguments on the <code>Debug</code> tab of the <code>csc</code> project&rsquo;s properties page:</p>
<pre><code>&quot;nameof.cs&quot; /out:&quot;nameof.exe&quot; /optimize
</code></pre>
<p>The first argument is our C# source file that contains the <code>nameof</code> operator code. The compiler will compile this file and write the CIL output to the file specified in the <code>&quot;/out&quot;</code> argument. Finally, the <code>&quot;/optimize&quot;</code> flag will cause the compiler to emit optimized CIL code (note: this flag is set when doing a <code>Release</code> build).</p>
<p>Now, if we press F5 to debug the <code>csc</code> project, the C# compiler will compile the <code>nameof.cs</code> file and write the results to <code>nameof.exe</code>. At this point, we haven&rsquo;t set any breakpoints, we just let the compiler finish. After finishing, the compiler has created the <code>nameof.exe</code> executable. Using <code>ildasm</code>, we can see that <code>csc.exe</code> has generated the exact same CIL code as we saw in our previous examples.</p>
<h4 id="compilation-pipeline">Compilation pipeline</h4>
<p>Before we dive head-first into Roslyn&rsquo;s source code to see how the <code>nameof</code> operator is compiled, let&rsquo;s see what the <a href="https://github.com/dotnet/roslyn/wiki/Roslyn%20Overview">Roslyn compilation pipeline</a> looks like:</p>
<p><img src="/images/posts/csharp6-under-the-hood-nameof/roslyn.svg" alt="Compilation of .NET code in Roslyn"></p>
<p>This diagram shows that Roslyn compiles C# source code in various stages. In the next sections, we&rsquo;ll look at what happens to our <code>nameof</code> source code in each phase.</p>
<h4 id="first-steps">First steps</h4>
<p>We&rsquo;ll start exploring Roslyn&rsquo;s internals by debugging the <code>csc</code> project while it tries to compile our C# code. This time though, we set a breakpoint in the project&rsquo;s <code>Main</code> method (located in the <code>Program.cs</code> file). Once the breakpoint hits, we use <code>Step Into</code> (F11) to dig deeper and deeper into Roslyn&rsquo;s source code.</p>
<p>At first, the compiler does some pretty mundane stuff, like parsing command-line arguments. However, things start to get interesting when we arrive at the <code>RunCore()</code> method in the <code>CommonCompiler</code> class. This method implements the aforementioned compilation pipeline. Let&rsquo;s see how the <code>nameof</code> operator is processed in the various phases.</p>
<h4 id="parse-phase">Parse phase</h4>
<p>In this phase, the compiler uses the <code>ParseFile()</code> method to parse our source code into a <a href="https://github.com/dotnet/roslyn/wiki/Roslyn%20Overview#syntax-trees">syntax tree</a>. The following is a simplified version of the syntax tree the compiler creates for our C# code:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>Clearly, the syntax tree hierarchy directly corresponds to the hierarchy in our C# code. For example, the root node is the namespace declaration, which has a class declaration as its child.</p>
<p>Each syntax element in the syntax tree has a number of properties, such as a reference to its parent. Some syntax elements also have an identifier property, which is a string that contains the name of that syntax element. For example the <code>ClassDeclaration</code> describing the <code>Program</code> class has its identifier property set to <code>&quot;Program&quot;</code>.</p>
<p>Let&rsquo;s zoom in on the syntax tree for the C# code that uses the <code>nameof</code> operator: the <code>new ArgumentNullException(nameof(val))</code> expression. This time, we&rsquo;ll also show the syntax element&rsquo;s identifier in the tree (if it has one):</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>At the root of this part of the syntax tree is the <code>ObjectCreationExpression</code>. The object creation expression has three parts:</p>
<ol>
<li>The <code>new</code> keyword.</li>
<li>The identifier name (<code>&quot;ArgumentNullException&quot;</code>).</li>
<li>The argument list.</li>
</ol>
<p>The argument list subtree has a single child: an <code>Argument</code> that describes an <code>InvocationExpression</code>, which represents the <code>nameof(val)</code> argument. The syntax tree for this element has two parts:</p>
<ol>
<li>The identifier of the method to be called (<code>&quot;nameof&quot;</code>).</li>
<li>The argument list, which contains a single argument that refers to the <code>&quot;val&quot;</code> identifier.</li>
</ol>
<p>We can see that the the <code>nameof</code> operator is treated as a regular method call with a single argument. That argument is not a string though, but an <code>IdentifierName</code> element, which is a reference to another element with a matching identifier.</p>
<p>We know that in our code the <code>val</code> argument of the <code>nameof</code> call refers to the <code>DoSomething()</code> method&rsquo;s <code>val</code> parameter. Therefore, we expect the syntax tree of the <code>DoSomething()</code> method to have a parameter syntax element with its identifier set to <code>&quot;val&quot;</code>, which it does:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>In the next phase, the compiler will match these identifiers.</p>
<h4 id="declaration-and-bind-phase">Declaration and bind phase</h4>
<p>In the declaration and bind phase, identifiers are bound to symbols. In the parse phase, we saw that the <code>nameof</code> call was described by an <code>InvocationExpression</code>. The binding of this expression is done in the <code>BindInvocationExpression()</code> method.</p>
<p>The <code>BindInvocationExpression()</code> method starts by calling <code>TryBindNameofOperator()</code>. As our <code>InvocationExpression</code> indeed contains a <code>nameof</code> operator, the <code>BindNameofOperatorInternal()</code> method is called to handle the binding of the <code>nameof</code> operator.</p>
<p>The following, abbreviated code shows the <code>BindNameofOperatorInternal()</code> method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">private</span> <span class="n">BoundExpression</span> <span class="n">BindNameofOperatorInternal</span><span class="p">(</span><span class="n">InvocationExpressionSyntax</span> <span class="n">node</span><span class="p">,</span> <span class="n">DiagnosticBag</span> <span class="n">diagnostics</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">argument</span> <span class="p">=</span> <span class="n">node</span><span class="p">.</span><span class="n">ArgumentList</span><span class="p">.</span><span class="n">Arguments</span><span class="p">[</span><span class="m">0</span><span class="p">].</span><span class="n">Expression</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">string</span> <span class="n">name</span> <span class="p">=</span> <span class="s">&#34;&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">CheckSyntaxForNameofArgument</span><span class="p">(</span><span class="n">argument</span><span class="p">,</span> <span class="k">out</span> <span class="n">name</span><span class="p">,</span> <span class="n">diagnostics</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">new</span> <span class="n">BoundNameOfOperator</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">boundArgument</span><span class="p">,</span> <span class="n">ConstantValue</span><span class="p">.</span><span class="n">Create</span><span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="n">Compilation</span><span class="p">.</span><span class="n">GetSpecialType</span><span class="p">(</span><span class="n">SpecialType</span><span class="p">.</span><span class="n">System_String</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>First, the <code>InvocationExpressionSyntax</code> element&rsquo;s single argument is retrieved, which is of type <code>IdentifierNameSyntax</code>. Then the <code>CheckSyntaxForNameofArgument()</code> method sets the <code>name</code> parameter to the identifier of the <code>IdentifierNameSyntax</code> element. In our example, the <code>name</code> variable is set to <code>&quot;val&quot;</code>.</p>
<p>Finally, the method returns a <code>BoundNameOfOperator</code> instance, which is the bound symbol representation of the <code>InvocationExpressionSyntax</code>. Note that the third constructor argument is a call to <code>ConstantValue.Create()</code>, with the identifier name (<code>&quot;val&quot;</code>) as its argument. This method is implemented as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="n">ConstantValue</span> <span class="n">Create</span><span class="p">(</span><span class="kt">string</span> <span class="k">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="k">value</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">Null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">new</span> <span class="n">ConstantValueString</span><span class="p">(</span><span class="k">value</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>By passing a <code>ConstantValue</code> instance to the <code>BoundNameOfOperator</code> constructor, we indicate that the <code>BoundNameOfOperator</code> symbol can also be represented by a constant value. The importance of this will become clear later.</p>
<h4 id="lowering">Lowering</h4>
<p>After the binding has finished, there is one thing left to: lowering. In the process of lowering, complex semantic constructs are rewritten in terms of simpler ones. For example, each <code>lock</code> call is lowered to a <code>try/finally</code> block that uses <code>Monitor.Enter</code> and <code>Monitor.Exit</code>.</p>
<p>As it turns out, lowering also applies to the <code>nameof</code> operator. The <code>VisitExpressionImpl()</code> method (in the <code>LocalRewriter</code> class) is called for each <code>BoundExpression</code> instance, including derived classes such as the <code>BoundNameOfOperator</code> class. It looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">private</span> <span class="n">BoundExpression</span> <span class="n">VisitExpressionImpl</span><span class="p">(</span><span class="n">BoundExpression</span> <span class="n">node</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">ConstantValue</span> <span class="n">constantValue</span> <span class="p">=</span> <span class="n">node</span><span class="p">.</span><span class="n">ConstantValue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">constantValue</span> <span class="p">!=</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">MakeLiteral</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">Syntax</span><span class="p">,</span> <span class="n">constantValue</span><span class="p">,</span> <span class="n">type</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This method takes a <code>BoundExpression</code> and also returns a <code>BoundExpression</code>. However, if the <code>ConstantValue</code> property is not <code>null</code>, the returned <code>BoundExpression</code> is of type <code>BoundLiteral</code>, as returned by the <code>MakeLiteral()</code> method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">private</span> <span class="n">BoundExpression</span> <span class="n">MakeLiteral</span><span class="p">(</span><span class="n">CSharpSyntaxNode</span> <span class="n">syntax</span><span class="p">,</span> <span class="n">ConstantValue</span> <span class="n">constantValue</span><span class="p">,</span> <span class="n">TypeSymbol</span> <span class="n">type</span><span class="p">,</span> <span class="n">BoundLiteral</span> <span class="n">oldNodeOpt</span> <span class="p">=</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">new</span> <span class="n">BoundLiteral</span><span class="p">(</span><span class="n">syntax</span><span class="p">,</span> <span class="n">constantValue</span><span class="p">,</span> <span class="n">type</span><span class="p">,</span> <span class="n">hasErrors</span><span class="p">:</span> <span class="n">constantValue</span><span class="p">.</span><span class="n">IsBad</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Therefore, when the <code>VisitExpressionImpl()</code> method is called to apply lowering to bound expressions, each <code>BoundNameOfOperator</code> instance is replaced by a <code>BoundLiteral</code> instance.</p>
<h4 id="emit-phase">Emit phase</h4>
<p>The last phase is the emit phase. Here, the bound symbols created in the previous phase are written to file as CIL code.</p>
<p>From our <code>nameof</code> viewpoint, things start getting interesting when the <code>EmitExpression()</code> method is called with the <code>BoundLiteral</code> instance (representing our <code>nameof</code> call) as its argument.</p>
<p>As we saw earlier, the <code>BoundLiteral</code> instance had its <code>ConstantValue</code> property set to an instance of <code>ConstantValueString</code> (containing the string <code>&quot;val&quot;</code>). This is important because normally, the compiler evaluates an expression to determine what code to emit. However, if the compiler find that an expression&rsquo;s <code>ConstantValue</code> property is not <code>null</code>, it will skip evaluating the expression but instead emit the constant value.</p>
<p>In the <code>EmitExpression()</code> method, you can clearly see this behavior:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">private</span> <span class="k">void</span> <span class="n">EmitExpression</span><span class="p">(</span><span class="n">BoundExpression</span> <span class="n">expression</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">used</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">constantValue</span> <span class="p">=</span> <span class="n">expression</span><span class="p">.</span><span class="n">ConstantValue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">constantValue</span> <span class="p">!=</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">EmitConstantExpression</span><span class="p">(</span><span class="n">expression</span><span class="p">.</span><span class="n">Type</span><span class="p">,</span> <span class="n">constantValue</span><span class="p">,</span> <span class="n">used</span><span class="p">,</span> <span class="n">expression</span><span class="p">.</span><span class="n">Syntax</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As the <code>ConstantValue</code> property of our <code>BoundLiteral</code> instance is not null, the <code>EmitConstantExpression()</code> method is called, which in turn calls <code>EmitConstantValue()</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">internal</span> <span class="k">void</span> <span class="n">EmitConstantValue</span><span class="p">(</span><span class="n">ConstantValue</span> <span class="k">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">ConstantValueTypeDiscriminator</span> <span class="n">discriminator</span> <span class="p">=</span> <span class="k">value</span><span class="p">.</span><span class="n">Discriminator</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">switch</span> <span class="p">(</span><span class="n">discriminator</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">case</span> <span class="n">ConstantValueTypeDiscriminator</span><span class="p">.</span><span class="n">String</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">EmitStringConstant</span><span class="p">(</span><span class="k">value</span><span class="p">.</span><span class="n">StringValue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As the <code>ConstantValue</code> property of the <code>BoundLiteral</code> instance is of type <code>ConstantValueString</code>, the <code>EmitStringConstant()</code> method is called with the <code>StringValue</code> property as its argument. Note that for our <code>ConstantValueString</code> instance, the <code>StringValue</code> property returns the string <code>&quot;val&quot;</code>.</p>
<p>Having arrived at the <code>EmitStringConstant()</code> method, we are finally able to see how the CIL code for the <code>nameof</code> operator is emitted:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">internal</span> <span class="k">void</span> <span class="n">EmitStringConstant</span><span class="p">(</span><span class="kt">string</span> <span class="k">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="k">value</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">EmitNullConstant</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">EmitOpCode</span><span class="p">(</span><span class="n">ILOpCode</span><span class="p">.</span><span class="n">Ldstr</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">EmitToken</span><span class="p">(</span><span class="k">value</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>With <code>value</code> not being <code>null</code>, the <code>else</code> branch is executed. First, the CIL code for the <code>ldstr</code> opcode is emitted. Then, the <code>&quot;val&quot;</code> string token is emitted. This will output the CIL code we were expecting:</p>
<pre tabindex="0"><code>IL_0003:  ldstr      &#34;val&#34;
</code></pre><p>Our tour through Roslyn&rsquo;s internals has shown us how the <code>nameof</code> operator has been parsed to syntax elements, then bound to symbols and finally emitted as CIL code.</p>
<h2 id="conclusion">Conclusion</h2>
<p>The <code>nameof</code> operator is easy to understand and use. While its use is limited, it does make your code more robust. As the <code>nameof</code> operator is just <em>syntactic sugar</em>, there is no runtime performance impact. Furthermore, existing string optimizations also apply to the <code>nameof</code> operator and the compiled code runs on older versions of the .NET framework.</p>
<p>To find out how the <code>nameof</code> operator was implemented, we used <code>ildasm</code> to examine the generated CIL code and stepped through Roslyn&rsquo;s internals to see how the compiler generated the CIL code for the <code>nameof</code> operator.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library - part 7: CDN</title>
			<link>https://www.erikschierboom.com/2015/11/07/building-a-javascript-library-part-7-cdn/</link>
			<pubDate>Sat, 07 Nov 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/11/07/building-a-javascript-library-part-7-cdn/</guid>
			<description>This is the seventh and last in a series of posts that discuss the steps taken to publish our library. In our previous post, we added TypeScript support to our library. This post will show how we added our library to a Content Delivery Network.
Content Delivery Network A Content Delivery Network (CDN) is a network of servers that deliver content based on the geographic location of the user. In other words, when you request content from a CDN, the server geographically nearest to you will send the content.</description>
			<content type="html"><![CDATA[<p>This is the seventh and last in a <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> that discuss the steps taken to publish our library. In our <a href="https://www.erikschierboom.com/2015/11/04/building-a-javascript-library-part-6-typescript/">previous post</a>, we added TypeScript support to our library. This post will show how we added our library to a Content Delivery Network.</p>
<h2 id="content-delivery-network">Content Delivery Network</h2>
<p>A Content Delivery Network (CDN) is a network of servers that deliver content based on the geographic location of the user. In other words, when you request content from a CDN, the server geographically nearest to you will send the content. The main advantage of this is speed, but another is reliability. If one server goes down, another will automatically take over. Another advantage is that your own servers use less bandwith, very useful to cut down on bandwidth costs.</p>
<p>Some well-known CDN providers are <a href="https://www.akamai.com/us/en/media-and-delivery.jsp">Akamai</a>, <a href="https://www.cloudflare.com/features-cdn/">CloudFlare</a> and <a href="https://aws.amazon.com/cloudfront/">Amazon CloudFront</a>. While most CDN providers are paid services, some offer basic functionality for free.</p>
<h2 id="hosted-javascript-libraries">Hosted JavaScript libraries</h2>
<p>For developers, CDN&rsquo;s are often used to serve JavaScript libraries. For example, <a href="https://jquery.com/">jQuery</a> has its own CDN at <a href="https://code.jquery.com/">code.jquery.com</a> which hosts jQuery, jQueryUI and several others. For a larger list of libraries, you can use the <a href="http://www.asp.net/ajax/cdn">Microsoft Ajax Content Delivery Network</a> or <a href="https://developers.google.com/speed/libraries/#libraries">Google&rsquo;s hosted libraries</a>. However, if they don&rsquo;t host the library you want to use, you&rsquo;re out of luck, right? Enter cdnjs.</p>
<h2 id="cdnjs">cdnjs</h2>
<p><a href="https://cdnjs.com/">cdnjs</a> is a CDN that hosts many JavaScript libraries, a lot more than the aforementioned CDN&rsquo;s. The great thing about cdnjs is that if they don&rsquo;t already host the library you want, you can add it yourelf! Let&rsquo;s do that for our library.</p>
<p>First we <a href="https://github.com/cdnjs/cdnjs/fork">fork the cdnjs repository</a>. In that fork, we create a new directory with our library&rsquo;s name in the <code>ajax/libs</code> folder. Within the created folder, we add a <code>package.json</code> file using cdnjs&rsquo;s custom <a href="https://github.com/cdnjs/cdnjs/blob/master/test/schemata/npm-package.json">package.json format</a>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;filename&#34;</span><span class="p">:</span> <span class="s2">&#34;knockout-paging.min.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;knockout-paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;0.3.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;Knockout paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;keywords&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;knockout&#34;</span><span class="p">,</span> <span class="s2">&#34;paging&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;homepage&#34;</span><span class="p">:</span> <span class="s2">&#34;https://github.com/ErikSchierboom/knockout-paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;dependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;knockout&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.2.0&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Although the format is similar to the <a href="https://docs.npmjs.com/files/package.json">regular package.json format</a>, the <code>&quot;filename&quot;</code> field is new <em>and</em> required.</p>
<p>At this point, we can start adding the files we want cdnjs to serve. To do so, we create a subfolder for the version of our library which files we want to host. Within that folder, we then put all files we want to be hosted. For our library, this gives us the following files and folders:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>Note that we distribute both the regular and minified versions of our library.</p>
<p>The final step is to commit our changes and send it in a pull request. Once accepted, our library will be <a href="https://cdnjs.com/libraries/knockout-paging">available on cdnjs</a>. The full URL for version 0.3.0 of our library&rsquo;s <code>knockout-paging.min.js</code> file is: <a href="https://cdnjs.cloudflare.com/ajax/libs/knockout-paging/0.3.0/knockout-paging.min.js">https://cdnjs.cloudflare.com/ajax/libs/knockout-paging/0.3.0/knockout-paging.min.js</a>.</p>
<p>Note that most of the steps to create the correct folders and files can also be done automatically using the <a href="https://github.com/cdnjs/cdnjs-importer">cdnjs-importer</a> tool.</p>
<h3 id="updating-versions">Updating versions</h3>
<p>To add a new version of a library, you used to create a new subfolder with that version&rsquo;s file(s). Then, you&rsquo;d commit and send a new pull request. However, the preferred method nowadays is to <a href="https://github.com/cdnjs/cdnjs#enabling-npmrecommended-or-git-auto-update">enable auto-updating</a>. There are two ways libraries can be updated automatically:</p>
<ol>
<li>Through NPM.</li>
<li>Through Git.</li>
</ol>
<p>For our library, we&rsquo;ll use Git. To enable auto-updating from Git, we add the following to our cdnjs library&rsquo;s <code>package.json</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;autoupdate&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;source&#34;</span><span class="p">:</span> <span class="s2">&#34;git&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;target&#34;</span><span class="p">:</span> <span class="s2">&#34;git://github.com/ErikSchierboom/knockout-paging.git&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;basePath&#34;</span><span class="p">:</span> <span class="s2">&#34;/dist/&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;files&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;knockout-paging.min.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;knockout-paging.js&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This will instruct cdnjs to periodically check for new versions at the specified Git repository. It does this by checking the Git tags, which should use <a href="http://semver.org/">semantic versioning</a>. Now, if we commit the updated <code>package.json</code> file and submit it to cdnjs, new versions of our library wil automatically be added. Of course, old versions will remain available.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We made our library available through a CDN by adding it to <a href="https://cdnjs.com/">cdnjs</a>, which was quite simple. Furthermore, we also configured cdnjs to automatically make new versions of our library available through the use of its auto-updating feature.</p>
<p>And that brings us to the end of the last of our <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> on how we published our <a href="https://github.com/ErikSchierboom/knockout-paging">knockout-paging</a> plugin.
Making our library available through a CDN was easy.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library - part 6: TypeScript</title>
			<link>https://www.erikschierboom.com/2015/11/04/building-a-javascript-library-part-6-typescript/</link>
			<pubDate>Wed, 04 Nov 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/11/04/building-a-javascript-library-part-6-typescript/</guid>
			<description>This is the sixth in a series of posts that discuss the steps taken to publish our library. In our previous post, we used build servers to automatically build and test our software. This post will show how we added TypeScript support to our library.
TypeScript The TypeScript language is a typed superset of JavaScript that adds features like modules, classes and interfaces. The great thing of it being a JavaScript superset is that any JavaScript code is also valid TypeScript code!</description>
			<content type="html"><![CDATA[<p>This is the sixth in a <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> that discuss the steps taken to publish our library. In our <a href="https://www.erikschierboom.com/2015/10/26/building-a-javascript-library-part-5-build-server/">previous post</a>, we used build servers to automatically build and test our software. This post will show how we added TypeScript support to our library.</p>
<h2 id="typescript">TypeScript</h2>
<p>The <a href="http://www.typescriptlang.org/">TypeScript</a> language is a typed superset of JavaScript that adds features like modules, classes and interfaces. The great thing of it being a JavaScript superset is that any JavaScript code is also valid TypeScript code! This allows you to gradually introduce TypeScript-specific features to your existing JavaScript code.</p>
<p>Let&rsquo;s look at some TypeScript code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">Greeter</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">greeting</span><span class="o">:</span> <span class="nx">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">constructor</span><span class="p">(</span><span class="nx">message</span><span class="o">:</span> <span class="nx">string</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">greeting</span> <span class="o">=</span> <span class="nx">message</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="nx">greet</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;Hello, &#34;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">greeting</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">greeter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Greeter</span><span class="p">(</span><span class="s2">&#34;world&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nx">alert</span><span class="p">(</span><span class="nx">greeter</span><span class="p">.</span><span class="nx">greet</span><span class="p">());</span>
</span></span></code></pre></div><p>As can be seen, TypeScript allows us to use features like classes and constructors. However, this code is not valid JavaScript code (it might be in the future). Therefore, we&rsquo;ll use the TypeScript compiler to convert to plain JavaScript. Our example compiles to the following JavaScript code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">Greeter</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">function</span> <span class="nx">Greeter</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">greeting</span> <span class="o">=</span> <span class="nx">message</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Greeter</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">greet</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;Hello, &#34;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">greeting</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">Greeter</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">})();</span>
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">greeter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Greeter</span><span class="p">(</span><span class="s2">&#34;world&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nx">alert</span><span class="p">(</span><span class="nx">greeter</span><span class="p">.</span><span class="nx">greet</span><span class="p">());</span>
</span></span></code></pre></div><p>The compiled output is valid JavaScript code, which is quite similar to the TypeScript source. One thing that is lost completely in the translation though, are the type annotations. So what&rsquo;s that about?</p>
<h2 id="static-typing">Static typing</h2>
<p>One of TypeScript&rsquo;s best features is that it allows you to add type annotations to your code. This makes TypeScript statically typed, as opposed to JavaScript being dynamically typed. As JavaScript does not support type annotations, the TypeScript compiler does not include them in the compiled JavaScript. This is known as <a href="https://en.wikipedia.org/wiki/Type_erasure">type erasure</a>.</p>
<p>Regardless of your stance on dynamic vs. static typing, the latter has some benefits:</p>
<ol>
<li>Bugs can be found at compile-time instead of runtime.</li>
<li>You can (more) safely refactor code.</li>
<li>Tooling can easily support code-completion.</li>
</ol>
<p>You might not miss these features in small projects, but in large projects they can greatly enhance productivity. That is why the Angular team chose to write Angular 2 <a href="http://blogs.msdn.com/b/typescript/archive/2015/03/05/angular-2-0-built-on-typescript.aspx">completely in TypeScript</a>.</p>
<h2 id="declaration-files">Declaration files</h2>
<p>So how does TypeScript interact with plain JavaScript code, which doesn&rsquo;t have type annotations or classes? Well, thanks to <a href="https://typescript.codeplex.com/wikipage?title=Writing%20Definition%20%28.d.ts%29%20Files">declaration files</a>, you can use them as if they were written in TypeScript.</p>
<p>A declaration file is a TypeScript file, but with only types and variable definitions, the actual implementation is done in another (JavaScript) file. Let&rsquo;s consider the following JavaScript code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">Rectangle</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">function</span> <span class="nx">Rectangle</span><span class="p">(</span><span class="nx">width</span><span class="p">,</span> <span class="nx">height</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Rectangle</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">createSquare</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">size</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">new</span> <span class="nx">Rectangle</span><span class="p">(</span><span class="nx">size</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">Rectangle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">})();</span>
</span></span></code></pre></div><p>We could use this code from TypeScript as is, but we wouldn&rsquo;t have any type information and could thus easily use it incorrectly. We can remedy this by specifying the types in a declaration file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">Rectangle</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">width</span><span class="o">:</span> <span class="nx">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">height</span><span class="o">:</span> <span class="nx">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">constructor</span><span class="p">(</span><span class="nx">width</span><span class="o">:</span> <span class="nx">number</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span> <span class="nx">number</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">width</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">createSquare</span><span class="p">(</span><span class="nx">size</span><span class="o">:</span> <span class="nx">number</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">new</span> <span class="nx">Rectangle</span><span class="p">(</span><span class="nx">size</span><span class="p">,</span> <span class="nx">size</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we reference this declaration file in our TypeScript code, we can then safely use the JavaScript code.</p>
<h2 id="creating-a-declaration-file">Creating a declaration file</h2>
<p>Now that we know what declaration files are, let&rsquo;s create one for our library. Declaration files must have a <code>.d.ts</code> extension, so lets name our library&rsquo;s declaration file <code>knockout-paging.d.ts</code>. As our library extends the <a href="http://knockoutjs.com/">Knockout</a> library, we start by downloading its <a href="https://raw.githubusercontent.com/borisyankov/DefinitelyTyped/2d4c4679bc2b509f27435a4f9da5e2de11258571/knockout/knockout.d.ts">declaration file</a>. We&rsquo;ll reference this file in our declaration file to import its types.</p>
<p>We are now ready to define our declaration file. First, we&rsquo;ll define an interface for our paged observable array:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">/// &lt;reference path=&#34;knockout.d.ts&#34; /&gt;
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">KnockoutPagedObservableArray</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="kr">extends</span> <span class="nx">KnockoutObservableArray</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageSize</span><span class="o">:</span> <span class="nx">KnockoutObservable</span><span class="o">&lt;</span><span class="nx">number</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageNumber</span><span class="o">:</span> <span class="nx">KnockoutObservable</span><span class="o">&lt;</span><span class="nx">number</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">pageItems</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="nx">T</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageCount</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="nx">number</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">itemCount</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="nx">number</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">firstItemOnPage</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="nx">number</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">lastItemOnPage</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="nx">number</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">hasPreviousPage</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="kr">boolean</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">hasNextPage</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="kr">boolean</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isFirstPage</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="kr">boolean</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">isLastPage</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="kr">boolean</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pages</span><span class="o">:</span> <span class="nx">KnockoutComputed</span><span class="o">&lt;</span><span class="nx">number</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">toNextPage</span><span class="p">()</span><span class="o">:</span> <span class="k">void</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">toPreviousPage</span><span class="p">()</span><span class="o">:</span> <span class="k">void</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">toLastPage</span><span class="p">()</span><span class="o">:</span> <span class="k">void</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">toFirstPage</span><span class="p">()</span><span class="o">:</span> <span class="k">void</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As our paged observable array is a regular observable array with added properties and functions, our interface extends Knockout&rsquo;s <code>KnockoutObservableArray&lt;T&gt;</code> type. This type is defined in the previously downloaded <code>knockout.d.ts</code> file. To use the types in this declaration file, we reference it in our own declaration using the <code>/// &lt;reference path=&quot;...&quot; /&gt;</code> syntax.</p>
<p>To define our <code>ko.pagedObservableArray()</code> function, we&rsquo;ll have to extend the existing <code>ko</code> instance&rsquo;s type, which is the <code>KnockoutStatic</code> interface. Luckily, extending an interface is as simple as defining a new interface with the same name:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">KnockoutStatic</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pagedObservableArray</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="nx">value</span><span class="o">?:</span> <span class="nx">T</span><span class="p">[],</span>
</span></span><span class="line"><span class="cl">    <span class="nx">options</span><span class="o">?:</span> <span class="nx">KnockoutPagedOptions</span>
</span></span><span class="line"><span class="cl">  <span class="p">)</span><span class="o">:</span> <span class="nx">KnockoutPagedObservableArray</span><span class="o">&lt;</span><span class="nx">T</span><span class="o">&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">KnockoutPagedOptions</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageSize</span><span class="o">?:</span> <span class="nx">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageNumber</span><span class="o">?:</span> <span class="nx">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageGenerator</span><span class="o">?:</span> <span class="nx">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Here, we specify that the <code>ko</code> instance has a <code>pagedObservableArray()</code> function that takes two optional parameters. As the second parameter is actually an object, we define its allowed properties in a separate interface.</p>
<h3 id="testing-the-declaration-file">Testing the declaration file</h3>
<p>To test our declaration file, we can create a new TypeScript files that references our declaration file. We should then use our library in every supported way, checking to see if our declaration file allows it. For our library, this looks something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">/// &lt;reference path=&#34;knockout-paging.d.ts&#34; /&gt;
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// Different option formats
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">emptyOptions</span> <span class="o">=</span> <span class="p">{};</span>
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">allOptions</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageNumber</span><span class="o">:</span> <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">pageGenerator</span><span class="o">:</span> <span class="s2">&#34;sliding&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">pagedObservableArray</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">simple</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">emptyOptions</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="nx">emptyOptions</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">allOptions</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="nx">allOptions</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">observables</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">paged</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([]);</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pageSize</span> <span class="o">=</span> <span class="nx">paged</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pageNumber</span> <span class="o">=</span> <span class="nx">paged</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">computed</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">paged</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([]);</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">firstItemOnPage</span> <span class="o">=</span> <span class="nx">paged</span><span class="p">.</span><span class="nx">firstItemOnPage</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">hasPreviousPage</span> <span class="o">=</span> <span class="nx">paged</span><span class="p">.</span><span class="nx">hasPreviousPage</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pages</span> <span class="o">=</span> <span class="nx">paged</span><span class="p">.</span><span class="nx">pages</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">functions</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">paged</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([]);</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paged</span><span class="p">.</span><span class="nx">toNextPage</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paged</span><span class="p">.</span><span class="nx">toLastPage</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can then try to compile this test file using the TypeScript compiler. It should build without errors or warnings.</p>
<p>Note that for brevity, we left out some tests.</p>
<h2 id="including-the-declaration-file">Including the declaration file</h2>
<p>To make our declaration file available, we simply add it to our repository. People can then use it by referencing it from their TypeScript code.</p>
<p>Starting from version 1.6, the TypeScript compiler can <a href="https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages">automatically load declaration files</a> (without explicitly referencing them). To support this, we&rsquo;ll add a <code>&quot;typings&quot;</code> property to our <code>package.json</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;typings&#34;</span><span class="err">:</span> <span class="s2">&#34;./knockout-paging.d.ts&#34;</span><span class="err">,</span>
</span></span></code></pre></div><p>The declaration file will now automatically be picked up by the TypeScript compiler.</p>
<h2 id="publishing-the-declaration-file">Publishing the declaration file</h2>
<p>An alternative place where people look for declaration files is the <a href="https://github.com/borisyankov/DefinitelyTyped">DefinitelyTyped repository</a>. This repository contains many declaration files, but mostly for libraries that don&rsquo;t provide a declaration file themselves.</p>
<p>Although our library&rsquo; <em>does</em> provide a declaration file, it&rsquo;s not a bad idea to also submit it to DefinitelyTyped. To do so, we just follow the <a href="http://definitelytyped.org/guides/contributing.html">contribution guidelines</a>:</p>
<ol>
<li>We <a href="https://help.github.com/articles/fork-a-repo/">fork</a> the <a href="https://github.com/borisyankov/DefinitelyTyped">DefinitelyTyped repository</a>.</li>
<li>In the fork, we create a folder with our library&rsquo;s name.</li>
<li>We add the declaration- and tests file to that folder.</li>
<li>We compile our tests file to see if everything is valid.</li>
<li>We commit our changes and submit a <a href="https://help.github.com/articles/using-pull-requests/">pull request</a>.</li>
</ol>
<p>Once the pull request has been accepted, our declaration file will have been added to the DefinitelyType repository.</p>
<p>Note that if we update our declaration file, we should also update it in the DefinitelyTyped repository.</p>
<h3 id="installing-declaration-files">Installing declaration files</h3>
<p>Although you could manually search and download declaration files from the DefinitelyTyped repository, you can also use the <a href="http://definitelytyped.org/tsd/">TSD</a> tool. To install it, we use NPM:</p>
<pre tabindex="0"><code>npm install tsd -g
</code></pre><p>We can now use the <code>tsd</code> command to install declaration files. Here is how we&rsquo;d install our library&rsquo;s declaration file:</p>
<pre tabindex="0"><code>tsd install knockout-paging --save
</code></pre><p>Once this command has completed, our library&rsquo;s declaration file will have been saved in <code>typings/knockout-paging/knockout-paging.d.ts</code>.</p>
<p>When TSD executes a command, it modifies the <code>tsd.json</code> file. This file contains metadata used by TSD:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;v4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;repo&#34;</span><span class="p">:</span> <span class="s2">&#34;borisyankov/DefinitelyTyped&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;ref&#34;</span><span class="p">:</span> <span class="s2">&#34;master&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;typings&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;bundle&#34;</span><span class="p">:</span> <span class="s2">&#34;typings/tsd.d.ts&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;installed&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;knockout-paging/knockout-paging.d.ts&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;commit&#34;</span><span class="p">:</span> <span class="s2">&#34;001ca36ba58cef903c4c063555afb07bbc36bb58&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The most important part is the <code>&quot;installed&quot;</code> section, which lists all installed declaration files. This allows TSD to install all typings file the project depends on just by examining the <code>tsd.json</code> file, similar to how the <code>dependencies</code> section in a <code>package.json</code> file is used by NPM to install any dependencies.</p>
<h2 id="conclusion">Conclusion</h2>
<p>As TypeScript is becoming more popular, we created a declaration file for our library. Creating this file was fairly straightforward and gives users a type-safe way to interact with our library. Besides adding the declaration file to our repository, we also added it to the DefinitelyTyped repository.</p>
<p>In the <a href="https://www.erikschierboom.com/2015/11/07/building-a-javascript-library-part-7-cdn/">next post</a> we&rsquo;ll add our library to a CDN.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library - part 5: build server</title>
			<link>https://www.erikschierboom.com/2015/10/26/building-a-javascript-library-part-5-build-server/</link>
			<pubDate>Mon, 26 Oct 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/10/26/building-a-javascript-library-part-5-build-server/</guid>
			<description>This is the fifth in a series of posts that discuss the steps taken to publish our library. In our previous post, we added support for package managers. This post will show how we use build servers to automatically build and test our software.
Build servers When creating a library, it is important to verify that your code also works as intended on other machines/configurations. One way to do this is by utilising a build server, which is software designed to automatically build (and often test) software.</description>
			<content type="html"><![CDATA[<p>This is the fifth in a <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> that discuss the steps taken to publish our library. In our <a href="https://www.erikschierboom.com/2015/10/05/building-a-javascript-library-part-4-package-managers/">previous post</a>, we added support for package managers. This post will show how we use build servers to automatically build and test our software.</p>
<h2 id="build-servers">Build servers</h2>
<p>When creating a library, it is important to verify that your code also works as intended on other machines/configurations. One way to do this is by utilising a build server, which is software designed to automatically build (and often test) software.</p>
<p>Most build servers can be linked to a source control repository, which allows them to do automatic builds whenever a change in the source control repository is detected. This automatic building is known as <a href="https://en.wikipedia.org/wiki/Continuous_integration">continous integration</a>.</p>
<p>For our library, we&rsquo;ll look at two online build servers: <a href="https://travis-ci.org/">Travis</a> and <a href="http://www.appveyor.com/">AppVeyor</a>. We&rsquo;ll use both to do continuous integration of our library. Note that for open-source software (like our library), both Travis and AppVeyor are free of charge.</p>
<h2 id="travis">Travis</h2>
<p>The first build server, <a href="https://travis-ci.org/">Travis</a>, is probably the most popular online build server. It supports a wide variety of <a href="http://docs.travis-ci.com/user/ci-environment/">build environments</a>, which allows it to build software for many platforms and languages. Note that each build environment runs on Linux.</p>
<p>To work with Travis, the first step is to create an account. Registering is easy, as you can just use your existing GitHub account. Once registered, you&rsquo;ll be redirected to your account&rsquo;s page:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-repos.png" alt="Travis account"></p>
<p>Here, we click on the &ldquo;+&rdquo; next to &ldquo;My Repositories&rdquo; (highlighted in red). This will redirect us to a page that lists all your public GitHub repositories:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-add.png" alt="Travis add repository"></p>
<p>To enable Travis builds for our library&rsquo;s repository, we find it in the list and click on the button with the cross before the repository&rsquo;s name. After some brief processing, the button will become green and Travis builds will have been enabled for that repository:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-added.png" alt="Travis added repository"></p>
<p>Next, we click on the cogwheel icon adjacent to the enable button. This will show our project&rsquo;s settings page:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-settings.png" alt="Travis repository settings"></p>
<p>We&rsquo;ll ignore the various settings and open the &ldquo;Current&rdquo; tab:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-current.png" alt="Travis current build"></p>
<p>At the moment, there are no builds for this repository. To allow Travis to build our repository, we need to create a YAML configuration file named <code>.travis.yml</code> in our repository&rsquo;s root folder. The full list of <a href="http://docs.travis-ci.com/user/customizing-the-build/">configuration options</a> is huge, but our project only needs a fairly minimal configuration file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l">node_js</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">before_install</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">npm install -g gulp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">script</span><span class="p">:</span><span class="w"> </span><span class="l">gulp ci</span><span class="w">
</span></span></span></code></pre></div><p>The first line specifies the language Travis should create a build environment for. As our library uses Node.js for building and testing, we&rsquo;ll use that as our platform/language.</p>
<p>In the second line, we indicate that before running our actual build script, we want Travis to install <a href="http://gulpjs.com/">Gulp</a> in our build environment. Note that we can use NPM here, which Travis installs automatically for Node.js build environments.</p>
<p>Finally, we tell Travis what script to run to build our repository. For that, we use our custom <code>gulp ci</code> command, which uses Gulp (installed in the previous step) to build <em>and</em> test our library.</p>
<p>We then commit the <code>.travis.yml</code> file to version control and push it to GitHub. At this point, Travis will automatically detect the change in our repository and adds it to the build queue. After a short while, Travis will be running the build as specified by the <code>.travis.yml</code> file and output the build log to the screen:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-build.png" alt="Travis build"></p>
<p>This build log shows that Travis does several things:</p>
<ul>
<li>Create a worker environment.</li>
<li>Use Git to clone our repository.</li>
<li>Install Node.js.</li>
<li>Run the <code>before_install</code> script, which installs Gulp.</li>
<li>Run <code>npm install</code> to install any package dependencies.</li>
<li>Run the <code>script</code> script, which executes the <code>gulp ci</code> command.</li>
<li>Determine if the build&rsquo;s success by looking at the exit code (0 means success).</li>
</ul>
<p>From now on, each change in our repository will trigger a new Travis build. This means that we use Travis for continous integration.</p>
<p>It is worth noting that you&rsquo;ll receive an email with the build results each time Travis has run a build.</p>
<h3 id="badge">Badge</h3>
<p>One last thing we can now do is to include a <em>badge</em> in our project&rsquo;s readme. This badge is an image showing the last build&rsquo;s status.</p>
<p>To find the badge settings, click on the build status button next to the GitHub logo:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-badge.png" alt="Travis badge"></p>
<p>The badge is available in many different output formats, including the Markdown format used in our readme file:</p>
<pre tabindex="0"><code>[![Build Status](https://travis-ci.org/ErikSchierboom/knockout-pre-rendered.svg?branch=master)](https://travis-ci.org/
ErikSchierboom/knockout-pre-rendered)
</code></pre><p>After commiting the updated readme file to the repository, our project&rsquo;s readme now includes the latest Travis build status:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-badge-status.png" alt="Travis badge status"></p>
<h2 id="appveyor">AppVeyor</h2>
<p>The second build server we&rsquo;ll look at is <a href="http://www.appveyor.com/">AppVeyor</a>, which is a build server that runs on Windows (whereas Travis runs on Linux).</p>
<p><a href="https://ci.appveyor.com/signup">Registering</a> is simple, as you can either create a new account or use your existing GitHub, BitBucket or Visual Studio Online account.</p>
<p>Once registered, you are redirected to a page with an overview of your existing projects:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/appveyor-projects.png" alt="AppVeyor projects"></p>
<p>Here, we click on the &ldquo;NEW PROJECT&rdquo; button, which redirects us to a page where all our projects are listed:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/appveyor-new-projects.png" alt="AppVeyor projects"></p>
<p>Having selected GitHub as our project source, we then hover over our target project and click on the &ldquo;ADD&rdquo; button:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/appveyor-new-project-select.png" alt="AppVeyor projects"></p>
<p>After some processing, our project&rsquo;s own build page is shown:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/appveyor-latest-build.png" alt="AppVeyor projects"></p>
<p>By default, it shows the latest build, which we don&rsquo;t yet have. To build our project, we once again create a YAML configuration file in our project&rsquo;s root, this time named <code>appveyor.yml</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">nodejs_version</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0.12&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">install</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">ps</span><span class="p">:</span><span class="w"> </span><span class="l">Install-Product node $env:nodejs_version</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">npm install</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">npm install -g gulp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">test_script</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">gulp ci</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">build</span><span class="p">:</span><span class="w"> </span><span class="kc">off</span><span class="w">
</span></span></span></code></pre></div><p>This build file will cause AppVeyor to do the following things:</p>
<ul>
<li>Create a worker environment.</li>
<li>Use Git to clone our repository.</li>
<li>Install Node.js.</li>
<li>Run <code>npm install</code> to install any package dependencies.</li>
<li>Install Gulp.</li>
<li>Run the <code>gulp ci</code> script.</li>
<li>Determine the build&rsquo;s success by looking at the exit code.</li>
</ul>
<p>Note that we set the <code>build</code> configuration option to <code>off</code>, as we want to disable AppVeyor&rsquo;s automatic build command feature, as that only works for .NET repositories.</p>
<p>We then commit the <code>appveyor.yml</code> file to our repository and push it to GitHub. AppVeyor will detect this change to our repository and add it to its build queue. After a short while, the build will be run and its output is written to the screen:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/appveyor-build-log.png" alt="AppVeyor build log"></p>
<p>Once again, you can clearly see that the steps that were executed reflect our YAML configuration file.</p>
<h3 id="badge-1">Badge</h3>
<p>AppVeyor also supports badges, which you can find in the &ldquo;Badges&rdquo; section on the project&rsquo;s &ldquo;SETTINGS&rdquo; tab:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/appveyor-badge.png" alt="AppVeyor badge"></p>
<p>Once again, we&rsquo;ll select the Markdown format and add it to our readme file:</p>
<pre tabindex="0"><code>[![Build status](https://ci.appveyor.com/api/projects/status/9odakh2g33mtpbm5?svg=true)](https://ci.appveyor.com/project/ErikSchierboom/knockout-paging)
</code></pre><p>Having pushed our modified readme to the repository, it now also shows the AppVeyor badge:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/appveyor-badge-status.png" alt="AppVeyor badge status"></p>
<h2 id="code-coverage">Code coverage</h2>
<p>As our build servers also run our library&rsquo;s tests, we can do one last cool thing: generate code coverage reports and automatically upload them to <a href="https://coveralls.io/">coveralls.io</a>.</p>
<p>First, you need to create an account at <a href="https://coveralls.io/">coveralls.io</a>. You can use your GitHub or Bitbucket credentials to sign up. After authentication finishes, you&rsquo;ll be redirected to your projects page:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-projects.png" alt="Coveralls projects"></p>
<p>We now need to select the repository for which we want to store coverage. We do that by clicking on the &ldquo;ADD REPOS&rdquo; button. We will then be shown an overview of all our repositories:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-repos.png" alt="Coveralls repositories"></p>
<p>Using the search box, we search for our repository:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-repo.png" alt="Coveralls repository"></p>
<p>We then click on the &ldquo;OFF&rdquo; button, which will enable coverage data to be stored for that repository.</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-repos-active.png" alt="Coveralls filter repositories"></p>
<p>When coverage has been enabled, the button becomes green and its text will change to &ldquo;ON&rdquo;. An additional button named &ldquo;DETAILS&rdquo; will also have appeared. Click on that button. This will show our repository&rsquo;s page:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-details.png" alt="Coveralls active repository"></p>
<p>As we don&rsquo;t have any coverage at the moment, instructions are displayed on how to get started. The first step is to have our library generate code coverage reports.</p>
<h3 id="generating-code-coverage-reports">Generating code coverage reports</h3>
<p>Because code coverage is determined by running tests, we need to hook up a code coverage tool to our library&rsquo;s test runner: Mocha. One of the best code coverage libraries is <a href="http://blanketjs.org/">blanket.js</a>, which supports QUnit, Jasmine <em>and</em> Mocha. Let&rsquo;s install Blanket:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm install blanket --save-dev
</span></span></code></pre></div><p>To have Blanket correctly calculate code coverage, we need to add a <code>&quot;config&quot;</code> section to the <code>package.json</code> file. For our library, this <code>&quot;config&quot;</code> section looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;config&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;blanket&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;pattern&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;index.js&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;data-cover-never&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;node_modules&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The most important part is the <code>&quot;pattern&quot;</code> key, which contains the filenames Blanket should be generating code coverage for. As our library is contained in a single <code>index.js</code> file, we only list that file. The <code>&quot;data-cover-never&quot;</code> key specifies the files or directories to ignore. We set it to <code>&quot;node_modules&quot;</code> to prevent any package dependencies from accidentally being analyzed.</p>
<p>Believe it or not, but we are now ready to generate code coverage reports! Generating the actual coverage report is done through Mocha, which is a dependency of our library and thus already installed. To create a coverage report using Mocha, we add an entry to the <code>&quot;scripts&quot;</code> section in our <code>package.json</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;scripts&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;coverage&#34;</span><span class="p">:</span> <span class="s2">&#34;mocha --require blanket -R html-cov &gt; coverage.html&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This new <code>&quot;coverage&quot;</code> command runs Mocha, including the blanket code coverage library. The <code>&quot;-R&quot;</code> option specifies the type of report we want to output, which in our case is an HTML report that will be written to <code>coverage.html</code>.</p>
<p>We can now create the report by executing:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm run coverage
</span></span></code></pre></div><p>This will create the <code>coverage.html</code> file, which you can view in a browser:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-html-report.png" alt="Coveralls HTML report"></p>
<p>This report lists the code coverage percentage and highlights uncovered lines in red.</p>
<p>Unfortunately, this HTML coverage report cannot be used as input for coveralls.io, which requires code coverage reports in a JSON-based format:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;example.rb&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;source_digest&#34;</span><span class="p">:</span> <span class="s2">&#34;asdfasdf1234asfasdf2345&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;coverage&#34;</span><span class="p">:</span> <span class="p">[</span><span class="kc">null</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="kc">null</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>To have our library submit code coverage reports to coveralls.io in the correct format, we first install the <code>mocha-lcov-reporter</code> library:</p>
<pre tabindex="0"><code>npm install mocha-lcov-reporter --save-dev
</code></pre><p>This library adds a reporter to Mocha that outputs coverage data in a more structured format.</p>
<p>Let&rsquo;s add another entry to the <code>&quot;scripts&quot;</code> section in our <code>package.json</code> file that uses this new reporter:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;scripts&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;coverage-lines&#34;</span><span class="p">:</span> <span class="s2">&#34;mocha --require blanket -R mocha-lcov-reporter &gt; coverage.lcov&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we run this command, the resulting <code>coverage.lcov</code> file looks something like this:</p>
<pre tabindex="0"><code>SF:D:Programmerenknockout-pagingindex.js
DA:9,1
DA:10,1
DA:11,0
DA:12,1
DA:13,1
DA:15,0
DA:22,1
DA:25,1
</code></pre><p>This file bears some resemblance to coveralls.io&rsquo;s JSON format, but it is not quite the same. To convert this file to the coveralls.io format, we&rsquo;ll need the <code>coveralls</code> package:</p>
<pre tabindex="0"><code>npm install coveralls --save-dev
</code></pre><p>This library can convert <code>mocha-lcov-reporter</code> coverage files to the coveralls.io format, which it then submits to coveralls.io.</p>
<p>Before we can use this library to submit our coverage results, we have to let the <code>coveralls</code> library know which coveralls.io repository it should send the coverage to. For this, you have to use the repository&rsquo;s unique token, which can be found on the project&rsquo;s page:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-details-token.png" alt="Coveralls token"></p>
<p>So how do provide the <code>coveralls</code> library with the correct repository token? There are actually two options:</p>
<ol>
<li>Create a <code>.coveralls.yml</code> file that has a <code>repo_token</code> key which value is the repository token.</li>
<li>Set a <code>COVERALLS_REPO_TOKEN</code> environment variable to the repository token.</li>
</ol>
<p>You should only use the first option for private repositories, but as our library is open-source, we&rsquo;ll use the second option.</p>
<p>As we want to use Travis to automatically submit our coverage reports, we first go to our repository&rsquo;s settings page on Travis. There, you&rsquo;ll find a section named &ldquo;Environment Variables&rdquo;:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-environment.png" alt="Travis enviroment settings"></p>
<p>At the moment, there are no environment variables, so we&rsquo;ll click on the &ldquo;Add&rdquo; button. This will show two input fields: one for the environment variable&rsquo;s name and one for its value:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-environment-values.png" alt="Travis enviroment value"></p>
<p>After we have entered the correct name and value, we click on the &ldquo;Add&rdquo; button to save the environment variable. From now on, any new builds will have its <code>COVERALLS_REPO_TOKEN</code> enviroment variable set to the value we specified.</p>
<p>Note that for security reasons, you won&rsquo;t see the actual value on the settings page:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/travis-environment-values-saved.png" alt="Travis enviroment value"></p>
<p>The final step is to modify our <code>.travis.yml</code> file to submit the coverage results to coveralls.io after each successful build. To do so, we add an <code>after_success</code> section which does the following things:</p>
<ul>
<li>Use Mocha to run our tests.</li>
<li>Run Mocha using the <code>blanket</code> library to detect code coverage.</li>
<li>Use the <code>mocha-lcov-reporter</code> reporter to output the code coverage results.</li>
<li>Pipe the code coverage results to the <code>coveralls.js</code> file from the <code>coveralls</code> package.</li>
<li><code>coveralls.js</code> converts the coverage results to the coveralls.io format.</li>
<li><code>coveralls.js</code> submits the converted coverage results to coveralls.io.</li>
</ul>
<p>These steps are all done in a single command, which we add to the <code>.travis.yml</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">after_success</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="l">NODE_ENV=test YOURPACKAGE_COVERAGE=1 ./node_modules/.bin/mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js</span><span class="w">
</span></span></span></code></pre></div><p>We then commit our modified <code>.travis.yml</code> file and push it to GitHub. This will cause Travis to do a new build of our repository, but this time it will also submit the coverage results to coveralls.io.</p>
<p>Once the build has completed, we can see the coverage results on our repository&rsquo;s coveralls.io page:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-coverage.png" alt="Coveralls coverage"></p>
<p>We can drill down on the coverage for an individual build by clicking on the build number. This will show the coverage details for that build:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-coverage-details.png" alt="Coveralls coverage details"></p>
<p>One very handy feature is that by clicking on one of the covered files, that file will be displayed and each covered line will have a green background, whereas each uncovered line will have a red background:</p>
<p><img src="/images/posts/building-a-javascript-library-part-5-build-server/coveralls-coverage-lines.png" alt="Coveralls lines coverage"></p>
<p>And now we have setup Travis to automatically calculate our library&rsquo;s code coverage and submit it to coveralls.io.</p>
<h2 id="conclusion">Conclusion</h2>
<p>For our library, we wanted to ensure maximum compatibility. To this end, we setup the Travis and AppVeyor build servers to automatically build and test our library whenever the repository is modified.</p>
<p>Both Travis and AppVeyor were easy to setup, requiring a small number of clicks to enable automatic builds for our repository as well as creating a configuration file specifying how builds should be run. Furthermore, as Travis runs on Linux and AppVeyor on Windows, we automatically test different platforms.</p>
<p>Setting up automatic code coverage reports was slightly more work, but also not that difficult using the free coveralls.io service.</p>
<p>In the <a href="https://www.erikschierboom.com/2015/11/04/building-a-javascript-library-part-6-typescript/">next post</a> we&rsquo;ll add support for TypeScript.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library - part 4: package managers</title>
			<link>https://www.erikschierboom.com/2015/10/05/building-a-javascript-library-part-4-package-managers/</link>
			<pubDate>Mon, 05 Oct 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/10/05/building-a-javascript-library-part-4-package-managers/</guid>
			<description>This is the fourth in a series of posts that discuss the steps taken to publish our library. Our previous post went into detail on how we open-sourced our library. This post describes how we added support for package managers.
Package managers When building software, you&amp;rsquo;ll likely use (and thus depend on) software built by others. Here is how you&amp;rsquo;d manually add a software dependency to your project:
Find the website of the software you want to use.</description>
			<content type="html"><![CDATA[<p>This is the fourth in a <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> that discuss the steps taken to publish our library. Our <a href="https://www.erikschierboom.com/2015/08/22/building-a-javascript-library-part-3-open-sourcing/">previous post</a> went into detail on how we open-sourced our library. This post describes how we added support for package managers.</p>
<h2 id="package-managers">Package managers</h2>
<p>When building software, you&rsquo;ll likely use (and thus depend on) software built by others. Here is how you&rsquo;d manually add a software dependency to your project:</p>
<ul>
<li>Find the website of the software you want to use.</li>
<li>Search the website for the correct version of the software.</li>
<li>Download the software.</li>
<li>Copy the software to your project.</li>
<li>Possibly run some installation scripts.</li>
<li>Add the software to version control.</li>
</ul>
<p>This might not seem that bad, but what if you have many dependencies or want to upgrade to a newer version? You&rsquo;d have to repeat the previous steps for each dependency, which is both tedious and error prone.</p>
<p>A package manager can help you manage your software dependencies (also referred to as <em>packages</em>). It allows you to:</p>
<ul>
<li>Search for packages.</li>
<li>Install and uninstall packages.</li>
<li>Upgrade packages.</li>
<li>Restore packages.</li>
</ul>
<p>Any time you install, uninstall or upgrade a package, the package manager modifies a configuration file, which contains all dependencies.</p>
<p>As the package manager can restore all dependencies using the configuration file, you should only add the configuration file to source control, not the installed dependencies.</p>
<h3 id="implementations">Implementations</h3>
<p>There is a package manager for virtually every major language/platform:</p>
<ul>
<li><a href="https://www.nuget.org/">NuGet</a> (.NET)</li>
<li><a href="https://maven.apache.org/">Maven</a> (Java)</li>
<li><a href="https://rubygems.org/">RubyGems</a> (Ruby)</li>
<li><a href="https://pip.pypa.io/en/stable/">Pip</a> (Python)</li>
</ul>
<p>As our library was written in JavaScript, we&rsquo;ll add support for its three most popular package managers:</p>
<ul>
<li><a href="https://www.npmjs.com/">NPM</a></li>
<li><a href="http://bower.io">Bower</a></li>
<li><a href="http://jspm.io/">JSPM</a></li>
</ul>
<h3 id="npm">NPM</h3>
<p>The first package manager we&rsquo;ll look at is Node&rsquo;s package manager: <a href="https://www.npmjs.com/">NPM</a>. In Node, a project defines its metadata in a file named <code>package.json</code>, located in the project&rsquo;s root.</p>
<p>A minimal version of this file only contains the library&rsquo;s name and version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;knockout-paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;0.2.1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>There are <a href="https://docs.npmjs.com/files/package.json">many more fields</a> you can use though:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;knockout-paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;0.2.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;Adds paging functionality to Knockout.&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;main&#34;</span><span class="p">:</span> <span class="s2">&#34;dist/knockout-paging.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;files&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;LICENSE&#34;</span><span class="p">,</span> <span class="s2">&#34;README.md&#34;</span><span class="p">,</span> <span class="s2">&#34;index.js&#34;</span><span class="p">,</span> <span class="s2">&#34;dist&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;repository&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;git&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;git@github.com/ErikSchierboom/knockout-paging.git&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;keywords&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;knockout&#34;</span><span class="p">,</span> <span class="s2">&#34;paging&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;author&#34;</span><span class="p">:</span> <span class="s2">&#34;Erik Schierboom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;license&#34;</span><span class="p">:</span> <span class="s2">&#34;Apache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;bugs&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://github.com/ErikSchierboom/knockout-paging/issues&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;homepage&#34;</span><span class="p">:</span> <span class="s2">&#34;https://github.com/ErikSchierboom/knockout-paging&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>In general, the more fields you specify, the better. Of special note is the <code>&quot;files&quot;</code> field, which specifies what files are copied when the package is installed.</p>
<h4 id="submitting">Submitting</h4>
<p>To be able to submit a project to NPM, we first have to authenticate to NPM:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm adduser
</span></span></code></pre></div><p>Just follow the instructions to create an account or login to an existing account.</p>
<p>Then we navigate to the project&rsquo;s root (where the <code>package.json</code> file is stored) and do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm publish
</span></span></code></pre></div><p>This command parses the <code>package.json</code> file and submits its metadata to NPM. And that&rsquo;s all! Our library has now been published and has its own <a href="https://www.npmjs.com/package/knockout-paging">page at NPMJS.com</a>.</p>
<h4 id="installing">Installing</h4>
<p>At this point, people can install our library using NPM:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm install knockout-paging
</span></span></code></pre></div><p>This will install the library in the <code>node_modules</code> directory, ready for use:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>You can see that the files specified in the <code>&quot;files&quot;</code> field in the <code>package.json</code> file were copied, along with the <code>package.json</code> file itself and the <code>knockout</code> package dependency, which is stored in a nested <code>node_modules</code> directory.</p>
<h5 id="sources">Sources</h5>
<p>NPM can install packages from the following sources:</p>
<ul>
<li>NPM registry</li>
<li>Local folder</li>
<li>Git endpoints</li>
</ul>
<p>That means we could also have used:</p>
<pre tabindex="0"><code>npm install git://github.com/ErikSchierboom/knockout-paging.git
</code></pre><p>or</p>
<pre tabindex="0"><code>npm install /Users/erikschierboom/Programming/knockout-paging
</code></pre><p>to install our library.</p>
<h4 id="updating">Updating</h4>
<p>If you have made changes to your project and you want to publish the updated version on NPM, you have to do two things:</p>
<ol>
<li>Update the version number in your <code>package.json</code> file (using <a href="http://semver.org/">semantic versioning</a>).</li>
<li>Do an <code>npm publish</code>.</li>
</ol>
<p>Again, the <code>npm publish</code> command will parse the <code>package.json</code> file and update the NPM repository. Note that older versions will remain available.</p>
<p>Note that you can install a specific version using <code>&lt;package&gt;@&lt;version&gt;</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm install knockout-paging@0.0.1
</span></span></code></pre></div><h3 id="bower">Bower</h3>
<p>The second package manager we&rsquo;ll be supporting is <a href="http://bower.io">Bower</a>, which is a bit different from NPM. Whereas NPM is primarily used to distribute software, Bower is often also used to distribute images, CSS and such.</p>
<p>For our library, we&rsquo;ll use Bower to distribute software, like we did with NPM. We start by creating a file in our project&rsquo;s root named <code>bower.json</code>.</p>
<p>A minimal <code>bower.json</code> file only contains the name of the library:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;knockout-paging&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Once again, there are <a href="https://github.com/bower/bower.json-spec">many more fields</a> you can use:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;knockout-paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;main&#34;</span><span class="p">:</span> <span class="s2">&#34;dist/knockout-paging.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;homepage&#34;</span><span class="p">:</span> <span class="s2">&#34;https://github.com/ErikSchierboom/knockout-paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;authors&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;Erik Schierboom&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;Adds paging functionality to Knockout.&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;keywords&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;knockout&#34;</span><span class="p">,</span> <span class="s2">&#34;foreach&#34;</span><span class="p">,</span> <span class="s2">&#34;paging&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;license&#34;</span><span class="p">:</span> <span class="s2">&#34;Apache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;ignore&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">,</span> <span class="s2">&#34;!dist/*&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;dependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;knockout&#34;</span><span class="p">:</span> <span class="s2">&#34;^3.2.0&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Once again, the more fields you supply, the better. By default, Bower copies all files in your project when installed. However, you can exclude files and folders using the <code>&quot;ignore&quot;</code> field.</p>
<h4 id="submitting-1">Submitting</h4>
<p>Before we can submit our library, we need to look at how Bower handles versioning of packages. Whereas NPM uses the <code>&quot;version&quot;</code> field in the <code>package.json</code> file, Bower scans the available <a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging">Git</a> or <a href="http://svnbook.red-bean.com/en/1.7/svn.branchmerge.tags.html">SVN</a> tags. If those tags are named using <a href="http://semver.org/">semantic versioning</a>, Bower will be able to infer the available versions.</p>
<p>As an example, to create a version <code>0.0.1</code> package for our library, we create a tag named &ldquo;<code>0.0.1</code>&rdquo; using the following commands:</p>
<pre tabindex="0"><code># commit files for version
git commit -am &#34;First release&#34;

# tag the commit
git tag -a 0.0.1 -m &#34;Version 0.0.1&#34;

# push commit to GitHub
git push

# push tag to GitHub
git push origin 0.0.1
</code></pre><p>These commands first create a commit, then create a tag named <code>&quot;0.1.1&quot;</code> linked to that commit and finally push both the commit and the tag to GitHub.</p>
<p>Having done that, we can now register our library with Bower. First we need to install Bower globally using NPM:</p>
<pre tabindex="0"><code>npm install -g bower
</code></pre><p>Then all we have to do is:</p>
<pre tabindex="0"><code>bower register knockout-paging git@github.com/ErikSchierboom/knockout-paging.git
</code></pre><p>This command registers a Bower package named <code>knockout-paging</code> located at the specified Git endpoint.</p>
<h4 id="installing-1">Installing</h4>
<p>To install the library through Bower, we can now use:</p>
<pre tabindex="0"><code>bower install knockout-paging
</code></pre><p>When this command executes, Bower does the following things:</p>
<ul>
<li>Find the source for the <code>knockout-paging</code> package.</li>
<li>Checkout the source to the <code>bower_components/knockout-paging</code> directory.</li>
<li>Remove all files matching any of the rules in the <code>&quot;ignore&quot;</code> field.</li>
<li>Install all dependencies listed in the <code>&quot;dependencies&quot;</code> field.</li>
</ul>
<p>After the command has completed, it will have created the following files:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>You can see that Bower used the <code>&quot;ignore&quot;</code> field to copy everything but the <code>dist</code> folder. Note that the <code>bower.json</code> is always copied.</p>
<p>If we look at the console output of the <code>bower install knockout-paging</code> command, we can clearly see that Bower automatically inferred the package version to <code>&quot;0.0.1&quot;</code>, even though we did not specify a version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">bower cached        git://github.com/ErikSchierboom/knockout-paging.git#0.0.1
</span></span><span class="line"><span class="cl">bower validate      0.0.1 against git://github.com/ErikSchierboom/knockout-paging.git#*
</span></span><span class="line"><span class="cl">bower cached        git://github.com/SteveSanderson/knockout.git#3.2.0
</span></span><span class="line"><span class="cl">bower validate      3.2.0 against git://github.com/SteveSanderson/knockout.git#^3.2.0
</span></span><span class="line"><span class="cl">bower install       knockout-paging#0.0.1
</span></span><span class="line"><span class="cl">bower install       knockout#3.2.0
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">knockout-paging#0.2.1 bower_components/knockout-paging
</span></span><span class="line"><span class="cl">└── knockout#3.2.0
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">knockout#3.2.0 bower_components/knockout
</span></span></code></pre></div><h5 id="sources-1">Sources</h5>
<p>Bower can install packages from the following sources:</p>
<ul>
<li>Bower registry</li>
<li>Local folders</li>
<li>Git endpoints</li>
<li>Subversion endpoints</li>
<li>URL&rsquo;s</li>
</ul>
<p>As can be seen, you can also use Bower to install libraries that have not been submitted to Bower. For example, we could also install our library using its Git endpoint:</p>
<pre tabindex="0"><code>bower install git://github.com/ErikSchierboom/knockout-paging.git
</code></pre><p>or install it from a local folder:</p>
<pre tabindex="0"><code>bower install /Users/erikschierboom/Programming/knockout-paging
</code></pre><h4 id="updating-1">Updating</h4>
<p>To update a package, just create a new tag with the correct semver name:</p>
<pre tabindex="0"><code># commit files for new version
git commit -am &#34;Awesome update&#34;

# tag the commit
git tag -a 0.0.2 -m &#34;Version 0.0.2&#34;

# push commit to GitHub
git push

# push tag to GitHub
git push origin 0.0.2
</code></pre><p>Now, when someone tries to install the <code>knockout-paging</code> package using Bower, it will automatically install version <code>0.0.2</code>.</p>
<p>Note that you can also explicitly specify the version Bower should install using <code>&lt;package&gt;#&lt;version&gt;</code>:</p>
<pre tabindex="0"><code>bower install knockout-paging#0.0.1
</code></pre><h3 id="jspm">JSPM</h3>
<p>The third and last package manager we&rsquo;ll add support for is <a href="http://jspm.io/">JSPM</a>, which is the <em>new kid on the block</em>. JSPM is a package manager for the <a href="https://github.com/systemjs/systemjs">SystemJS universal module loader</a>, which can load AMD, CommonJS, ES6 or global modules.</p>
<h4 id="submitting-2">Submitting</h4>
<p>Like NPM, JSPM uses the <code>package.json</code> file for describing the package. JSPM <a href="https://github.com/jspm/registry/wiki/Configuring-Packages-for-jspm">extends the package.json spec</a> with new properties, most notably the following two properties:</p>
<ul>
<li><code>&quot;registry&quot;</code>: the registry to use when JSPM install the package. Supported values are: <code>&quot;jspm&quot;</code>, <code>&quot;npm&quot;</code> and <code>&quot;github&quot;</code>.</li>
<li><code>&quot;format&quot;</code>: the module format used by the package. Its value is either, <code>&quot;es6&quot;</code>, <code>&quot;amd&quot;</code>, <code>&quot;cjs&quot;</code> or <code>&quot;global&quot;</code>.</li>
</ul>
<p>To indicates that we want JSPM to use the NPM registry for our library, which is written as a global module, we modify our library&rsquo;s <code>package.json</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="err">...</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;registry&#34;</span><span class="p">:</span> <span class="s2">&#34;npm&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;global&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>To allow JSPM to use these fields, we must publish new versions of our library, that include the changed <code>package.json</code> file, to NPM and GitHub.</p>
<p>Having done that, the final step is to add our library to the <a href="http://kasperlewau.github.io/registry/">JSPM registry</a>. This is done by adding our library to the <a href="https://github.com/jspm/registry/blob/master/registry.json"><code>registry.json</code></a> file in the <a href="https://github.com/jspm/registry">JSPM repository</a>.</p>
<p>To do so, first we <a href="https://github.com/ErikSchierboom/registry">fork the JSPM repository</a>. Next, we&rsquo;ll clone our fork to our local machine. There, we&rsquo;ll modify the <code>registry.json</code> file to define a JSPM package for our library:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;knockout-paging&#34;</span><span class="err">:</span> <span class="s2">&#34;npm:knockout-paging&#34;</span><span class="err">,</span>
</span></span></code></pre></div><p>The key is our package name (which is used to install the package) and the value is a combination of the registry and the registry&rsquo;s source.</p>
<p>Finally, we&rsquo;ll commit this change, push it to our fork on GitHub and send a pull-request. Once the pull-request has been accepted, our library has been <a href="http://kasperlewau.github.io/registry/#/?q=knockout-paging">added to the JSPM registry</a>.</p>
<h4 id="installing-2">Installing</h4>
<p>To install our library, we first need to install JSPM globally:</p>
<pre tabindex="0"><code>npm install -g jspm
</code></pre><p>Once installed, we can do:</p>
<pre tabindex="0"><code>jspm install knockout-paging
</code></pre><p>This will cause JSPM to search its registry for the source of the <code>knockout-paging</code> package (which we set to NPM earlier). You can see this happening if you examine the output of the <code>jspm install</code> command we just executed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Updating registry cache...
</span></span><span class="line"><span class="cl">Looking up npm:knockout-paging
</span></span><span class="line"><span class="cl">Downloading npm:knockout-paging@0.2.2
</span></span><span class="line"><span class="cl">Looking up npm:knockout
</span></span><span class="line"><span class="cl">Installed npm:knockout@^3.2.0 <span class="o">(</span>3.3.0<span class="o">)</span>
</span></span><span class="line"><span class="cl">...
</span></span></code></pre></div><p>Once the command has completed, JSPM will have created the following files:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h5 id="sources-2">Sources</h5>
<p>JSPM supports installing packages from the following sources:</p>
<ul>
<li>JSPM registry</li>
<li>NPM registry</li>
<li>GitHub</li>
</ul>
<p>As an example, we could install <a href="https://jquery.com/">jQuery</a> using each of the three sources:</p>
<pre tabindex="0"><code>jspm install jquery               // Use the JSPM registry

jspm install npm:jquery           // Use the NPM registry

jspm install github:jquery/jquery // Use GitHub
</code></pre><h4 id="updating-2">Updating</h4>
<p>To update a package, you just use the registry&rsquo;s specific updating strategy. For NPM, that means updating the <code>package.json</code> file followed by a publish to the NPM registry. For GitHub, that means creating a release/tag using the proper semantic versioning name.</p>
<h2 id="conclusion">Conclusion</h2>
<p>As most software is installed through package managers nowadays, it was vital that our library could be installed using a package manager. We added support for the most popular JavaScript package managers: NPM, Bower and JSPM. Supporting those package managers was easy, it involved not much more than creating and publishing a JSON config file describing the package. When creating and updating packages, be aware that the package managers expect packages to use <a href="http://semver.org/">semantic versioning</a>.</p>
<p>The <a href="https://www.erikschierboom.com/2015/10/26/building-a-javascript-library-part-5-build-server/">next post</a> shows how we enabled build servers to automatically build and test our software.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library - part 3: open-sourcing</title>
			<link>https://www.erikschierboom.com/2015/08/22/building-a-javascript-library-part-3-open-sourcing/</link>
			<pubDate>Sat, 22 Aug 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/08/22/building-a-javascript-library-part-3-open-sourcing/</guid>
			<description>This is the third in a series of posts that discuss the steps taken to publish our library. Our previous post showed how we automated repetitive tasks. This post describes how we open-sourced our library.
Why open-source? Before we&amp;rsquo;ll describe how we made our library open-source, let&amp;rsquo;s first ask: why ? What exactly are the benefits of making code open-source?
As it turns out, open-sourcing code has several advantages:
You don&amp;rsquo;t have to do everything yourself.</description>
			<content type="html"><![CDATA[<p>This is the third in a <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> that discuss the steps taken to publish our library. Our <a href="https://www.erikschierboom.com/2015/08/12/building-a-javascript-library-part-2-automation/">previous post</a> showed how we automated repetitive tasks. This post describes how we open-sourced our library.</p>
<h2 id="why-open-source">Why open-source?</h2>
<p>Before we&rsquo;ll describe <em>how</em> we made our library open-source, let&rsquo;s first ask: <em>why</em> ? What exactly are the benefits of making code open-source?</p>
<p>As it turns out, open-sourcing code has several advantages:</p>
<ul>
<li>You don&rsquo;t have to do everything yourself. People all over the world can contribute (e.g. <a href="https://github.com/nodejs/node">node.js</a> has over 700 contributors). This means the software can be developed faster and cheaper.</li>
<li>You benefit from the knowledge of others. They will find bugs you didn&rsquo;t and come up with new ideas. Furthermore, they will help you improve your code, making you a better programmer.</li>
<li>Your code becomes part of your CV. Not only does it demonstrate your skills as a programmer, it also implies you are passionate about developing software. Recruiters also actively scan open-source projects for potential candidates.</li>
<li>You use open-source software everyday (even without knowing it), why not give back to the community? It is the right thing to do.</li>
<li>It forces you to think on how to setup your project. If the code is difficult to work with or hard to build, you won&rsquo;t find many people helping you.</li>
<li>It is fun! Collaboratively developing software is one of my greatest joys in programming.</li>
</ul>
<p>Of course there are also disadvantages to open-sourcing your code:</p>
<ul>
<li>People expect you to actively maintain your code. Not only will they expect you to fix bugs, but also to add new features.</li>
<li>You can mistakenly publish sensitive data (more on that later).</li>
<li>You can get into license trouble (more on this later too).</li>
<li>Monetizing your software becomes harder.</li>
</ul>
<p>We feel the advantages overwhelmingly outweigh the disadvantages, which is why we chose to open-source our library.</p>
<h2 id="preparing-for-open-sourcing-code">Preparing for open-sourcing code</h2>
<p>Before we&rsquo;ll actually open-source our code, there are some things left to do.</p>
<h3 id="write-documentation">Write documentation</h3>
<p>Although open-source code allows people to inspect the code to find out how it works, you <em>should</em> still write documentation. If you are not convinced of the benefits of writing documentation, try using a new library without reading any of its documentation. ;)</p>
<p>The documentation should at least specify:</p>
<ul>
<li>What functionality the library offers.</li>
<li>How to use the library, preferrably using examples showing common use cases.</li>
<li>How to install the library.</li>
</ul>
<p>For open-source projects, the documentation should also contain:</p>
<ul>
<li>The license the code is released under.</li>
<li>A description on how people can contribute.</li>
</ul>
<p>A <code>README</code> file containing this minimal documentation should be stored alongside your source code for easy access. Note that this documentation file should be relatively small, people should be able to read it quickly.</p>
<h4 id="separate-documentation-website">Separate documentation website</h4>
<p>If you feel that the minimal <code>README</code> file cannot describe your library in enough detail, you should consider creating a separate documentation website. The <a href="https://github.com/HangfireIO/Hangfire">Hangfire</a> library does precisely this, with a compact <a href="https://github.com/HangfireIO/Hangfire/blob/master/README.md">README</a> to get you started but also a separate <a href="http://docs.hangfire.io/en/latest/">documentation website</a> that goes into far more detail.</p>
<h4 id="documentation-tools">Documentation tools</h4>
<p>There are many tools for writing documentation, such as <a href="http://jekyllrb.com/">Jekyll</a> (used on <a href="http://getbootstrap.com/">getbootstrap.com</a>) and <a href="http://sphinx-doc.org/">Sphinx</a> (used on <a href="http://docs.asp.net/en/latest/">docs.asp.net</a>). One benefit of Sphinx is that <a href="https://readthedocs.org/">readthedocs.org</a> provides free hosting for your documentation!</p>
<p>To make things really open, you can also open-source your documentation! This is done by the aforementioned <a href="http://docs.asp.net/en/latest/">docs.asp.net</a>, which contents are <a href="https://github.com/aspnet/Docs">hosted on GitHub</a>.</p>
<p>Note: some people use documentation generators like <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> or <a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a>, which generate documentation by parsing source code. While this is a convenient way to quickly &ldquo;write&rdquo; some documentation, it should only be used in addition to hand-written documentation.</p>
<h4 id="demos">Demos</h4>
<p>A great way to show how to use your library is to create one or more demos. There are several websites where you can create HTML demo applications for free, but we particularly like:</p>
<ul>
<li><a href="http://jsbin.com/">JS Bin</a></li>
<li><a href="http://jsfiddle.net/">JSFiddle</a></li>
</ul>
<p>Of course, you should link to any demo applications from your <code>README</code>.</p>
<p>Note: there are also &ldquo;Fiddle&rdquo; sites for other languages/platforms:</p>
<ul>
<li><a href="https://dotnetfiddle.net/">.NET fiddle</a> (C#, F# and VB)</li>
<li><a href="http://scalafiddle.net/console">Scala fiddle</a></li>
<li><a href="http://sqlfiddle.com/">SQL fiddle</a></li>
<li><a href="http://refiddle.com/">Regex fiddle</a></li>
</ul>
<p>You can find a comprehensive list of &ldquo;Fiddle&rdquo; sites at <a href="https://fiddles.io/">fiddles.io</a>.</p>
<h3 id="choosing-a-license">Choosing a license</h3>
<p>When code is open-source, it is important for other people to know what they are allowed to do with it. This is defined by a license. If you need help choosing a license, check out <a href="http://choosealicense.com/">choosealicense.com</a>.</p>
<p>For our library, we chose the <a href="http://choosealicense.com/licenses/apache-2.0/">Apache 2 license</a>, which lets other people freely use our code. The main difference with the popular <a href="http://choosealicense.com/licenses/mit/">MIT license</a> is that the Apache license has better protection against patent issues. You should probably also choose the Apache license if you want to <a href="http://tomtunguz.com/open-source-exits-by-license/">raise venture capital</a>.</p>
<p>You should mention the license in both your source code and the <code>README</code> file, as well as include it in a separate <a href="https://github.com/ErikSchierboom/knockout-paging/blob/master/LICENSE">LICENSE</a> file.</p>
<h3 id="cleaning-up">Cleaning up</h3>
<p>At this point, you should clean-up your code. As you are making your code public, why not make it as nice as you can? Note that if you have written tests, you should be able to safely refactor your code.</p>
<p>Having cleaned-up code is also in your best interest, as people are less likely to contribute code to your library if the code is hard to read or maintain.</p>
<h4 id="removing-sensitive-data">Removing sensitive data</h4>
<p>As part of the clean-up, please make sure that your code does not contain sensitive data like SSH keys or passwords. Even though GitHub has a page dedicated to <a href="https://help.github.com/articles/remove-sensitive-data/">dealing with sensitive data</a>, a simple <a href="https://github.com/search?p=2&amp;q=rackspace_api_key&amp;ref=searchresults&amp;type=Code">GitHub search</a> shows that many repositories still contain sensitive data.</p>
<p>Due to the distributed nature of open-source software (anyone could have a copy of your code), published sensitive data <em>must</em> be considered compromised, so make sure to remove sensitive data from your code <em>before</em> open-sourcing it.</p>
<h3 id="hosting">Hosting</h3>
<p>Our last task is to decide where to host our code. As we use <a href="https://git-scm.com/">Git</a> as our version control system, we are looking for websites that can host Git code. Luckily, there are several such websites:</p>
<ul>
<li><a href="https://github.com/">GitHub</a></li>
<li><a href="https://bitbucket.org/">Bitbucket</a></li>
<li><a href="http://www.codeplex.com/">Codeplex</a></li>
<li><a href="https://code.google.com/">Google Code</a> (will be shutdown in 2016)</li>
</ul>
<p>Hosting open-source code is completely free on all four websites. We chose GitHub mainly for its great collaboration options:</p>
<ul>
<li>Contributing code through through <a href="https://help.github.com/articles/using-pull-requests/">pull-requests</a>.</li>
<li>Keeping track of issues through the built-in <a href="https://help.github.com/articles/about-issues/">issue tracker</a>.</li>
</ul>
<p>There are other benefits of using GitHub:</p>
<ul>
<li>As most open-source projects are hosted on GitHub, most open-source contributors are also on GitHub.</li>
<li>An easy to setup <a href="https://help.github.com/articles/about-github-wikis/">wiki</a>.</li>
<li><a href="https://pages.github.com/">Free website hosting</a>.</li>
</ul>
<p>Having chosen GitHub to host our code, we then created a <a href="https://github.com/ErikSchierboom/knockout-paging">repository</a> for our library&rsquo;s code. If you need help creating a GitHub repository, check out this <a href="https://help.github.com/articles/create-a-repo/">tutorial</a>.</p>
<h3 id="publishing">Publishing</h3>
<p>Finally, we are ready to open-source our code! As our code already was in a local Git repository, we just add our GitHub repository&rsquo;s URL as a remote and push to it:</p>
<pre tabindex="0"><code># Link our local Git repository
git remote add origin git@github.com:ErikSchierboom/knockout-paging.git

# Push local commits to GitHub
git push origin master
</code></pre><p>And with that, <a href="https://github.com/ErikSchierboom/knockout-paging">our code</a> has been open-sourced.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Open-sourcing code is easy: just pick an online host and push your code to it. However, to create a great open-source project, you should write documentation, choose a license and clean-up your code. Although these tasks may seem like chores, they will give your project a much better chance at reaping the main benefit of open-sourcing code: getting help from others.</p>
<p>Our <a href="https://www.erikschierboom.com/2015/10/05/building-a-javascript-library-part-4-package-managers/">next post</a> examines how we allowed our library to be installed through package managers.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library - part 2: automation</title>
			<link>https://www.erikschierboom.com/2015/08/12/building-a-javascript-library-part-2-automation/</link>
			<pubDate>Wed, 12 Aug 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/08/12/building-a-javascript-library-part-2-automation/</guid>
			<description>This is the second in a series of posts that discuss the steps taken to publish our library. The previous post showed how we tested our library. In this post, we&amp;rsquo;ll look at how to automate repetitive tasks.
Task automation Developing a library is not just about writing code. We also have the following repetitive tasks:
Running tests. Creating a distribution version of our library. Creating a minified version of our distribution file.</description>
			<content type="html"><![CDATA[<p>This is the second in a <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> that discuss the steps taken to publish our library. The <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library-part-1-testing/">previous post</a> showed how we tested our library. In this post, we&rsquo;ll look at how to automate repetitive tasks.</p>
<h2 id="task-automation">Task automation</h2>
<p>Developing a library is not just about writing code. We also have the following repetitive tasks:</p>
<ul>
<li>Running tests.</li>
<li>Creating a distribution version of our library.</li>
<li>Creating a minified version of our distribution file.</li>
<li>Setting the correct version number in our distribution file.</li>
<li>Incrementing version numbers.</li>
</ul>
<p>All these repetitive tasks can be done manually, but we&rsquo;ll automate them. Automated tasks have several advantages over manual tasks:</p>
<ul>
<li>They run faster.</li>
<li>They run reliably.</li>
<li>They can be scheduled.</li>
</ul>
<p>To define and run automated tasks, we&rsquo;ll use a tool called a task runner. At the moment, the two most popular ones are <a href="http://gruntjs.com/">Grunt</a> and <a href="http://gulpjs.com/">Gulp</a>. Their most striking difference is that Grunt uses configuration files to define tasks and Gulp uses code.</p>
<p>Internally, Grunt works with files whereas Gulp work with streams. Using streams means that Gulp does less writing to disk and allows tasks to be <a href="http://blog.carbonfive.com/2014/05/05/roll-your-own-asset-pipeline-with-gulp/">chained efficiently</a>, which improves performance.</p>
<p>For our library, we&rsquo;ll use Gulp as we prefer doing our configuration in code.</p>
<h3 id="installing-gulp">Installing Gulp</h3>
<p>As Gulp runs on <a href="https://nodejs.org/">node.js</a>, the first step is to <a href="https://nodejs.org/download/">install node.js</a>. Once that is done, we can use the <a href="https://docs.npmjs.com/getting-started/what-is-npm">Node Package Manager</a> (NPM) to install <a href="https://www.npmjs.com/package/gulp">Gulp</a>:</p>
<pre tabindex="0"><code>npm install --global gulp
</code></pre><p>Note that we install Gulp globally, which allows us to run Gulp everywhere.</p>
<p>Next we install Gulp as a development dependency of our project:</p>
<pre tabindex="0"><code>npm install --save-dev gulp
</code></pre><p>Our final step is to create a <code>gulpfile.js</code> file in our project&rsquo;s root in which our tasks are defined:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">gulp</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;gulp&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;default&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// place code for your default task here
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><p>Here, we just define an empty task named <code>&quot;default&quot;</code>.</p>
<p>To run a task, just call <code>gulp &lt;taskname&gt;</code>, which in our case means:</p>
<pre tabindex="0"><code>gulp default
</code></pre><p>As <code>&quot;default&quot;</code> is, well, the default, we could have also used:</p>
<pre tabindex="0"><code>gulp
</code></pre><p>Now we&rsquo;re ready to start creating tasks.</p>
<h3 id="running-tests">Running tests</h3>
<p>As you <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library-part-1-testing/">might recall</a>, running our tests required us to open the test runner file in a web-browser. To run our tests using Gulp, being a command-line application, we need to use a <em>headless</em> browser, which is a browser without a GUI that can be run from the command-line.</p>
<p>We&rsquo;ll use the <a href="http://phantomjs.org/">PhantomJS</a> <em>headless</em> browser using the <a href="https://www.npmjs.com/package/gulp-mocha-phantomjs">gulp-mocha-phantomjs</a> plugin:</p>
<pre tabindex="0"><code>npm install gulp-mocha-phantomjs --save-dev
</code></pre><p>Next, we create a <code>&quot;test&quot;</code> task that uses PhantomJS to open our test runner file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">mochaPhantomJS</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;gulp-mocha-phantomjs&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;test&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">gulp</span><span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="s2">&#34;runner.html&#34;</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">mochaPhantomJS</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>If we run <code>gulp test</code>, the following will be printed to the screen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">D:<span class="se">\P</span>rogramming<span class="se">\k</span>nockout-paging&gt;gulp <span class="nb">test</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span>14:02:54<span class="o">]</span> Using gulpfile D:<span class="se">\P</span>rogrammeren<span class="se">\k</span>nockout-paging<span class="se">\g</span>ulpfile.js
</span></span><span class="line"><span class="cl"><span class="o">[</span>14:02:54<span class="o">]</span> Starting <span class="s1">&#39;test&#39;</span>...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  paged extender
</span></span><span class="line"><span class="cl">    V pageCount on empty paged observable array is <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="m">1</span> passing <span class="o">(</span>6ms<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>14:02:59<span class="o">]</span> Finished <span class="s1">&#39;test&#39;</span> after 4.8 s
</span></span></code></pre></div><p>You can see that phantomJS has opened our test runner file and written its output to the console. But what happens when one of the tests fail? Well, you&rsquo;ll see something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">D:<span class="se">\P</span>rogramming<span class="se">\k</span>nockout-paging&gt;gulp <span class="nb">test</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span>14:07:05<span class="o">]</span> Using gulpfile D:<span class="se">\P</span>rogrammeren<span class="se">\k</span>nockout-paging<span class="se">\g</span>ulpfile.js
</span></span><span class="line"><span class="cl"><span class="o">[</span>14:07:05<span class="o">]</span> Starting <span class="s1">&#39;test&#39;</span>...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  paged extender
</span></span><span class="line"><span class="cl">    1<span class="o">)</span> pageCount on empty paged observable array is <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="m">0</span> passing <span class="o">(</span>7ms<span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="m">1</span> failing
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  1<span class="o">)</span> paged extender pageCount on empty paged observable array is 1:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      AssertionError: expected <span class="m">1</span> to equal <span class="m">329</span>
</span></span><span class="line"><span class="cl">      + expected - actual
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      +329
</span></span><span class="line"><span class="cl">      -1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>14:07:09<span class="o">]</span> <span class="s1">&#39;test&#39;</span> errored after 4.79 s
</span></span><span class="line"><span class="cl"><span class="o">[</span>14:07:09<span class="o">]</span> Error in plugin <span class="s1">&#39;gulp-mocha-phantomjs&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">test</span> failed
</span></span></code></pre></div><p>The test task now outputs the failed assertion and an error message: <code>Error in plugin 'gulp-mocha-phantomjs'</code>. This is Gulp warning us that the <code>'gulp-mocha-phantomjs'</code> task returned an error code, which it does when one or more tests fail.</p>
<p>You can use this error returning feature to define tasks that only succeed when all tests pass, ideal for continuous integration scenarios. For example, we can define a <code>&quot;integration&quot;</code> task that depends on the <code>&quot;test&quot;</code> task to run successfully:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;integration&#34;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&#34;test&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// This will only execute when the &#39;test&#39; task is successful
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><h3 id="creating-a-distribution-file">Creating a distribution file</h3>
<p>Our library is developed in the <code>index.js</code> file in our root folder. However, it is customary to place the files you want to distribute in a separate folder. We&rsquo;ll use the <code>dist</code> folder for that. What we want is for Gulp to copy our <code>index.js</code> file to <code>dist/knockout-paging.js</code>. For that we&rsquo;ll need the <a href="https://www.npmjs.com/package/gulp-rename">gulp-rename</a> plugin:</p>
<pre tabindex="0"><code>npm install gulp-rename --save-dev
</code></pre><p>The actual Gulp task is quite simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;dist&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">gulp</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="s2">&#34;./index.js&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">rename</span><span class="p">(</span><span class="s2">&#34;knockout-paging.js&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s2">&#34;./dist&#34;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>When we run <code>gulp dist</code>, the <code>index.js</code> file&rsquo;s contents will be copied to <code>dist/knockout-paging.js</code>.</p>
<h3 id="creating-minified-distribution-file">Creating minified distribution file</h3>
<p>In the previous step, we created a distribution file for our library, which was not minified. As it is good practice to also distribute a minified version of your library, we&rsquo;ll create a task for this. For that, we&rsquo;ll use the <a href="https://www.npmjs.com/package/gulp-uglify">gulp-uglify</a> plugin:</p>
<pre tabindex="0"><code>npm install gulp-uglify --save-dev
</code></pre><p>Applying minification is just a matter of piping our library file to <code>plugins.uglify()</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;dist-minified&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">gulp</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="s2">&#34;./index.js&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">uglify</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">rename</span><span class="p">(</span><span class="s2">&#34;knockout-paging.min.js&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s2">&#34;./dist&#34;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now when we run <code>gulp dist-minified</code>, a minified version of the <code>index.js</code> file is written to <code>dist/knockout-paging.min.js</code>. Note that the <code>index.js</code> file itself is <em>not</em> modified.</p>
<p>With Gulp, you can chain commands. This allows us to combine the previous two tasks into a single task:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s1">&#39;dist-combined&#39;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">gulp</span><span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="s1">&#39;./index.js&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">rename</span><span class="p">(</span><span class="s1">&#39;knockout-paging.js&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s1">&#39;./dist&#39;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">uglify</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">rename</span><span class="p">(</span><span class="s1">&#39;knockout-paging.min.js&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s1">&#39;./dist&#39;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Running <code>gulp dist-combined</code> will create both the unmodified <code>dist/knockout-paging.js</code> and minified <code>dist/knockout-paging.min.js</code> files, once again not modifying the <code>index.js</code> file.</p>
<h3 id="setting-the-version-number">Setting the version number</h3>
<p>When we distribute our library, the distribution file&rsquo;s header should contain its version number. We could manually add it to our distribution file each time we release a new version, but let&rsquo;s automate it.</p>
<p>First, we install the <a href="https://www.npmjs.com/package/gulp-replace">gulp-replace</a> package:</p>
<pre tabindex="0"><code>npm install gulp-replace --save-dev
</code></pre><p>Then we add a placeholder for the version number in our <code>index.js</code> file&rsquo;s header:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/*!
</span></span></span><span class="line"><span class="cl"><span class="cm">  Knockout paged extender {{ &#34;{{ version &#34; }}}}
</span></span></span><span class="line"><span class="cl"><span class="cm">  License: Apache 2
</span></span></span><span class="line"><span class="cl"><span class="cm">*/</span>
</span></span></code></pre></div><p>To automatically replace the <code>&quot;{{ &quot;{{ version &quot; }}}}&quot;</code> placeholder with the current version number, we retrieve the version number specified in our <code>package.json</code> file and use the <code>replace</code> plugin we just installed to do the replacing:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;dist-version&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pkg</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;./package.json&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">gulp</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="s2">&#34;./index.js&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="s1">&#39;{{ &#34;{{ version &#34; }}}}&#39;</span><span class="p">,</span> <span class="nx">pkg</span><span class="p">.</span><span class="nx">version</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">rename</span><span class="p">(</span><span class="s2">&#34;knockout-paging.js&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s2">&#34;./dist&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">uglify</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">rename</span><span class="p">(</span><span class="s2">&#34;knockout-paging.min.js&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s2">&#34;./dist&#34;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now suppose that our <code>package.json</code> looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;name&#34;</span><span class="o">:</span> <span class="s2">&#34;knockout-paging&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;version&#34;</span><span class="o">:</span> <span class="s2">&#34;0.2.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we run <code>gulp dist-version</code>, the <code>dist/knockout-paging.js</code> file&rsquo;s header will contain the current version number:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/*!
</span></span></span><span class="line"><span class="cl"><span class="cm">  Knockout paged extender 0.2.1
</span></span></span><span class="line"><span class="cl"><span class="cm">  License: Apache 2
</span></span></span><span class="line"><span class="cl"><span class="cm">*/</span>
</span></span></code></pre></div><p>Note that the minified file does not contain the header, as the minification process removes comments.</p>
<h3 id="incrementing-version-numbers">Incrementing version numbers</h3>
<p>With more and more libraries using <a href="http://semver.org/">semantic version</a> (semver), managing the current version number of your library is an important task. In semver, a version number is comprised of three parts: <code>&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;</code>. When you want to do a new release, semver defines which part of the version number to increment:</p>
<ul>
<li>Major: incompatible API changes.</li>
<li>Minor: functionality added in a backwards-compatible manner.</li>
<li>Patch: bug fixes (also backwards-compatible).</li>
</ul>
<p>Using <code>1.2.5</code> as our current version number, here&rsquo;s how the version number should be modified for each change type:</p>
<ul>
<li>Major: <code>2.0.0</code></li>
<li>Minor: <code>1.3.0</code></li>
<li>Patch: <code>1.2.6</code></li>
</ul>
<p>The main benefit of semver is that version numbers now have meaning. For example, if only the patch part of a version number has changed, you should be able to update safely.</p>
<p>We can automate these version number changes using <a href="https://www.npmjs.com/package/gulp-bump">gulp-bump</a>:</p>
<pre tabindex="0"><code>npm install gulp-bump --save-dev
</code></pre><p>We then define three tasks, for each of the three semver change types:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">updateVersion</span><span class="p">(</span><span class="nx">importance</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">gulp</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="s2">&#34;./package.json&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">bump</span><span class="p">({</span> <span class="nx">type</span><span class="o">:</span> <span class="nx">importance</span> <span class="p">}))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s2">&#34;./&#34;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;patch-release&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">updateVersion</span><span class="p">(</span><span class="s2">&#34;patch&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;minor-release&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">updateVersion</span><span class="p">(</span><span class="s2">&#34;minor&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s2">&#34;major-release&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">updateVersion</span><span class="p">(</span><span class="s2">&#34;major&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now if we run <code>gulp major-release</code>, the version number in our <code>package.json</code> file will be updated according to the rules defined for major changes.</p>
<h4 id="updating-in-multiple-files">Updating in multiple files</h4>
<p>Our previous example only modified the <code>package.json</code> file, but you can also update multiple files by passing an array of filenames:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">updateVersion</span><span class="p">(</span><span class="nx">importance</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">gulp</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">src</span><span class="p">([</span><span class="s2">&#34;./package.json&#34;</span><span class="p">,</span> <span class="s2">&#34;./bower.json&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">bump</span><span class="p">({</span> <span class="nx">type</span><span class="o">:</span> <span class="nx">importance</span> <span class="p">}))</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="s2">&#34;./&#34;</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This modified task updates the version in both the <code>package.json</code> and <code>bower.json</code> files.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Usually, maintaining a library means doing repetitive tasks, like minifying files or running tests. For our library, we automated these tasks using Gulp. Defining these tasks was easy, as we could just use already available tasks. Automating our tasks not only saved us time, but also prevented us from making mistakes.</p>
<p>In the <a href="https://www.erikschierboom.com/2015/08/22/building-a-javascript-library-part-3-open-sourcing/">next post</a>, we&rsquo;ll look at how we open-source our code.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library</title>
			<link>https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/</link>
			<pubDate>Wed, 05 Aug 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/</guid>
			<description>In the Building a Knockout paging plugin post, we developed a Knockout paging plugin using JavaScript. However, writing the software itself was just one step in building the library.
In a series of seven blog posts, we will look at all the other steps we took when developing our JavaScript library. These include automating tasks, open-sourcing our code, adding package manager support, using a build server to automatically build (and test) our software, supporting TypeScript and adding our library to a CDN.</description>
			<content type="html"><![CDATA[<p>In the <a href="https://www.erikschierboom.com/2015/06/10/building-a-knockout-paging-plugin/">Building a Knockout paging plugin</a> post, we developed a Knockout paging plugin using JavaScript. However, writing the software itself was just one step in building the library.</p>
<p>In a series of seven blog posts, we will look at all the other steps we took when developing our JavaScript library. These include automating tasks, open-sourcing our code, adding package manager support, using a build server to automatically build (and test) our software, supporting TypeScript and adding our library to a CDN.</p>
<ul>
<li><a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library-part-1-testing/">Part 1: testing</a></li>
<li><a href="https://www.erikschierboom.com/2015/08/12/building-a-javascript-library-part-2-automation/">Part 2: automation</a></li>
<li><a href="https://www.erikschierboom.com/2015/08/22/building-a-javascript-library-part-3-open-sourcing/">Part 3: open-sourcing</a></li>
<li><a href="https://www.erikschierboom.com/2015/10/05/building-a-javascript-library-part-4-package-managers/">Part 4: package-managers</a></li>
<li><a href="https://www.erikschierboom.com/2015/10/26/building-a-javascript-library-part-5-build-server/">Part 5: build server</a></li>
<li><a href="https://www.erikschierboom.com/2015/11/04/building-a-javascript-library-part-6-typescript/">Part 6: TypeScript</a></li>
<li><a href="https://www.erikschierboom.com/2015/11/07/building-a-javascript-library-part-7-cdn/">Part 7 CDN</a></li>
</ul>
]]></content>
		</item>
		
		<item>
			<title>Building a JavaScript library - part 1: testing</title>
			<link>https://www.erikschierboom.com/2015/08/05/building-a-javascript-library-part-1-testing/</link>
			<pubDate>Wed, 05 Aug 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/08/05/building-a-javascript-library-part-1-testing/</guid>
			<description>In the Building a Knockout paging plugin post, we developed a Knockout paging plugin. This is the first in a series of posts that discuss the steps taken to publish our library. In this post, we&amp;rsquo;ll look at testing our library.
Why testing? Before we dive into testing, let&amp;rsquo;s consider why we write tests at all. Tim King did a great job on listing twelve benefits of writing tests:
Unit tests prove that your code actually works.</description>
			<content type="html"><![CDATA[<p>In the <a href="https://www.erikschierboom.com/2015/06/10/building-a-knockout-paging-plugin/">Building a Knockout paging plugin</a> post, we developed a Knockout paging plugin. This is the first in a <a href="https://www.erikschierboom.com/2015/08/05/building-a-javascript-library/">series of posts</a> that discuss the steps taken to publish our library. In this post, we&rsquo;ll look at testing our library.</p>
<h2 id="why-testing">Why testing?</h2>
<p>Before we dive into testing, let&rsquo;s consider why we write tests at all. Tim King did a great job on listing <a href="http://sd.jtimothyking.com/2006/07/11/twelve-benefits-of-writing-unit-tests-first/">twelve benefits of writing tests</a>:</p>
<ol>
<li>Unit tests prove that your code actually works.</li>
<li>You get a low-level regression-test suite.</li>
<li>You can improve the design without breaking it.</li>
<li>It&rsquo;s more fun to code with them than without.</li>
<li>They demonstrate concrete progress.</li>
<li>Unit tests are a form of sample code.</li>
<li>It forces you to plan before you code.</li>
<li>It reduces the cost of bugs.</li>
<li>It&rsquo;s even better than code inspections.</li>
<li>It virtually eliminates coder&rsquo;s block.</li>
<li>Unit tests make better designs.</li>
<li>It&rsquo;s faster than writing code without tests.</li>
</ol>
<p>There is even <a href="http://link.springer.com/article/10.1007/s10664-006-5964-9">scientific</a> <a href="http://link.springer.com/article/10.1007%2Fs10664-008-9062-z">data</a> that shows the value of writing tests. For our library, we&rsquo;ll write tests to ensure our software works as intended and to prevent new releases from breaking existing features.</p>
<h2 id="test-framework">Test framework</h2>
<p>Before we can start writing tests, we need to choose a test framework. The three most popular JavaScript test frameworks are probably:</p>
<ul>
<li><a href="http://jasmine.github.io/">Jasmine</a></li>
<li><a href="http://mochajs.org/">Mocha</a></li>
<li><a href="https://qunitjs.com/">QUnit</a></li>
</ul>
<p>We prefer Mocha, for its ease of use and great asynchronous testing support. One thing to note about Mocha is that you need to plug in an assertion library. Once again, there are many options, but we chose <a href="http://chaijs.com/">chai</a> for its flexibility. Another strong point of both Mocha and Chai is that they have great documentation.</p>
<p>Having chosen our test framework and assertion library, we install them using <a href="https://docs.npmjs.com/">NPM</a>:</p>
<pre tabindex="0"><code>npm install mocha --save-dev
npm install chai --save-dev
</code></pre><h2 id="choosing-a-test-format">Choosing a test format</h2>
<p>Before we&rsquo;ll start to write our tests, we have to decide in what format to write our tests. Mocha supports various formats, but most people use either the <a href="http://mochajs.org/#tdd">TDD</a> or <a href="http://mochajs.org/#bdd">BDD</a> style. When done properly, BDD tests describe <em>how</em> your system should behave, like a requirements document. Furthermore, BDD tests are written in a format such that non-programmers should also be able to understand them. For these reasons, we choose to write our tests in BDD style.</p>
<h2 id="writing-tests">Writing tests</h2>
<p>Having chosen our test format, we can start writing our tests. As BDD tests form a type of specification, we name the file that will contain our tests <code>spec.js</code>. In that file, we first specify the test format (BDD) and create a shortcut for Chai&rsquo;s <code>expect</code> function. The latter is done to improve the readability of our tests.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">mocha</span><span class="p">.</span><span class="nx">setup</span><span class="p">(</span><span class="s2">&#34;bdd&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">expect</span> <span class="o">=</span> <span class="nx">chai</span><span class="p">.</span><span class="nx">expect</span><span class="p">;</span>
</span></span></code></pre></div><p>Now we&rsquo;ll write our first test using the <code>describe()</code> and <code>it()</code> functions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">describe</span><span class="p">(</span><span class="s2">&#34;paged extender&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;pageCount on empty paged observable array is 1&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">var</span> <span class="nx">emptyPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nx">expect</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The <code>describe()</code> function is used to group related tests, the <code>it()</code> function contains the actual test. As you can see, we use a verbose test name, as BDD prescribes. Don&rsquo;t be hesitant to use verbose test names, they will make your test results much easier to read.</p>
<p>The line in which we test if <code>pageCount()</code> returns the correct value, almost reads like a sentence. Once again, this is typical for the BDD style.</p>
<h2 id="running-tests">Running tests</h2>
<p>Mocha tests run in an HTML file, known as a test runner. Hence, we create a <code>runner.html</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">&#34;en&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">&#34;utf-8&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Knockout paged spec<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;node_modules/mocha/mocha.css&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- 1. Placeholder node that will contain the test results --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;mocha&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- 2. Library dependencies --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;node_modules/knockout/build/output/knockout-latest.debug.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- 3. Library --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;index.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- 4. Test libraries --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;node_modules/chai/chai.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;node_modules/mocha/mocha.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- 5. Tests --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;spec.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- 6. Run tests --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/javascript&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nx">mocha</span><span class="p">.</span><span class="nx">run</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The test runner is comprised of the following parts:</p>
<ol>
<li>The <code>&lt;div&gt;</code> HTML element to which Mocha will write the test results.</li>
<li>Script include of our library&rsquo;s only dependency: Knockout.</li>
<li>Script include of the library itself.</li>
<li>Script includes of the Mocha and Chai test libraries.</li>
<li>Script include of the specification file containing the tests.</li>
<li>JavaScript code to get Mocha to run our tests.</li>
</ol>
<p>If we open this test runner file in a browser, you&rsquo;ll see something like this:</p>
<p><img src="/images/posts/publishing-library-part-1-testing/mocha-test-runner.png" alt="Mocha test runner"></p>
<p>As you can see, Mocha has run one test, which passed. Note that Mocha used the <code>describe()</code> function to group tests.</p>
<h2 id="structuring-tests">Structuring tests</h2>
<p>Once you add more tests, how you structure your tests becomes important. Two simple options to structure your tests are:</p>
<ul>
<li>Put related tests in separate files.</li>
<li>Put related tests in a (nested) <code>describe()</code> block.</li>
</ul>
<p>As we have a relative small amount of tests, we&rsquo;ll use the <code>describe()</code> option:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">describe</span><span class="p">(</span><span class="s2">&#34;paged extender&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">describe</span><span class="p">(</span><span class="s2">&#34;on empty paged observable array&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;itemCount is 0&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kd">var</span> <span class="nx">emptyPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="nx">expect</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">describe</span><span class="p">(</span><span class="s2">&#34;on single-item paged observable array&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;itemCount is equal to 1&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kd">var</span> <span class="nx">singleItemPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([</span><span class="s2">&#34;a&#34;</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">      <span class="nx">expect</span><span class="p">(</span><span class="nx">singleItemPagedArray</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The output now looks like this:</p>
<p><img src="/images/posts/publishing-library-part-1-testing/mocha-test-runner-grouped.png" alt="Mocha test runner - grouped tests"></p>
<p>You can clearly see how the nesting also influences the output. Note that we modified the test names to better combine with the nested context&rsquo;s description.</p>
<p>As nested <code>describe()</code> calls can become a bit confusing, Mocha also supports the <code>context()</code> function to group tests:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">describe</span><span class="p">(</span><span class="s2">&#34;paged extender&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">context</span><span class="p">(</span><span class="s2">&#34;on empty paged observable array&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;itemCount is 0&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kd">var</span> <span class="nx">emptyPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">      <span class="nx">expect</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">context</span><span class="p">(</span><span class="s2">&#34;on single-item paged observable array&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;itemCount is equal to 1&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kd">var</span> <span class="nx">singleItemPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([</span><span class="s2">&#34;a&#34;</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">      <span class="nx">expect</span><span class="p">(</span><span class="nx">singleItemPagedArray</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">()).</span><span class="nx">to</span><span class="p">.</span><span class="nx">equal</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The output of this code is exactly the same as the previous example, which makes sense as <code>context()</code> is just an alias for <code>describe()</code>.</p>
<h3 id="context-dependent-test-setup">Context-dependent test setup</h3>
<p>When tests are grouped, they are usually related to each other. Normally, this implies that they share at least part of their test setup code. As an example, consider the following tests, which all test a property of an empty paged array:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">context</span><span class="p">(</span><span class="s2">&#34;on empty paged array&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;itemCount is 0&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">var</span> <span class="nx">emptyPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([]);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assert</span><span class="p">.</span><span class="nx">strictEqual</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">(),</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;pageCount is 1&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">var</span> <span class="nx">emptyPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([]);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assert</span><span class="p">.</span><span class="nx">strictEqual</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">(),</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;hasPreviousPage is false&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">var</span> <span class="nx">emptyPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([]);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assert</span><span class="p">.</span><span class="nx">isFalse</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">hasPreviousPage</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Each test contains the exact same line to setup the empty paged array. To share this common setup code, we can move it into a <code>beforeEach()</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">context</span><span class="p">(</span><span class="s2">&#34;on empty paged array&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">emptyPagedArray</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">beforeEach</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">emptyPagedArray</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pagedObservableArray</span><span class="p">([]);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;itemCount is 0&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assert</span><span class="p">.</span><span class="nx">strictEqual</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">(),</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;pageCount is 1&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assert</span><span class="p">.</span><span class="nx">strictEqual</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">(),</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s2">&#34;hasPreviousPage is false&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assert</span><span class="p">.</span><span class="nx">isFalse</span><span class="p">(</span><span class="nx">emptyPagedArray</span><span class="p">.</span><span class="nx">hasPreviousPage</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>What happens is that just before Mocha runs a test, it checks for a <code>beforeEach()</code> function in the <code>context()</code> or <code>describe()</code> call the test is defined in. If a <code>beforeEach()</code> function is found, Mocha calls it just before running the test.</p>
<h2 id="conclusion">Conclusion</h2>
<p>To test our library, we wrote our tests using Mocha and Chai, which were both easy to use and well documented. Our tests were written in BDD style, which we feel makes them easier to read and can help people understand how the library should work.</p>
<p>Although hard to quantify, we feel the tests helped us reduce the number of bugs in our code. Furthermore, they protected us from breaking things when we released new versions of the library.</p>
<p>In the <a href="https://www.erikschierboom.com/2015/08/12/building-a-javascript-library-part-2-automation/">next post</a>, we&rsquo;ll look at how we automated repetitive tasks.</p>
]]></content>
		</item>
		
		<item>
			<title>Building a Knockout paging plugin</title>
			<link>https://www.erikschierboom.com/2015/06/10/building-a-knockout-paging-plugin/</link>
			<pubDate>Wed, 10 Jun 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/06/10/building-a-knockout-paging-plugin/</guid>
			<description>If you want to add paging to a Knockout application, you&amp;rsquo;ll find this is not supported out-of-the-box. This blog post describes how we created a library to add paging support to Knockout.
Creating the plugin As our goal is to add paging functionality to Knockout observable arrays, we&amp;rsquo;ll write an extender.
An extender is a function defined in the ko.extenders object that takes the observable to extend as its first parameter and an options parameter as its second.</description>
			<content type="html"><![CDATA[<p>If you want to add paging to a <a href="http://knockoutjs.com/">Knockout</a> application, you&rsquo;ll find this is not supported out-of-the-box. This blog post describes how we created a <a href="https://github.com/ErikSchierboom/knockout-paging">library</a> to add paging support to Knockout.</p>
<h2 id="creating-the-plugin">Creating the plugin</h2>
<p>As our goal is to add paging functionality to Knockout observable arrays, we&rsquo;ll write an <a href="http://knockoutjs.com/documentation/extenders.html">extender</a>.</p>
<p>An extender is a function defined in the <code>ko.extenders</code> object that takes the observable to extend as its first parameter and an options parameter as its second. Our basic <code>paged</code> extender looks as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">ko</span><span class="p">.</span><span class="nx">extenders</span><span class="p">.</span><span class="nx">paged</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">target</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">target</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>Note that our extender returns the observable passed in as the first parameter, as our goal is to add features to an existing observable, not create a new one.</p>
<p>Applying our custom extender to an observable array is easy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">().</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{}</span> <span class="p">});</span>
</span></span></code></pre></div><p>Note that for the moment, we&rsquo;ll just pass an empty object as the options parameter.</p>
<h3 id="adding-observables">Adding observables</h3>
<p>Our second step is to add observables for the current page number and page size to the observable being extended:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">ko</span><span class="p">.</span><span class="nx">extenders</span><span class="p">.</span><span class="nx">paged</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">target</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// Add new observables to the existing observable
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">target</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>We can now do this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">().</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">();</span> <span class="c1">// Returns 1
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span> <span class="c1">// Set the page number to 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">();</span> <span class="c1">// Returns 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">();</span> <span class="c1">// Returns 10
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span> <span class="c1">// Set the page size to 5
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">();</span> <span class="c1">// Returns 5
</span></span></span></code></pre></div><h4 id="options">Options</h4>
<p>In the previous example, we saw that the <code>pageNumber</code> and <code>pageSize</code> observables were assigned default values. To allow users to customize these default values, we&rsquo;ll use the options parameter.</p>
<p>To support this, we modify our observables as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">((</span><span class="nx">options</span> <span class="o">&amp;&amp;</span> <span class="nx">options</span><span class="p">[</span><span class="s2">&#34;pageNumber&#34;</span><span class="p">])</span> <span class="o">||</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">((</span><span class="nx">options</span> <span class="o">&amp;&amp;</span> <span class="nx">options</span><span class="p">[</span><span class="s2">&#34;pageSize&#34;</span><span class="p">])</span> <span class="o">||</span> <span class="mi">10</span><span class="p">);</span>
</span></span></code></pre></div><p>Now we can initialize these observables using the options parameter:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">observableArray</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageNumber</span><span class="o">:</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">5</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">();</span> <span class="c1">// Returns 2
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">();</span> <span class="c1">// Returns 5
</span></span></span></code></pre></div><p>If you don&rsquo;t specify any options, the observables are set to their default values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">().</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">();</span> <span class="c1">// Returns 1
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">();</span> <span class="c1">// Returns 10
</span></span></span></code></pre></div><h3 id="computed-values">Computed values</h3>
<p>The second phase in creating our <code>paged</code> extender is to add a property that returns the total number of pages. To be able to calculate this value, we need to know two things:</p>
<ul>
<li>The number of items in the array.</li>
<li>The current page size.</li>
</ul>
<p>The number of items can be retrieved through the <code>length</code> property of the underlying array:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">().</span><span class="nx">length</span><span class="p">;</span>
</span></span></code></pre></div><p>The current page size is stored in the <code>pageSize</code> observable we added earlier.</p>
<p>A naive implementation of the <code>pageCount</code> property looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="nb">Math</span><span class="p">.</span><span class="nx">ceil</span><span class="p">(</span><span class="nx">target</span><span class="p">().</span><span class="nx">length</span> <span class="o">/</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="p">);</span>
</span></span></code></pre></div><p>If we ignore the possibility of <code>pageSize()</code> returning zero, we would indeed get the correct page count. However, there is a problem with this implementation. Suppose we have the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">observableArray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="c1">// Returns 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// Now change the page size which should cause the page count to change
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="c1">// Returns ??
</span></span></span></code></pre></div><p>Can you guess what value the second <code>pageCount()</code> call returns? Contrary to what you might expect, the returned value is still <code>3</code>. The reason for this is that an observable does not dynamically respond to changes in other observables. For that, Knockout has the concept of <a href="http://knockoutjs.com/documentation/computedObservables.html">computed observables</a>.</p>
<p>Let&rsquo;s convert the <code>pageCount</code> property to a computed observable:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pureComputed</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">ceil</span><span class="p">(</span><span class="nx">target</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">()</span> <span class="o">/</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now, due to the dependency tracking of computed observables, the code works as expected:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">observableArray</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="c1">// Returns 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// Now change the page size
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="c1">// Returns 2
</span></span></span></code></pre></div><p>The following <em>read-only</em> computed values were also added:</p>
<ul>
<li><code>pageItems</code>: the array items on the current page.</li>
<li><code>pageCount</code>: the total number of pages.</li>
<li><code>itemCount</code>: the total number of items in the array.</li>
<li><code>firstItemOnPage</code>: the index (one-based) of the first item on the current page.</li>
<li><code>lastItemOnPage</code>: the index (one-based) of the last item on the current page.</li>
<li><code>hasPreviousPage</code>: indicates if there is a previous page.</li>
<li><code>hasNextPage</code>: indicates if there is a next page.</li>
<li><code>isFirstPage</code>: indicates if the current page is the first page.</li>
<li><code>isLastPage</code>: indicates if the current page is the last page.</li>
<li><code>pages</code>: an array of pages.</li>
</ul>
<p>The following example shows how these values can be used:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">11</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">();</span> <span class="c1">// Returns 1
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageSize</span><span class="p">();</span> <span class="c1">// Returns 2
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageItems</span><span class="p">();</span> <span class="c1">// Returns [2, 3]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="c1">// Returns 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">itemCount</span><span class="p">();</span> <span class="c1">// Returns 5
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">firstItemOnPage</span><span class="p">();</span> <span class="c1">// Returns 1
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">lastItemOnPage</span><span class="p">();</span> <span class="c1">// Returns 2
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">hasPreviousPage</span><span class="p">();</span> <span class="c1">// Returns false
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">hasNextPage</span><span class="p">();</span> <span class="c1">// Returns true
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">isFirstPage</span><span class="p">();</span> <span class="c1">// Returns true
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">isLastPage</span><span class="p">();</span> <span class="c1">// Returns false
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">pages</span><span class="p">();</span> <span class="c1">// Returns [1, 2, 3]
</span></span></span></code></pre></div><h3 id="functions">Functions</h3>
<p>To make navigating easier, we add the following functions:</p>
<ul>
<li><code>toNextPage</code>: move to the next page (if there is one).</li>
<li><code>toPreviousPage</code>: move to the previous page (if there is one).</li>
<li><code>toFirstPage</code>: move to the first page.</li>
<li><code>toLastPage</code>: move to the last page.</li>
</ul>
<p>Their implementation is straightforward; this is the implementation of the <code>toNextPage</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">toNextPage</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="nx">target</span><span class="p">.</span><span class="nx">hasNextPage</span><span class="p">())</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">(</span><span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">()</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>This example shows how to use these functions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">target</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">11</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">});</span> <span class="c1">// page number is 1
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">toNextPage</span><span class="p">();</span> <span class="c1">// page number becomes 2
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">toLastPage</span><span class="p">();</span> <span class="c1">// page number becomes 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">toNextPage</span><span class="p">();</span> <span class="c1">// page number remains 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">toPreviousPage</span><span class="p">();</span> <span class="c1">// page number becomes 2
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">target</span><span class="p">.</span><span class="nx">toFirstPage</span><span class="p">();</span> <span class="c1">// page number becomes 1
</span></span></span></code></pre></div><h3 id="page-generators">Page generators</h3>
<p>As we saw earlier, the <code>pages</code> computed observable returns an array of page numbers. The most simple implementation justs return all pages:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pages</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pureComputed</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pageNumbers</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">pageNumbers</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">pageNumbers</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Note that we define it as a computed value, as it depends on the <code>pageCount</code> observable.</p>
<p>Although this implementation is fine for a small number of pages, it becomes unwieldy when there are many pages. In that case, a sliding window of pages, containing the current page and some pages surrounding it, is a better option:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pages</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pureComputed</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">windowSize</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">leftBasedStartIndex</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">()</span> <span class="o">-</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nx">windowSize</span> <span class="o">/</span> <span class="mi">2</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">rightBasedStartIndex</span> <span class="o">=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">()</span> <span class="o">-</span> <span class="nx">windowSize</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">startIndex</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">leftBasedStartIndex</span><span class="p">,</span> <span class="nx">rightBasedStartIndex</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">stopIndex</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">(),</span> <span class="nx">startIndex</span> <span class="o">+</span> <span class="nx">windowSize</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pageNumbers</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="nx">startIndex</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">stopIndex</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">pageNumbers</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">pageNumbers</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The following example show how the sliding window works:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">input</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">4</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">6</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">7</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">8</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">9</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">10</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">11</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">12</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">13</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">15</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">16</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">17</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">18</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">19</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">20</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">sliding</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">(</span><span class="nx">input</span><span class="p">).</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Return the pages around the current page (1)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">sliding</span><span class="p">.</span><span class="nx">pages</span><span class="p">();</span> <span class="c1">// Returns [1, 2, 3, 4, 5]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// Changing the page number changes the returned pages
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">sliding</span><span class="p">.</span><span class="nx">pageNumber</span><span class="p">(</span><span class="mi">7</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Return the pages around the current page (7)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">sliding</span><span class="p">.</span><span class="nx">pages</span><span class="p">();</span> <span class="c1">// Returns [5, 6, 7, 8, 9]
</span></span></span></code></pre></div><h3 id="custom-page-generators">Custom page generators</h3>
<p>But what if someone wants to supply their own page generator? Ideally, you should be able to just <em>plugin</em> your own page generator (relevant: <a href="http://en.wikipedia.org/wiki/Open/closed_principle">open/closed principle</a>). The first step towards realizing this is defining what the signature of a page generator is. Let&rsquo;s define it as a function that takes a paged observable and returns an array of pages.</p>
<p>We can rewrite our simple page generator to conform to this definition:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">simplePageGenerator</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">pagedObservable</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pageNumbers</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">pageNumbers</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">pageNumbers</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span></code></pre></div><p>The next step is to modify our extender to be able to plugin a page generator. There are lots of ways to do this. Taking a cue from how extenders are defined in the <code>ko.extenders</code> object, we&rsquo;ll define page generators in the <code>ko.paging.generators</code> object:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">ko</span><span class="p">.</span><span class="nx">paging</span><span class="p">.</span><span class="nx">generators</span><span class="p">[</span><span class="s2">&#34;simple&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">pagedObservable</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">pageNumbers</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;=</span> <span class="nx">pagedObservable</span><span class="p">.</span><span class="nx">pageCount</span><span class="p">();</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">pageNumbers</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">pageNumbers</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// We omit the &#39;sliding&#39; page generator for brevity
</span></span></span></code></pre></div><p>We then modify our paged extender to allow the page generator to be specified in the options value:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">pageGeneratorName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">options</span> <span class="o">&amp;&amp;</span> <span class="nx">options</span><span class="p">[</span><span class="s2">&#34;pageGenerator&#34;</span><span class="p">])</span> <span class="o">||</span> <span class="s2">&#34;simple&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pageGenerator</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">paging</span><span class="p">.</span><span class="nx">generators</span><span class="p">[</span><span class="nx">pageGeneratorName</span><span class="p">];</span>
</span></span></code></pre></div><p>The final step is to have the <code>pages</code> computed value forward calls to the current page generator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pages</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pureComputed</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageGenerator</span><span class="p">(</span><span class="nx">target</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>We are now ready to plugin a custom page generator. First we add it to the <code>ko.paging.generators</code> object:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">ko</span><span class="p">.</span><span class="nx">paging</span><span class="p">.</span><span class="nx">generators</span><span class="p">[</span><span class="s2">&#34;custom&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">pagedObservable</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">[</span><span class="mi">42</span><span class="p">];</span> <span class="c1">// Always return page number 42
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span>
</span></span></code></pre></div><p>We can then use it as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">custom</span> <span class="o">=</span> <span class="nx">ko</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">observableArray</span><span class="p">([])</span>
</span></span><span class="line"><span class="cl">  <span class="p">.</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageGenerator</span><span class="o">:</span> <span class="s2">&#34;custom&#34;</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">custom</span><span class="p">.</span><span class="nx">pages</span><span class="p">();</span> <span class="c1">// Returns [42]
</span></span></span></code></pre></div><h4 id="customizing-page-generators">Customizing page generators</h4>
<p>The observant among you might have noticed a problem with the sliding window page generator: the window size could not be changed. This is due to how we defined page generators: as a simple function. To allow customization of page generators, we re-define a page generator as an object with a <code>generate</code> function that takes a paged observable and returns an array of pages.</p>
<p>Rewriting the sliding page generator to the new format is easy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">ko</span><span class="p">.</span><span class="nx">paging</span><span class="p">.</span><span class="nx">generators</span><span class="p">[</span><span class="s1">&#39;sliding&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">windowSize</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">generate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">pagedObservable</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">     <span class="c1">// Same implementation as before
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The next step is to modify our <code>pages</code> computed value to call the <code>generate</code> function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="nx">target</span><span class="p">.</span><span class="nx">pages</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">pureComputed</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">target</span><span class="p">.</span><span class="nx">pageGenerator</span><span class="p">.</span><span class="nx">generate</span><span class="p">(</span><span class="nx">target</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now we are able to change the window size:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">input</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">4</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">6</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">7</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">8</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">9</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">10</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">11</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">12</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">13</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">14</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">15</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">16</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">17</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">18</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">19</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="mi">20</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">var</span> <span class="nx">sliding</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">(</span><span class="nx">input</span><span class="p">).</span><span class="nx">extend</span><span class="p">({</span> <span class="nx">paged</span><span class="o">:</span> <span class="p">{</span> <span class="nx">pageSize</span><span class="o">:</span> <span class="mi">2</span> <span class="p">}</span> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Window size is 5 (default)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">sliding</span><span class="p">.</span><span class="nx">pages</span><span class="p">();</span> <span class="c1">// Returns [1, 2, 3, 4, 5]
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// Change the window size
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">ko</span><span class="p">.</span><span class="nx">paging</span><span class="p">.</span><span class="nx">generators</span><span class="p">[</span><span class="s2">&#34;sliding&#34;</span><span class="p">].</span><span class="nx">windowSize</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Window size is 3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">sliding</span><span class="p">.</span><span class="nx">pages</span><span class="p">();</span> <span class="c1">// Returns [1, 2, 3]
</span></span></span></code></pre></div><h2 id="installation">Installation</h2>
<p>The best way to install this library is using <a href="http://bower.io/">Bower</a>:</p>
<pre><code>bower install knockout-paging
</code></pre>
<p>You can also install the library using NPM:</p>
<pre><code>npm install knockout-paging --save-dev
</code></pre>
<p>The library is also available from a <a href="https://cdnjs.com/libraries/knockout-paging">CDN</a>.</p>
<h2 id="demo">Demo</h2>
<p>There is also a <a href="http://output.jsbin.com/liruyo/">JS Bin demo</a> that shows how the library can be used.</p>
<h2 id="conclusion">Conclusion</h2>
<p>If you want to do paging in Knockout, the <a href="https://github.com/ErikSchierboom/knockout-paging"><code>paged</code></a> extender can help you. Building the extender was not very hard, due to the easy, well-documented way in which Knockout can be extended.</p>
]]></content>
		</item>
		
		<item>
			<title>Using Knockout with existing HTML content</title>
			<link>https://www.erikschierboom.com/2015/04/25/knockout-pre-rendered/</link>
			<pubDate>Sat, 25 Apr 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/04/25/knockout-pre-rendered/</guid>
			<description>When creating an MVVM JavaScript application, Knockout is one of the most used libraries. One of its core principles is that all rendering is done client-side. One disadvantage is that this makes indexing the website harder. Another is that client-side rendering usually takes longer than server-side rendering.
The Knockout pre-rendered library adds two new binding handlers to Knockout that allow observables to be initialized from pre-rendered HTML content:
init: initialize an observable to a value retrieved from existing HTML content.</description>
			<content type="html"><![CDATA[<p>When creating an MVVM JavaScript application, <a href="http://knockoutjs.com/">Knockout</a> is one of the most used libraries. One of its core principles is that all rendering is done client-side. One disadvantage is that this makes <a href="https://developers.google.com/webmasters/ajax-crawling/docs/learn-more">indexing the website harder</a>. Another is that client-side rendering usually takes longer than server-side rendering.</p>
<p>The <a href="https://github.com/ErikSchierboom/knockout-pre-rendered">Knockout pre-rendered library</a> adds two new binding handlers to Knockout that allow observables to be initialized from pre-rendered HTML content:</p>
<ul>
<li><code>init</code>: initialize an observable to a value retrieved from existing HTML content.</li>
<li><code>foreachInit</code>: wraps the <a href="http://knockoutjs.com/documentation/foreach-binding.html"><code>foreach</code> binding</a>, with the observable array&rsquo;s elements bound to existing HTML elements.</li>
</ul>
<h2 id="init-binding">Init binding</h2>
<p>Suppose we have the following view model:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">ViewModel</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Normally, you&rsquo;d bind the <code>name</code> observable to an HTML element as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;text: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Once the binding has been applied however, the text within the <code>&lt;span&gt;</code> element will be cleared, as the bound observable did not have a value (existing HTML content is ignored).</p>
<p>We can fix this by specifying the <code>init</code> binding handler <em>before</em> the <code>text</code> binding handler:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Now, the text within the <code>&lt;span&gt;</code> element is left unchanged. This is due to the <code>init</code> binding handler setting the observable&rsquo;s value to the text content of the bound element. As Knockout binding handlers are executed left-to-right, when the <code>text</code> binding executes the <code>init</code> binding will already have initialized the observable.</p>
<p>You can combine the <code>init</code> handler with any binding, as long as you ensure that it is listed before the other bindings:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, textInput: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c">&lt;!-- This binding will use the &#34;value&#34; attribute to initialize the observable --&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">input</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, value: name&#34;</span> <span class="na">value</span><span class="o">=</span><span class="s">&#34;Larry Bird&#34;</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span> <span class="p">/&gt;</span>
</span></span></code></pre></div><h3 id="converting">Converting</h3>
<p>By default, the <code>init</code> binding will set the observable&rsquo;s value to a string. If you want to convert to a different type, you can specify a convert function:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init: { convert: parseInt }, text: height&#34;</span><span class="p">&gt;</span>198<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Now, the observable&rsquo;s value will be set to what the <code>convert</code> function, with the <code>innerText</code> value as its parameter, returns.</p>
<h4 id="custom-conversion">Custom conversion</h4>
<p>It is also possible to use your own, custom conversion function. You could, for example, define it in your view model:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">CustomConvertViewModel</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">dateOfBirth</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">parseDate</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">innerText</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">innerText</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>You can then use this custom convert function as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init: { convert: parseDate }, text: dateOfBirth&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><h3 id="virtual-elements">Virtual elements</h3>
<p>You can also use the <code>init</code> binding handler as a virtual element:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="c">&lt;!-- ko init: { field: name } --&gt;</span>Michael Jordan<span class="c">&lt;!-- /ko --&gt;</span>
</span></span></code></pre></div><p>Converting works the same as before:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="c">&lt;!-- ko init: { field: height, convert: parseInt } --&gt;</span>198<span class="c">&lt;!-- /ko --&gt;</span>
</span></span></code></pre></div><p>Note that we now need to explicitly specify the <code>field</code> parameter, which points to the observable to initialize. In our previous examples, the <code>init</code> binding was able to infer this due to it being combined with the <code>text</code>, <code>textInput</code> or <code>value</code> binding and using the observable they were pointing to. As a consequence, the following bindings are equivalent:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init: { field: name }, text: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Although you&rsquo;d probably not need it, you could have the <code>init</code> handler initialize a different observable than the one <code>text</code>, <code>textInput</code> or <code>value</code> binding uses:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">span</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init: { field: name }, text: year&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The result of this binding is that the <code>name</code> observable will have its value initialized to <code>&quot;Michael Jordan&quot;</code>, after which the element will be bound to the <code>year</code> observable.</p>
<h2 id="foreach-init-binding">Foreach init binding</h2>
<p>This binding handler wraps the <code>foreach</code> binding, but instead of creating new HTML elements, it binds to existing HTML elements. Consider the following view model:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">PersonViewModel</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observable</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">ForeachViewModel</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">persons</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">persons</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">PersonViewModel</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">persons</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">PersonViewModel</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">persons</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">PersonViewModel</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can bind the elements in the <code>persons</code> observable array to existing HTML elements by using the <code>foreachInit</code> binding handler:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ul</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;foreachInit: persons&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-template</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;text: name&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Larry Bird<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Magic Johnson<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>There are several things to note:</p>
<ol>
<li>There must be one child element with the <code>data-template</code> attribute. This element will be used as the template when new items are added to the array.</li>
<li>Elements to be bound to array items must have the <code>data-init</code> attribute.</li>
<li>You can use the <code>init</code> binding handler to initialize the array items themselves.</li>
</ol>
<h3 id="template">Template</h3>
<p>You can also use a template that is defined elsewhere on the page:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ul</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;foreachInit: { name: &#39;personTemplate&#39;, data: persons }&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Larry Bird<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Magic Johnson<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/ko-template&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;personTemplate&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="o">&lt;</span><span class="nx">li</span> <span class="nx">data</span><span class="o">-</span><span class="nx">template</span> <span class="nx">data</span><span class="o">-</span><span class="nx">bind</span><span class="o">=</span><span class="s2">&#34;text: name&#34;</span><span class="o">&gt;&lt;</span><span class="err">/li&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><h3 id="create-missing-array-elements">Create missing array elements</h3>
<p>Up until now, we assumed that the observable array already contained an item for each HTML element bound inside the <code>foreachInit</code> section. However, you can also have the <code>foreachInit</code> binding handler dynamically add an element for each bound element.</p>
<p>Take the following view model:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">ForeachDynamicViewModel</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">persons</span> <span class="o">=</span> <span class="nx">ko</span><span class="p">.</span><span class="nx">observableArray</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">this</span><span class="p">.</span><span class="nx">addPerson</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">persons</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">PersonViewModel</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Note that the <code>persons</code> observable array does not contain any elements, but that it does have a function to add a new element to the array.</p>
<p>We can use the <code>foreachInit</code> binding handler as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ul</span>
</span></span><span class="line"><span class="cl">  <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;foreachInit: { name: &#39;personTemplate&#39;, createElement: addPerson }&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-template</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;text: name&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Michael Jordan<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Larry Bird<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">li</span> <span class="na">data-init</span> <span class="na">data-bind</span><span class="o">=</span><span class="s">&#34;init, text: name&#34;</span><span class="p">&gt;</span>Magic Johnson<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>What happens is that for each element with the <code>data-init</code> attribute, the function specified in the <code>createElement</code> parameter is called.</p>
<h2 id="installation">Installation</h2>
<p>The best way to install this library is using <a href="http://bower.io/">Bower</a>:</p>
<pre><code>bower install knockout-pre-rendered
</code></pre>
<p>You can also install the library using NPM:</p>
<pre><code>npm install knockout-pre-rendered --save-dev
</code></pre>
<p>The library is also available from a <a href="https://cdnjs.com/libraries/knockout-pre-rendered">CDN</a>.</p>
<h2 id="demos">Demos</h2>
<p>Here are some JSBin demo&rsquo;s that show how to use the binding handlers:</p>
<ul>
<li><a href="http://jsbin.com/nocaro"><code>foreachInit</code> binding</a></li>
<li><a href="http://jsbin.com/jazeke"><code>init with text</code> binding</a></li>
<li><a href="http://jsbin.com/xuluye/"><code>init with value</code> binding</a></li>
<li><a href="http://jsbin.com/wikaji/"><code>init</code> binding</a></li>
</ul>
<h2 id="acknowledgements">Acknowledgements</h2>
<p>Many thanks go out to <a href="https://github.com/brianmhunt">Brian M Hunt</a>, which <a href="https://github.com/brianmhunt/knockout-fast-foreach"><code>fastForEach</code> binding handler</a> formed the basis of the <code>foreachInit</code> binding handler.</p>
<h2 id="conclusion">Conclusion</h2>
<p>For newly-developed Knockout applications, you probably don&rsquo;t need this library, unless you worry greatly about search engine indexation. However, if you have an existing application that already serves HTML, this library will allow you to integrate Knockout in an easy and non-disruptive way.</p>
]]></content>
		</item>
		
		<item>
			<title>Config files</title>
			<link>https://www.erikschierboom.com/2015/02/01/config-files/</link>
			<pubDate>Sun, 01 Feb 2015 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2015/02/01/config-files/</guid>
			<description>When developing .NET applications, the importance of Web.config and App.config files is evident. They are used for many configuration purposes, such as specifying connection strings and web server settings.
If you examine Web.config or App.config files, you&amp;rsquo;ll find they are XML files. This is an example of a basic config file:
&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;utf-8&amp;#34;?&amp;gt; &amp;lt;configuration&amp;gt; &amp;lt;connectionStrings&amp;gt; &amp;lt;add name=&amp;#34;Default&amp;#34; connectionString=&amp;#34;Server=myServer;Database=myDB;&amp;#34; /&amp;gt; &amp;lt;add name=&amp;#34;Backup&amp;#34; connectionString=&amp;#34;Server=myBackupServer;Database=myDB;&amp;#34; /&amp;gt; &amp;lt;/connectionStrings&amp;gt; &amp;lt;/configuration&amp;gt; The root element of a config file is the &amp;lt;configuration&amp;gt; element, which can have zero or more children.</description>
			<content type="html"><![CDATA[<p>When developing .NET applications, the importance of <code>Web.config</code> and <code>App.config</code> files is evident. They are used for many configuration purposes, such as specifying connection strings and web server settings.</p>
<p>If you examine <code>Web.config</code> or <code>App.config</code> files, you&rsquo;ll find they are XML files. This is an example of a basic config file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;connectionStrings&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;add</span> <span class="na">name=</span><span class="s">&#34;Default&#34;</span> <span class="na">connectionString=</span><span class="s">&#34;Server=myServer;Database=myDB;&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;add</span> <span class="na">name=</span><span class="s">&#34;Backup&#34;</span> <span class="na">connectionString=</span><span class="s">&#34;Server=myBackupServer;Database=myDB;&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/connectionStrings&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>The root element of a config file is the <code>&lt;configuration&gt;</code> element, which can have zero or more children. These child elements are known as <em>configuration sections</em>. Each config section in turn can also have zero or more child elements, which are known as <em>configuration elements</em>.</p>
<p>In our example, there is only one config section: <code>&lt;connectionStrings&gt;</code>. Its two <code>&lt;add&gt;</code> child config elements define the connection strings, using the <code>name</code> and <code>connectionString</code> attributes.</p>
<p>Retrieving the connection string in your application is easy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">def</span> <span class="p">=</span> <span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">ConnectionStrings</span><span class="p">[</span><span class="s">&#34;Default&#34;</span><span class="p">].</span><span class="n">ConnectionString</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">bak</span> <span class="p">=</span> <span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">ConnectionStrings</span><span class="p">[</span><span class="s">&#34;Backup&#34;</span><span class="p">].</span><span class="n">ConnectionString</span><span class="p">;</span>
</span></span></code></pre></div><p>The <code>ConnectionStrings</code> property of the <code>ConfigurationManager</code> class is a wrapper around the <code>&lt;connectionString&gt;</code> element in your config file. If you use the connection string&rsquo;s name in its indexer, you get back a strongly-typed class describing the connection string.</p>
<p>Note that to use the <code>ConfigurationManager</code> class, your application needs to reference the <code>System.Configuration</code> assembly.</p>
<h3 id="app-settings">App settings</h3>
<p>Another commonly used config section is <code>&lt;appSettings&gt;</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;appSettings&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;add</span> <span class="na">key=</span><span class="s">&#34;RequireLogin&#34;</span> <span class="na">value=</span><span class="s">&#34;True&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;add</span> <span class="na">key=</span><span class="s">&#34;Timeout&#34;</span> <span class="na">value=</span><span class="s">&#34;10&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/appSettings&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>The <code>&lt;appSettings&gt;</code> config section is used for application-specific configuration. You can think of it as a dictionary that maps <code>string</code> keys to <code>string</code> values.</p>
<p>Retrieval is easy using the key as an indexer:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">requireLogin</span> <span class="p">=</span> <span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">AppSettings</span><span class="p">[</span><span class="s">&#34;RequireLogin&#34;</span><span class="p">];</span>     <span class="c1">// Returns &#34;True&#34;</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">timeout</span>      <span class="p">=</span> <span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">AppSettings</span><span class="p">[</span><span class="s">&#34;Timeout&#34;</span><span class="p">];</span> <span class="c1">// Returns &#34;10&#34;</span>
</span></span></code></pre></div><p>As values are returned as a <code>string</code>, any type conversions are up to you:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">requireLogin</span> <span class="p">=</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToBoolean</span><span class="p">(</span><span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">AppSettings</span><span class="p">[</span><span class="s">&#34;RequireLogin&#34;</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">timeout</span>      <span class="p">=</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToUInt32</span><span class="p">(</span><span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">AppSettings</span><span class="p">[</span><span class="s">&#34;Timeout&#34;</span><span class="p">]);</span>
</span></span></code></pre></div><p>If you try to retrieve an app setting with a key that does not exist, you get back <code>null</code>.</p>
<h2 id="config-sections">Config sections</h2>
<p>The <code>&lt;connectionStrings&gt;</code> and <code>&lt;appSettings&gt;</code> config sections are built-in. If you want to use a non-built in config sections, you need to explicitly register them. This is done in the <code>&lt;configSections&gt;</code> element in your config file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;glimpse&#34;</span> <span class="na">type=</span><span class="s">&#34;Glimpse.Core.Configuration.Section, Glimpse.Core&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;glimpse</span> <span class="na">defaultRuntimePolicy=</span><span class="s">&#34;On&#34;</span> <span class="na">endpointBaseUri=</span><span class="s">&#34;~/Glimpse.axd&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;logging</span> <span class="na">level=</span><span class="s">&#34;Trace&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/glimpse&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>Here we register a config section named <code>&quot;glimpse&quot;</code>, implemented by the <code>Glimpse.Core.Configuration.Section</code> type found in the <code>Glimpse.Core</code> assembly. The name of the config section element <em>must</em> match the registered name, hence the <code>&lt;glimpse&gt;</code> config section.</p>
<p>The <code>&lt;glimpse&gt;</code> config section itself is interesting. Besides having the <code>&lt;logging&gt;</code> child config element, it also has config options itself, expressed as attributes. This shows that there are two ways to define config options in a config section:</p>
<ol>
<li>Through child elements and their attributes</li>
<li>Using attributes on the config section element itself</li>
</ol>
<p>For simple configuration options, attributes on the config section element probably suffice. However, this has some disadvantages:</p>
<ul>
<li>You can&rsquo;t have more than one option with the same name</li>
<li>You can&rsquo;t use nesting; there is only one level at which to define attributes</li>
</ul>
<p>The following is an example of a config section with nested child config elements:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;glimpse</span> <span class="na">defaultRuntimePolicy=</span><span class="s">&#34;On&#34;</span> <span class="na">endpointBaseUri=</span><span class="s">&#34;~/Glimpse.axd&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;runtimePolicies&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;ignoredTypes&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">type=</span><span class="s">&#34;Glimpse.AspNet.Policy.LocalPolicy, Glimpse.AspNet&#34;</span><span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;/ignoredTypes&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/runtimePolicies&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/glimpse&gt;</span>
</span></span></code></pre></div><h3 id="creating-custom-configuration-sections">Creating custom configuration sections</h3>
<p>For many applications, just using the <code>&lt;appSettings&gt;</code> config section suffices. However, there are several disadvantages to this approach:</p>
<ul>
<li>Values are always returned as a <code>string</code></li>
<li>Limited discoverability; it is not easy to find which settings are supported</li>
<li>You cannot discern between required and optional options</li>
<li>Related config options cannot be grouped</li>
<li>There is no warning or error when using unsupported settings</li>
</ul>
<p>Config sections have none of these disadvantages, so how to create our own config section? Suppose we want to create a custom config section to replace the following <code>&lt;appSettings&gt;</code> section:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;appSettings&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;add</span> <span class="na">key=</span><span class="s">&#34;RequireLogin&#34;</span> <span class="na">value=</span><span class="s">&#34;True&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;add</span> <span class="na">key=</span><span class="s">&#34;Timeout&#34;</span> <span class="na">value=</span><span class="s">&#34;10&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/appSettings&gt;</span>
</span></span></code></pre></div><p>The first step is to define a class inheriting from <code>ConfigurationSection</code>. Within that class, create a property for each config setting:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomConfigSection</span> <span class="p">:</span> <span class="n">ConfigurationSection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;requireLogin&#34;)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">RequireLogin</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">bool</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;requireLogin&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;requireLogin&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="na">
</span></span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;timeout&#34;)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Timeout</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>For a property to be recognized as a config setting, you decorate it with the <code>ConfigurationProperty</code> attribute, passing the element&rsquo;s name as its parameter. The properties themselves are just wrappers over an indexer (inherited from <code>ConfigurationSection</code>); the actual retrieval and storing of the properties is done in the base class. Note that the indexer returns an <code>object</code>, so casting to the correct type is up to you.</p>
<p>The last step is to register our custom config section in our config file. You might recall that to register a custom config section, we needed to specify the config section&rsquo;s type and its assembly. If we assume our <code>CustomConfigSection</code> class is in the <code>ConfigDemo</code> namespace in the <code>ConfigDemo</code> assembly, we can register and use it as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom</span> <span class="na">requireLogin=</span><span class="s">&#34;True&#34;</span> <span class="na">timeout=</span><span class="s">&#34;10&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>We are now ready to use our custom config section to retrieve the config options:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">customConfig</span> <span class="p">=</span> <span class="p">(</span><span class="n">CustomConfigSection</span><span class="p">)</span><span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">GetSection</span><span class="p">(</span><span class="s">&#34;custom&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">requireLogin</span> <span class="p">=</span> <span class="n">customConfig</span><span class="p">.</span><span class="n">RequireLogin</span><span class="p">;</span> <span class="c1">// Returns true</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">timeout</span>      <span class="p">=</span> <span class="n">customConfig</span><span class="p">.</span><span class="n">Timeout</span><span class="p">;</span>      <span class="c1">// Returns 10</span>
</span></span></code></pre></div><p>To get an instance of our custom config section, <code>GetSection</code> is called with the config section&rsquo;s registered name. We then cast the returned value to our custom config section class. Finally, we can use our custom config section&rsquo;s properties to retrieve the (strongly-typed) config setting values.</p>
<h3 id="customizing-configuration-properties">Customizing configuration properties</h3>
<p>So far, the only benefit of our custom config section was that our properties could be non-string values. However, this is not all there is to config properties.</p>
<h4 id="required-properties">Required properties</h4>
<p>Custom config sections allow config properties to be marked as optional or required. You do this using the <code>IsRequired</code> property of the <code>ConfigurationProperty</code> attribute.</p>
<p>The example below makes the <code>RequireLogin</code> property required and the <code>Timeout</code> property optional. Note that config properties are optional by default.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomConfigSection</span> <span class="p">:</span> <span class="n">ConfigurationSection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;requireLogin&#34;, IsRequired = true)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">RequireLogin</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">bool</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;requireLogin&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;requireLogin&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="na">
</span></span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;timeout&#34;, IsRequired = false)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Timeout</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This is now a valid configuration:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom</span> <span class="na">requireLogin=</span><span class="s">&#34;True&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>Should you forget to configure a required property, a runtime exception is thrown.</p>
<h4 id="default-values">Default values</h4>
<p>You can also assign default values to properties:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomConfigSection</span> <span class="p">:</span> <span class="n">ConfigurationSection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;requireLogin&#34;, DefaultValue = true)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">RequireLogin</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">bool</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;requireLogin&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;requireLogin&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="na">
</span></span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;timeout&#34;, DefaultValue = 20)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Timeout</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Take the following configuration file as an example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom</span> <span class="na">requireLogin=</span><span class="s">&#34;False&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>In this config file, the <code>requireLogin</code> setting is explicitly set, overriding the default value. However, the <code>timeout</code> setting is not specified and will get assigned its default value:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">customConfig</span> <span class="p">=</span> <span class="p">(</span><span class="n">CustomConfigSection</span><span class="p">)</span><span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">GetSection</span><span class="p">(</span><span class="s">&#34;custom&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">requireLogin</span> <span class="p">=</span> <span class="n">customConfig</span><span class="p">.</span><span class="n">RequireLogin</span><span class="p">;</span> <span class="c1">// Returns false (config value)</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">timeout</span>      <span class="p">=</span> <span class="n">customConfig</span><span class="p">.</span><span class="n">Timeout</span><span class="p">;</span>      <span class="c1">// Returns 20 (default value)</span>
</span></span></code></pre></div><h4 id="validators">Validators</h4>
<p>Sometimes, you want to limit a config element to a specific range of values. For this, you can use configuration validators. Let&rsquo;s start with an example, where we want to limit the values of our timeout config property to the range [0..30]:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomConfigSection</span> <span class="p">:</span> <span class="n">ConfigurationSection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;timeout&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="na">    [IntegerValidator(MinValue = 0, MaxValue = 30)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Timeout</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;timeout&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If you would assign a value to this config property not in the specified range, you&rsquo;ll get a runtime exception.</p>
<p>There are <a href="https://msdn.microsoft.com/en-us/library/system.configuration.configurationvalidatorattribute(v=vs.110).aspx">several built-in</a> config validators, including a regex validator and one that allows you to specify a callback. If the validator you want is not available, you can create it yourself by defining a class that inherits from <code>ConfigurationValidatorAttribute</code>.</p>
<h4 id="converting-values">Converting values</h4>
<p>As we saw earlier, config elements are not limited to the <code>string</code> type; we can have <code>int</code>, <code>boolean</code> and even <code>TimeSpan</code> config elements. If you want precise control over how your config element is converted, you can create a custom config converter.</p>
<p>To illustrate how this works, we&rsquo;ll create a config converter that reads and stores integer values as hexadecimal numbers:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">HexConverter</span> <span class="p">:</span> <span class="n">ConfigurationConverterBase</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">override</span> <span class="kt">object</span> <span class="n">ConvertTo</span><span class="p">(</span><span class="n">ITypeDescriptorContext</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">CultureInfo</span> <span class="n">ci</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                     <span class="kt">object</span> <span class="k">value</span><span class="p">,</span> <span class="n">Type</span> <span class="n">type</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kt">string</span><span class="p">.</span><span class="n">Format</span><span class="p">(</span><span class="s">&#34;{0:X}&#34;</span><span class="p">,</span> <span class="k">value</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">override</span> <span class="kt">object</span> <span class="n">ConvertFrom</span><span class="p">(</span><span class="n">ITypeDescriptorContext</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">CultureInfo</span> <span class="n">ci</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                       <span class="kt">object</span> <span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kt">int</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">data</span><span class="p">.</span><span class="n">ToString</span><span class="p">(),</span> <span class="n">NumberStyles</span><span class="p">.</span><span class="n">HexNumber</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The <code>ConvertFrom()</code> method is responsible for converting config file value to the config property type, which in this case is a conversion from a hex <code>string</code> to an <code>int</code>. It is no surprise that the <code>ConvertTo()</code> method works the other way around, converting the <code>int</code> config property to its hex <code>string</code> config file value.</p>
<p>To use this config converter, we decorate our config element with a <code>TypeConverter</code> attribute pointing to our config converter type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomConfigSection</span> <span class="p">:</span> <span class="n">ConfigurationSection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;hexTimeout&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="na">    [TypeConverter(typeof(HexConverter))]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">HexTimeout</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;hexTimeout&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;hexTimeout&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now use hex values in our config file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom</span> <span class="na">hexTimeout=</span><span class="s">&#34;9A&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>The <code>HexTimeout</code> property will automatically convert the hex <code>string</code> config value to an <code>int</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">customConfig</span> <span class="p">=</span> <span class="p">(</span><span class="n">CustomConfigSection</span><span class="p">)</span><span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">GetSection</span><span class="p">(</span><span class="s">&#34;custom&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">timeout</span> <span class="p">=</span> <span class="n">customConfig</span><span class="p">.</span><span class="n">HexTimeout</span><span class="p">;</span> <span class="c1">// Returns 154</span>
</span></span></code></pre></div><h3 id="custom-configuration-elements">Custom configuration elements</h3>
<p>So far, our custom config section only had config attributes, and no (child) config elements. Let&rsquo;s add a config element to our config section that represents an URL.</p>
<p>As you might have guessed, we create a class that inherits from <code>ConfigurationElement</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">UrlConfigElement</span> <span class="p">:</span> <span class="n">ConfigurationElement</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;value&#34;)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">string</span> <span class="n">Value</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="kt">string</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;value&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">set</span> <span class="p">{</span> <span class="k">base</span><span class="p">[</span><span class="s">&#34;value&#34;</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Including this config element in our config section is easy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomConfigSection</span> <span class="p">:</span> <span class="n">ConfigurationSection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;url&#34;)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">UrlConfigElement</span> <span class="n">Url</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="n">UrlConfigElement</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;url&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We declare the config property as we are used to, only now the type is our custom config element. Note that we don&rsquo;t need a setter, as setting values will be done in the <code>UrlConfigElement</code> itself.</p>
<p>We can now use this custom config element in our config file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;url</span> <span class="na">value=</span><span class="s">&#34;http://www.google.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/custom&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>Finally, using the config element is simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">customConfig</span> <span class="p">=</span> <span class="p">(</span><span class="n">CustomConfigSection</span><span class="p">)</span><span class="n">ConfigurationManager</span><span class="p">.</span><span class="n">GetSection</span><span class="p">(</span><span class="s">&#34;custom&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">url</span> <span class="p">=</span> <span class="n">customConfig</span><span class="p">.</span><span class="n">Url</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span> <span class="c1">// Returns &#34;http://www.google.com&#34;</span>
</span></span></code></pre></div><p>It is interesting to note that the base class for config sections, <code>ConfigurationSection</code>, actually derives from the <code>ConfigurationElement</code> class. In other words, every config section is also a config element, which is why you can have config properties directly within a config section.</p>
<h3 id="multiple-configuration-elements">Multiple configuration elements</h3>
<p>What if want users to define multiple instances of our custom config element? To support this, we need to create another class, one that represents zero or more instances of our config element.</p>
<p>Let&rsquo;s start with the code for this collection class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[ConfigurationCollection(typeof(UrlConfigElement))]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">UrlConfigElementCollection</span> <span class="p">:</span> <span class="n">ConfigurationElementCollection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">protected</span> <span class="kd">override</span> <span class="n">ConfigurationElement</span> <span class="n">CreateNewElement</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">UrlConfigElement</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">protected</span> <span class="kd">override</span> <span class="kt">object</span> <span class="n">GetElementKey</span><span class="p">(</span><span class="n">ConfigurationElement</span> <span class="n">element</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">element</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">throw</span> <span class="k">new</span> <span class="n">ArgumentNullException</span><span class="p">(</span><span class="s">&#34;element&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">((</span><span class="n">UrlConfigElement</span><span class="p">)</span><span class="n">element</span><span class="p">).</span><span class="n">Value</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Our custom config element class inherits from the <code>ConfigurationElementCollection</code> class, which itself derives from the <code>ConfigurationElement</code> class. Therefore, you could also define config properties on the collection class itself. The class is decorated with the <code>ConfigurationCollection</code> attribute, which indicates the config element type the class is a collection of.</p>
<p>The two methods are abstract in the base class, so we must implement them. The first, <code>CreateNewElement()</code> simply returns an instance of the config element. The <code>GetElementKey()</code> method returns an object that uniquely identifies an instance of the config element type. Here we use the <code>UrlConfigElement</code>&rsquo;s actual URL, stored in its <code>Value</code> property.</p>
<p>We can then include our config element collection in our config section like any regular configuration property:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CustomConfigSection</span> <span class="p">:</span> <span class="n">ConfigurationSection</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [ConfigurationProperty(&#34;urls&#34;)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">UrlConfigElementCollection</span> <span class="n">Urls</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="n">UrlConfigElementCollection</span><span class="p">)</span><span class="k">base</span><span class="p">[</span><span class="s">&#34;urls&#34;</span><span class="p">];</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now use the collection config property to configure multiple items:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;urls&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.google.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.microsoft.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.apple.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;/urls&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/custom&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>Retrieval of those config items is straightforward:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">foreach</span> <span class="p">(</span><span class="n">UrlConfigElement</span> <span class="n">urlElement</span> <span class="k">in</span> <span class="n">customConfig</span><span class="p">.</span><span class="n">Urls</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">var</span> <span class="n">url</span> <span class="p">=</span> <span class="n">urlElement</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As there can be only value per key and we used the URL value as the element&rsquo;s key, duplicate URL&rsquo;s will be filtered from the result. The following config file thus results in the same collection as the example above:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;urls&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.google.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.google.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.microsoft.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.microsoft.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.google.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;add</span> <span class="na">value=</span><span class="s">&#34;http://www.apple.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;/urls&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/custom&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><h4 id="custom-child-element-name">Custom child element name</h4>
<p>The default element name used to add an element to the collection is <code>&lt;add&gt;</code>, but this can be customized in the <code>ConfigurationCollection</code> attribute:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="na">[ConfigurationCollection(typeof(UrlConfigElement), AddItemName = &#34;url&#34;)]</span>
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">UrlConfigElementCollection</span> <span class="p">:</span> <span class="n">ConfigurationElementCollection</span>
</span></span></code></pre></div><p>We now add config elements using the <code>&lt;url&gt;</code> element:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;urls&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;url</span> <span class="na">value=</span><span class="s">&#34;http://www.google.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;url</span> <span class="na">value=</span><span class="s">&#34;http://www.microsoft.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;url</span> <span class="na">value=</span><span class="s">&#34;http://www.apple.com&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;/urls&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/custom&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><h2 id="config-sources">Config sources</h2>
<p>Config sources allow config sections to be configured in external files. This is done by adding the <code>configSource</code> attribute to your config section, pointing to the external config file.</p>
<p>The example below states that the <code>&lt;custom&gt;</code> config section is configured in the <code>Custom.config</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;configSections&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;section</span> <span class="na">name=</span><span class="s">&#34;custom&#34;</span> <span class="na">type=</span><span class="s">&#34;ConfigDemo.CustomConfigSection, ConfigDemo&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/configSections&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;custom</span> <span class="na">configSource=</span><span class="s">&#34;Custom.config&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>The <code>Custom.config</code> file looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;custom</span> <span class="na">requireLogin=</span><span class="s">&#34;True&#34;</span> <span class="na">timeout=</span><span class="s">&#34;25&#34;</span> <span class="nt">/&gt;</span>
</span></span></code></pre></div><p>There are several use cases for this, for example when a project is open-source and you don&rsquo;t want to share your local config settings or when you don&rsquo;t want any server-specific configuration in your config file.</p>
<h2 id="config-files-hierarchy">Config files hierarchy</h2>
<p>ASP.NET applications support a hierarchy of <code>Web.config</code> files, which is not supported by the <code>ConfigurationManager</code> class. If you want to use hierarchical <code>Web.config</code> files, you can use the <code>WebConfigurationManager</code> class instead. This class offers the same functionality as the <code>ConfigurationManager</code> class, but adds an overload to the <code>GetSection()</code> method that allows you to specify the path in which to look for the <code>Web.config</code> file.</p>
<p>If you don&rsquo;t need the hierarchy support, you can just use the <code>ConfigurationManager</code> class, which has the advantage that it also works in console applications.</p>
<h2 id="transforming-webconfig-files">Transforming Web.config files</h2>
<p>It is not uncommon for <code>Web.config</code> settings to change in different environments. A good example are connection strings, which test- and production environment values are likely different. To change a config setting, you could manually edit the files before deploying your application, but this is tedious and error-prone. Luckily, config file transforms allow you to automate this process.</p>
<p>Let&rsquo;s illustrate how this works through an example. Say our <code>Web.config</code> file has the following section:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;appSettings&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;add</span> <span class="na">key=</span><span class="s">&#34;Environment&#34;</span> <span class="na">value=</span><span class="s">&#34;TEST&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/appSettings&gt;</span>
</span></span></code></pre></div><p>If we want to change the value of the <code>Environment</code> app setting to <code>PRODUCTION</code> for <code>Release</code> builds, expand the <code>Web.config</code> file in your solution explorer and edit the <code>Web.Release.config</code> file as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration</span> <span class="na">xmlns:xdt=</span><span class="s">&#34;http://schemas.microsoft.com/XML-Document-Transform&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;appSettings&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;add</span> <span class="na">key=</span><span class="s">&#34;Environment&#34;</span> <span class="na">value=</span><span class="s">&#34;PRODUCTION&#34;</span> <span class="na">xdt:Transform=</span><span class="s">&#34;SetAttributes(value)&#34;</span>
</span></span><span class="line"><span class="cl">                                              <span class="na">xdt:Locator=</span><span class="s">&#34;Match(key)&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/appSettings&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>As you can see, the config transform file itself is also an XML file. Its contents look like the original config file, but with some differences:</p>
<ul>
<li>
<p>The <code>&lt;configuration&gt;</code> element now defines the <code>xdt</code> namespace. This imports the XML attributes we&rsquo;ll use to transform our config file.</p>
</li>
<li>
<p>The value of the <code>Environment</code> config element has been changed to <code>PRODUCTION</code>, which is the value we want to replace it with.</p>
</li>
<li>
<p>An <code>xdt:Locator</code> attribute has been added. This attribute is used to find the config element to transform in the source config file. In this case, if there is an <code>&lt;add&gt;</code> child element of the <code>&lt;appSettings&gt;</code> element which <code>key</code> attribute matches <code>Environment</code>, that element will be transformed.</p>
</li>
<li>
<p>The <code>xdt:Transform</code> attribute specifies what transformation to apply if a matching element is found. In our example, we simply state that the <code>value</code> attribute should be set to <code>PRODUCTION</code> in the transform config file.</p>
</li>
</ul>
<p>We can verify that this works by doing a <code>Release</code> mode publish of our ASP.NET application. The <code>Web.config</code> file that is published will look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;appSettings&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;add</span> <span class="na">key=</span><span class="s">&#34;Environment&#34;</span> <span class="na">value=</span><span class="s">&#34;PRODUCTION&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/appSettings&gt;</span>
</span></span></code></pre></div><p>Note that config transforms are <em>only</em> applied when publishing an ASP.NET application; if you do a regular build, the transformations won&rsquo;t be applied.</p>
<p>Interestingly, the default ASP.NET application template includes the following <code>Web.Release.config</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="cp">&lt;?xml version=&#34;1.0&#34;?&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;configuration</span> <span class="na">xmlns:xdt=</span><span class="s">&#34;http://schemas.microsoft.com/XML-Document-Transform&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;system.web&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;compilation</span> <span class="na">xdt:Transform=</span><span class="s">&#34;RemoveAttributes(debug)&#34;</span> <span class="nt">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/system.web&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/configuration&gt;</span>
</span></span></code></pre></div><p>So by default, a <code>Release</code> mode publish removes the <code>debug</code> attribute from the <code>compilation</code> element.</p>
<h4 id="transform-options">Transform options</h4>
<p>In our previous examples, we used the <code>SetAttributes</code> and <code>RemoveAttributes</code> values for the <code>xdt:Transform</code> attribute. However, there are more options:</p>
<ul>
<li>Replace: replace the element</li>
<li>Insert: insert the element</li>
<li>InsertBefore: insert the element before a specified element</li>
<li>InsertAfter: insert the element after a specified element</li>
<li>Remove: remove the element</li>
<li>RemoveAll: remove all elements</li>
<li>RemoveAttributes: remote attributes from the element</li>
<li>SetAttributes: set attributes of the elements</li>
</ul>
<p>With these transform options, you can create fairly advanced transformations.</p>
<h4 id="build-configurations">Build configurations</h4>
<p>It is important to note that you can have a config transform file for each build configuration in your project. If you add a <code>Staging</code> build configuration, you can create a <code>Web.Staging.config</code> file by right-clicking on your project and selecting <code>Add Config Transform</code>.</p>
<h3 id="transforming-appconfig-files">Transforming App.config files</h3>
<p>If you want to transform an <code>App.config</code> config file, you&rsquo;ll find this is not supported by default. For this, we can install the <a href="https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859">Config Transform</a> Visual Studio extension.</p>
<p>After you have installed the plugin, transforming an <code>App.config</code> file is almost the same as a <code>Web.config</code> file, but with one additional step. For every <code>App.config</code> you want to transform, you need to right-click on it and select the <code>Add Config Transforms</code> option. This will add <code>App.&lt;build config&gt;.config</code> files for each build configuration, similar to how it works with <code>Web.config</code> files. Note that you only need to do this once, unless you added a new build configuration, in which case you just run it again.</p>
<p>Once the <code>App.&lt;build config&gt;.config</code> files have been generated, you can use them in exactly the same way as <code>Web.config</code> transforms. The only difference is that just compiling the project is enough for the transform to be applied, you don&rsquo;t need to publish it.</p>
<p>So how does this plugin work? Well, the <code>Add Config Transforms</code> option not only added the config transform files, it also modified your project&rsquo;s <code>.csproj</code> file. If you open your project file, you&rsquo;ll find that the following MSBuild task has been added:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;UsingTask</span> <span class="na">TaskName=</span><span class="s">&#34;TransformXml&#34;</span>
</span></span><span class="line"><span class="cl">           <span class="na">AssemblyFile=</span><span class="s">&#34;$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll&#34;</span> <span class="nt">/&gt;</span>
</span></span></code></pre></div><p>This MSBuild task points to the DLL that is used to transform <code>Web.config</code> files, hence its name: <code>Microsoft.Web.Publishing.Tasks.dll</code>. If you examine the <code>.csproj</code> file further, you&rsquo;ll find that this task is used to automatically apply the transformation after the project has been compiled.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Config files are an important part of the .NET ecosystem. Just using app settings will suffice in many cases, but its disadvantages start to show when the configuration options become more complex. Creating your own config section(s) really helps in those scenarios. Implementing a custom config section or element is surprisingly easy and has many immediate advantages. When combining them with automatic config transforms, you can create some advanced config setups.</p>
]]></content>
		</item>
		
		<item>
			<title>RequireJS</title>
			<link>https://www.erikschierboom.com/2014/11/17/requirejs/</link>
			<pubDate>Mon, 17 Nov 2014 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2014/11/17/requirejs/</guid>
			<description>This blog post will show how to use the RequireJS library.
Why RequireJS? Although JavaScript is a very popular programming language, it lacks some features programmers take for granted. One of these omissions is a module system, which makes it hard to split JavaScript code into small, re-usable parts.
Although the next JavaScript version will have support for modules, browser support at the moment is virtually non-existent. Luckily, there are JavaScript libraries that add support for modules.</description>
			<content type="html"><![CDATA[<p>This blog post will show how to use the RequireJS library.</p>
<h2 id="why-requirejs">Why RequireJS?</h2>
<p>Although JavaScript is a very popular programming language, it lacks some features programmers take for granted. One of these omissions is a module system, which makes it hard to split JavaScript code into small, re-usable parts.</p>
<p>Although the next JavaScript version <em>will</em> have <a href="http://eviltrout.com/2014/05/03/getting-started-with-es6.html">support for modules</a>, browser support at the moment is virtually non-existent. Luckily, there are JavaScript libraries that add support for modules. <a href="http://requirejs.org/">RequireJS</a> is such a library. It implements the <a href="https://github.com/amdjs/amdjs-api/blob/master/AMD.md">Asynchronous Module Definition (AMD)</a>, which specifies an API that lets us define and use modules in our JavaScript code. A library that implements the AMD is known as an AMD loader.</p>
<h2 id="structure">Structure</h2>
<p>Although RequireJS is very powerful, its learning curve can be steep. This document aims to slowly build up your knowledge of RequireJS, starting with the basics and gradually moving on to more advanced functionality. We will do this through small, stand-alone examples.</p>
<h2 id="basics">Basics</h2>
<p>Before moving on to the examples, we&rsquo;ll introduce some basic concepts you need to understand when working with RequireJS.</p>
<h3 id="defining-modules">Defining modules</h3>
<p>In the AMD specification, modules are defined using the <code>define()</code> function. The <code>define()</code> function takes as its argument the JavaScript value to return when the module is requested.</p>
<p>This code defines a module that returns a number:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span>
</span></span></code></pre></div><p>You can also return an object:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">title</span><span class="o">:</span> <span class="s2">&#34;Master of Puppets&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">artist</span><span class="o">:</span> <span class="s2">&#34;Metallica&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">year</span><span class="o">:</span> <span class="mi">1986</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>When you need to do some setup work, you can pass a function to <code>define()</code>, in which the module&rsquo;s value is returned:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// Return the object value that is returned to requesters
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">increment</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">counter</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">getValue</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nx">counter</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="loading-modules">Loading modules</h3>
<p>Defining modules is one part of the modules equation, loading them is the other. Just as you use a function to define a module, you use a function to load a module: <code>require()</code>.</p>
<p>When you load a module, you refer to it by its module ID, which is just a simple <code>string</code>. The <code>define()</code> function takes an optional parameter that lets you specify a module&rsquo;s ID:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Define the module with module ID = &#39;album&#39;
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">define</span><span class="p">(</span><span class="s2">&#34;album&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">title</span><span class="o">:</span> <span class="s2">&#34;Master of Puppets&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">artist</span><span class="o">:</span> <span class="s2">&#34;Metallica&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">year</span><span class="o">:</span> <span class="mi">1986</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>We can now load this module as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">([</span><span class="s2">&#34;album&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">album</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">album</span><span class="p">.</span><span class="nx">title</span><span class="p">);</span> <span class="c1">// Use the value returned by the &#39;album&#39; module
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><p>The first parameter of the <code>require()</code> function is an array of module IDs, also known as its dependencies. The AMD loader will try to load the modules with the specified module IDs. Once all dependencies have been loaded, the callback function passed as the second parameter is called. The values returned by each module will be passed as arguments to the callback function, in the order specified by the dependencies array.</p>
<p>In our example, there is only one dependency: the module with ID <code>'album'</code>. Consequently, our callback method also has only one parameter, which will contain the value returned by the <code>'album'</code> module.</p>
<p>If a module does not explicitly specify a module ID, the AMD loader will define one for it based on the URL at which it is requested. This means that if you don&rsquo;t explicitly define a module ID, moving a module file to another location changes its module ID. Exactly how a module&rsquo;s ID is inferred from its URL will be discussed later.</p>
<p>In general, it is considered bad practice to specify an ID for your modules, as you lose the link between URL and module ID. This makes determining a module&rsquo;s ID less obvious.</p>
<h3 id="module-dependencies">Module dependencies</h3>
<p>So far, our modules did not depend on other modules. A module can depend on other modules by passing an array of the module IDs it depends on as its first parameter. The second parameter is the callback function that is called when all dependencies have been loaded. This is similar to our previous <code>require()</code> example. Within the callback function, we return our module&rsquo;s value:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Define a module with (two) dependencies
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;album&#34;</span><span class="p">,</span> <span class="s2">&#34;counter&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">album</span><span class="p">,</span> <span class="nx">counter</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">counter</span><span class="p">.</span><span class="nx">increment</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">album</span><span class="p">.</span><span class="nx">title</span> <span class="o">+</span> <span class="s2">&#34; requested &#34;</span> <span class="o">+</span> <span class="nx">counter</span><span class="p">.</span><span class="nx">getValue</span><span class="p">()</span> <span class="o">+</span> <span class="s2">&#34; times&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Note that the callback function&rsquo;s parameters are defined in the order of its dependencies. This means that the first parameter will get passed the value of the first module dependency (<code>'album'</code>); consequently, the second parameter corresponds to the <code>'counter'</code> module.</p>
<h3 id="main-file">Main file</h3>
<p>Another important concept is that of a main file. When you include RequireJS in your application, you have to point it to a JavaScript file that will be used as your application&rsquo;s entry point, your main file. When your application runs, RequireJS will automatically load this main file and its code will be executed.</p>
<p>The function of the main file is twofold:</p>
<ul>
<li>Run your application</li>
<li>Configure RequireJS (optional)</li>
</ul>
<p>To run your application, usually you load another module. You do this through the <code>requirejs</code> function, which will automatically be available in your main file. The following code is the most basic main file, which just loads the <code>'app'</code> module:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">requirejs</span><span class="p">([</span><span class="s2">&#34;app&#34;</span><span class="p">]);</span>
</span></span></code></pre></div><p>The <code>'app'</code> module contains the actual application logic. You could define your application logic in the main file itself, but it is good practice to keep it out of your main file.</p>
<p>The second function of the main file is to configure RequireJS. Configuring is done by passing the configuration options as an object parameter to <code>require.config</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// Specify configuration options
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><p>For the moment, we won&rsquo;t go into the various <a href="http://requirejs.org/docs/api.html#config">configuration options</a>. We&rsquo;ll see some of them later.</p>
<h3 id="module-paths">Module paths</h3>
<p>The last concept we need to introduce is that of module paths. When RequireJS requests a module, it loads that module using this template: <code>&lt;base URL&gt;/&lt;module ID&gt;.js</code>.</p>
<p>By default, the base URL is set to the path from which the main file is loaded. So if the main file is located at <code>scripts/main.js</code>, the base URL is set to <code>scripts</code>. Using this base URL, a request for the <code>'app'</code> module translates to a request to <code>scripts/app.js</code>. If the base URL was <code>frontend/js</code> and the module ID <code>'utils/message'</code>, the module would be loaded from <code>frontend/js/utils/message.js</code>.</p>
<p>Using this template, it is possible to determine a module&rsquo;s ID by knowing the base URL and the URL at which the module can be found. So if you have a module that is located at <code>scripts/utils/messages.js</code> and you know the base URL is <code>scripts</code>, the module ID is thus <code>'utils/messages'</code>.</p>
<p>Note that it is possible to customize the base URL, which will be discussed later.</p>
<h2 id="examples">Examples</h2>
<p>Now that we have learned the basics, we are ready to move on to our examples. The code for all examples can be found in a <a href="https://github.com/ErikSchierboom/requirejstutorial">GitHub repository</a>. We encourage you to clone that repository to your local machine to examine and play with the examples yourselves. The code for each example is in a separate directory.</p>
<h3 id="example-1-basic-usage">Example 1: basic usage</h3>
<p>Our first step to create a RequireJS application is to download the <a href="http://requirejs.org/docs/download.html"><code>require.js</code></a> library. We will store this file in a directory named <code>lib</code>.</p>
<p>We then create an HTML file named <code>index.html</code> in the root of our directory. In this file we include the <code>require.js</code> file we just downloaded:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">data-main</span><span class="o">=</span><span class="s">&#34;scripts/main&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;lib/require.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Example 1: basic usage<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>One thing stands out: the <code>data-main</code> attribute of the <code>&lt;script&gt;</code> tag with source <code>lib/require.js</code>. This <code>data-main</code> attribute points to the JavaScript file that will automatically be loaded by RequireJS when the page is loaded: the main file. Note that the <code>data-main</code> value omits the <code>.js</code> extension; this is required as RequireJS will add the extension itself.</p>
<p>In our example, we set <code>data-main</code> to <code>scripts/main</code>, which means that RequireJS will try to load the main file from <code>scripts/main.js</code> file. Our next step is to create this file.</p>
<p>As noted, the <code>main.js</code> file can be seen as the main entry point of your JavaScript application. In this file, two things can be done:</p>
<ol>
<li>Run your application</li>
<li>Configure RequireJS (optional)</li>
</ol>
<p>In this example, we&rsquo;ll ignore the configuration options. To run our application, we could put the application logic in our <code>main.js</code> file, but the whole purpose of RequireJS is to use modules so let&rsquo;s use that.</p>
<p>By convention, most main files load a module named <code>'app'</code>, which contains the application logic. Our main file is nothing more than an entry point. Applying this to our example results in the following main file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">requirejs</span><span class="p">([</span><span class="s2">&#34;app&#34;</span><span class="p">]);</span> <span class="c1">// Load the &#39;app&#39; module
</span></span></span></code></pre></div><p>The final step is to create the <code>'app'</code> module, which just shows an alert when it is loaded:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">alert</span><span class="p">(</span><span class="s2">&#34;Hello World&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>But where should we save our <code>'app'</code> module? By default, the base URL is set to the main file&rsquo;s path. As our main file was found at <code>scripts/main.js</code>, modules will be loaded from <code>scripts/&lt;module ID&gt;.js</code>. We thus save our <code>'app'</code> module in <code>scripts/app.js</code>:</p>
<p>Now when you open the <code>index.html</code> file in a browser, the following things happen:</p>
<ol>
<li>The RequireJS file is loaded from <code>lib/require.js</code></li>
<li>RequireJS loads the main file from <code>scripts/main.js</code></li>
<li>The main file loads the <code>'app'</code> module from <code>scripts/app.js</code></li>
<li>The <code>'app'</code> module shows the alert message</li>
</ol>
<p>This chain of requests is typical of a RequireJS application. You start with a request for the RequireJS library, which requests the main file, which then requests a module. This module can then also request other modules (its dependencies), and so on.</p>
<h4 id="structure-1">Structure</h4>
<p>The end result of this example, when looking at it from a file viewpoint, looks like this:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>And we now have a working RequireJS application!</p>
<h3 id="example-2-load-module-using-explicit-dependency-syntax">Example 2: load module using explicit dependency syntax</h3>
<p>In our previous example, the <code>'app'</code> module did not depend on another module. Let&rsquo;s change that. First, we&rsquo;ll define the <code>'messages'</code> module that the <code>'app'</code> module will use:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">getHello</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="s2">&#34;Hello World&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>This module returns an object with one function, <code>getHello()</code>, which returns a string.</p>
<p>We can now have our <code>'app'</code> module use the <code>'messages'</code> module by specifying it as a dependency in the <code>'app'</code> module:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;messages&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messages</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">alert</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span> <span class="c1">// Alerts &#39;Hello World&#39;
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><p>The dependency on the <code>'messages'</code> module is specified by passing its module ID in array form as the <code>define()</code> function&rsquo;s first parameter. When RequireJS loads the <code>'app'</code> module, it will see this dependency and start loading the <code>'messages'</code> module first. Once the <code>'messages'</code> module has been been loaded, RequireJS will call the <code>'app'</code> module&rsquo;s callback function with the value returned by the <code>'messages'</code> module as its parameter.</p>
<h3 id="example-3-load-module-using-the-require-function">Example 3: load module using the require() function</h3>
<p>Sometimes, a module&rsquo;s dependencies are not know beforehand, or you might want to defer loading them to a later time. This scenario is be supported by modifying a module&rsquo;s definition to not take an array of dependencies, but only a callback with a single parameter. This parameter is a function that can take a module ID and load that module.</p>
<p>In our previous example, the <code>'app'</code> module explicitly defined its dependency on the <code>'messages'</code> as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;messages&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messages</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">alert</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span> <span class="c1">// Alerts &#39;Hello World&#39;
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><p>We can get the same behavior by using the <code>require</code> parameter option:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">require</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">messages</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&#34;messages&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="nx">alert</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>In general, the first option is preferred as it makes finding a module&rsquo;s dependencies easier. The second option is usually reserved for more advanced use cases, e.g. when you don&rsquo;t know a module&rsquo;s dependencies beforehand.</p>
<h3 id="example-4-load-multiple-modules-using-explicit-syntax">Example 4: load multiple modules using explicit syntax</h3>
<p>So far, our modules only had a single dependency. To depend on more than one module, simply add the other module IDs to the dependencies array:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;messages&#34;</span><span class="p">,</span> <span class="s2">&#34;gui&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="nx">gui</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">gui</span><span class="p">.</span><span class="nx">showMessage</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The following module depends on both the <code>'messages'</code> and <code>'gui'</code> modules.</p>
<p>One can see that the order of the parameters in the callback function must correspond to the order of the dependencies.</p>
<p>Note that the dependent modules are requested in parallel, no guarantees are made which of the modules loads first. However, RequireJS does guarantee that the callback function is only called when <em>all</em> modules have been loaded successfully. If one or more modules failed to load, the callback function will not be called.</p>
<h3 id="example-5-namespaces">Example 5: namespaces</h3>
<p>Although JavaScript has no native concept of namespaces, we can simulate them using RequireJS. For this, we use the fact that a module&rsquo;s ID is determined by its URL.</p>
<p>Consider the following directory structure:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>The <code>main.js</code> and <code>app.js</code> files are in the <code>scripts</code> directory, which will be the base URL. The <code>'app'</code> module has two dependencies:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;utils/messages&#34;</span><span class="p">,</span> <span class="s2">&#34;utils/output/gui&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messages</span><span class="p">,</span> <span class="nx">gui</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">gui</span><span class="p">.</span><span class="nx">showMessage</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>When looking at the dependencies, one could argue that the <code>'messages'</code> module appears to be part of the <code>utils</code> namespace and the <code>'gui'</code> module is part of the <code>utils/output</code> namespace.</p>
<h3 id="example-6-load-modules-using-a-relative-path">Example 6: load modules using a relative path</h3>
<p>So far, modules were always defined in the same directory as our main file or in a sub-directory, but what to do with modules outside of this path?</p>
<p>Let&rsquo;s illustrate this problem with an example:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>Our base URL here is <code>scripts</code>. That means that we cannot load the <code>'app'</code> module from our <code>main.js</code> file as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">requirejs</span><span class="p">([</span><span class="s2">&#34;app&#34;</span><span class="p">]);</span> <span class="c1">// The module will fail to load
</span></span></span></code></pre></div><p>Requesting the <code>'app'</code> module like this, RequireJS will try to load it from <code>scripts/app.js</code>, which is not its correct location.</p>
<p>What we want is to first go up one directory from our base URL (we are now at the root) and then load the <code>lib/app.js</code> file. To do this, we use the special <code>..</code> path:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">requirejs</span><span class="p">([</span><span class="s2">&#34;../lib/app&#34;</span><span class="p">]);</span>
</span></span></code></pre></div><p>When RequireJS tries to load the <code>'../lib/app'</code> module, it first prepends the base URL: <code>scripts/../lib/app.js</code>. This path simplifies to <code>lib/app.js</code>, which is the correct path for the <code>'app'</code> module.</p>
<p>In the <code>'app'</code> module, we want to use the <code>'messages'</code> module, which is also outside the base URL. Once again, we could use the <code>..</code> special path:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;../lib/messages&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messages</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">alert</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>This code works, but there is an even better option. The special <code>.</code> path means: &ldquo;load the module relative to the current module&rdquo;. This option bypasses the base URL and uses the path of the module in which it is used.</p>
<p>We could thus also include the <code>'messages'</code> module as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;./messages&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messages</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">alert</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="example-7-custom-base-url">Example 7: custom base URL</h3>
<p>Up until now, the base URL used by RequireJS was always determined by the main file&rsquo;s location. However, you can explicitly set the base URL in your main file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">baseUrl</span><span class="o">:</span> <span class="s2">&#34;lib&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>To see how this influences an application, consider the follows folder structure:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>Our main file is located in the root. By default, the <code>'messages'</code> module&rsquo;s ID would thus be <code>'lib/messages'</code>. However, as we set the base URL to <code>lib</code>, its module ID becomes just <code>'messages'</code>.</p>
<p>The <code>'app'</code> module can thus request the <code>'messages'</code> module as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;messages&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">messages</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">alert</span><span class="p">(</span><span class="nx">messages</span><span class="p">.</span><span class="nx">getHello</span><span class="p">());</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Finally, to load the <code>'app'</code> module from the <code>main.js</code> file, we have to use a path relative to our custom <code>lib</code> base URL:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">requirejs</span><span class="p">([</span><span class="s2">&#34;../scripts/app&#34;</span><span class="p">]);</span>
</span></span></code></pre></div><h3 id="example-8-explicit-module-id">Example 8: explicit module ID</h3>
<p>Sometimes, you want to decouple a module&rsquo;s ID from its actual path. This can be done in the main file&rsquo;s configuration section. This feature is mostly used when working with external libraries.</p>
<p>Say we have the following directory structure:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<p>If the <code>'app'</code> module depends on jQuery, it would be defined like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;../lib/jquery-2.1.1&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">$</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><p>Not only does this path not look pretty, it also includes the version number, which means that each upgrade of the jQuery library requires us to modify all modules that depend on it.</p>
<p>A much more elegant solution is to explicitly define a module ID for the jQuery module in the main file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">jquery</span><span class="o">:</span> <span class="s2">&#34;../lib/jquery-2.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>What we have done is instruct RequireJS that when the <code>'jquery'</code> module is requested, it should load it from <code>lib/jquery-2.1.1.js</code> (as the base URL is the root directory).</p>
<p>Our <code>'app'</code> module now looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;jquery&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">$</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// ...
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">});</span>
</span></span></code></pre></div><p>Note that if you work with the jQuery library, its module ID in fact <strong>must</strong> be equal to <code>'jquery'</code>. For more information, see <a href="http://requirejs.org/docs/jquery.html">how to use RequireJS with jQuery</a>.</p>
<h3 id="example-9-external-url">Example 9: external URL</h3>
<p>Up until now, all our modules were stored locally. However, it is also possible to load a module from an external URL. One use case for this would be to load a module from a <a href="http://en.wikipedia.org/wiki/Content_delivery_network">CDN</a>. To load a module from an external URL, we just set the path of the module to an URL:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">jquery</span><span class="o">:</span> <span class="s2">&#34;https://code.jquery.com/jquery-2.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now when the <code>'jquery'</code> module is requested, it will be loaded from <code>https://code.jquery.com/jquery-2.1.1.js</code>.</p>
<h3 id="example-10-fallback-paths">Example 10: fallback paths</h3>
<p>When requesting a module, there is always the possibility that the module can not be loaded. This is especially true when you load a module from an external URL. To gracefully handle failure to load a module, RequireJS allows you to define a fallback path, which is used when the module could not be loaded from the original path.</p>
<p>To add a fallback, you define the module&rsquo;s path as an array of strings:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">jquery</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;https://code.jquery.com/jquery-2.1.1&#34;</span><span class="p">,</span> <span class="s2">&#34;../lib/jquery-2.1.1&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>What happens is that when the <code>'jquery'</code> module is requested, RequireJS will first try to load it by using the first path in the array. If that request fails, RequireJS will move to the next path in the array and try that, repeating this until either the module was loaded successfully or there are no more paths left to try.</p>
<p>The fallback option is often used when loading a module from an external URL, where a locally hosted file is used as a fallback. In our example, we instruct RequireJS to first try to load jQuery from an external URL, but upon failure to fall back to a local version of that file.</p>
<p>Note that you can add more than one fallback by just adding more paths to the array:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">jquery</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;https://code.jquery.com/jquery-2.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;../lib/jquery-2.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="example-11-dependencies-order">Example 11: dependencies order</h3>
<p>When working with multiple libraries, it is not uncommon for one library to depend on another. An example of this is the <a href="http://getbootstrap.com/">Bootstrap</a> library, which depends on <a href="http://jquery.com/">jQuery</a>. The first step is thus to define the paths to our our libraries:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">jquery</span><span class="o">:</span> <span class="s2">&#34;../lib/jquery-2.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">bootstrap</span><span class="o">:</span> <span class="s2">&#34;../relib/bootstrap&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>We could use these modules as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;jquery&#34;</span><span class="p">,</span> <span class="s2">&#34;bootstrap&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">bootstrap</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">$</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">$</span><span class="p">(</span><span class="s2">&#34;.alert&#34;</span><span class="p">).</span><span class="nx">alert</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>If you would run this code, you&rsquo;ll find that it does not always work. This is because RequireJS will request the <code>jquery</code> and <code>bootstrap</code> modules in parallel. Where the <code>jquery</code> module loads first, everything is fine. However, if the <code>bootstrap</code> module is the first to load, it will throw an exception as its dependency jQuery has not yet been loaded. The key thing to note is that the order in which you define your dependencies does not have to correspond to the order in which they are loaded.</p>
<p>To fix this problem, we have to do some additional configuration in our main file. There, you can define a <code>shim</code> section in which modules can be configured individually. To solve our dependency problem, we mark the <code>'jquery'</code> module as a dependency of the <code>'bootstrap'</code> module using the <code>deps</code> property:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;jquery&#39;</span><span class="o">:</span> <span class="s1">&#39;../lib/jquery-2.1.1&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;bootstrap&#39;</span><span class="o">:</span> <span class="s1">&#39;../lib/bootstrap
</span></span></span><span class="line"><span class="cl"><span class="s1">    },
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">    shim: {
</span></span></span><span class="line"><span class="cl"><span class="s1">        &#39;</span><span class="nx">bootstrap</span><span class="s1">&#39;: {
</span></span></span><span class="line"><span class="cl"><span class="s1">            deps: [&#39;</span><span class="nx">jquery</span><span class="err">&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now when the <code>'bootstrap'</code> module is loaded, RequireJS will first load the <code>'jquery'</code> module. Only when the <code>'jquery'</code> has loaded successfully, will the <code>'bootstrap'</code> module be loaded. This fixes our dependency problem.</p>
<p>Note that dependencies are defined as an array, which means that a module can have more than one dependency.</p>
<h3 id="example-12-optimize-requirejs-using-rjs">Example 12: optimize RequireJS using r.js</h3>
<p>By default, RequireJS will issue a request for each module its loads. Therefore, lots of modules means lots of requests. Obviously, this is not good for performance. Ideally, we would only load a single, minified file that contains all modules. For this, the <a href="http://requirejs.org/docs/optimization.html"><code>r.js</code></a> tool was developed. You run the <code>r.js</code> tool on a specific file, and <code>r.js</code> will then trace that file&rsquo;s dependencies, combine all of those dependencies and write them to a single file.</p>
<p>Using <code>r.js</code> is very simple. You can choose to run it on node.js, JavaScript or in the browser. We will use node.js in our example. To use r.js in node, install it using the following command:</p>
<p><code>npm install -g requirejs</code></p>
<p>At this point, we now have two options:</p>
<ol>
<li>Run <code>r.js</code> using command-line parameters</li>
<li>Run <code>r.js</code> with a build profile</li>
</ol>
<p>The build profile and command-line options can do exactly the same things, they just have a different way of doing them.</p>
<p>In our example, we&rsquo;ll use a build profile, which is just a JavaScript file containing the configuration options. Here is our example&rsquo;s build profile:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">out</span><span class="o">:</span> <span class="s2">&#34;main-built.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>We specify two configuration options:</p>
<ul>
<li><strong>name</strong>: the name of the file to optimize. From this file, <code>r.js</code> will start to analyze the dependency chain. Usually, this would point to the main file.</li>
<li><strong>out</strong>: the name of the file to which the optimized output should be written.</li>
</ul>
<p>Now we can run the following command to create our optimized <code>main-built.js</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">node r.js -o build.js
</span></span></code></pre></div><p>Once the command has completed, the optimized output will have been written to <code>main-built.js</code>. This file not only contains the main file, but also all modules it depends on.</p>
<p>The last step is to use our optimized file instead of our old main file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">data-main</span><span class="o">=</span><span class="s">&#34;scripts/main-built&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;lib/require.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Now, there will be only a single request to the <code>scripts/main-built.js</code> file, instead of issuing a request for each module.</p>
<h3 id="example-12-optimize-using-external-dependendies">Example 12: optimize using external dependendies</h3>
<p>If you configured a module with an external URL (see example 9), you would expect <code>r.js</code> to not include this file when optimizing. However, if you would run <code>r.js</code> on a file that has external dependencies, you will get an error message. The problem is that <code>r.js</code> by default includes all dependent modules in the output file, but that it cannot work with external files. To work around this, you need to instruct <code>r.js</code> to ignore the modules that are loaded from an external URL.</p>
<p>In our example, we used an external URL for the <code>'jquery'</code> module. We can instruct <code>r.js</code> to ignore the <code>'jquery'</code> module by setting its path to the special value: <code>'empty:'</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">out</span><span class="o">:</span> <span class="s2">&#34;main-built.js&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">jquery</span><span class="o">:</span> <span class="s2">&#34;empty:&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now when you run <code>r.js</code>, the optimized <code>main-built.js</code> file will not contain the <code>'jquery'</code> module and RequireJS will load it from its external URL.</p>
<h3 id="example-14-optimize-using-grunt">Example 14: optimize using Grunt</h3>
<p>In the previous examples, we ran the <code>r.js</code> tool from the command-line. However, you can also run <code>r.js</code> from <a href="http://gruntjs.com/">Grunt</a>. First, install the following Node module:</p>
<pre tabindex="0"><code>npm install grunt-contrib-requirejs --save-dev
</code></pre><p>Then enable this task by adding the following to your <code>Gruntfile.js</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">grunt</span><span class="p">.</span><span class="nx">loadNpmTasks</span><span class="p">(</span><span class="s2">&#34;grunt-contrib-requirejs&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>We are now ready to configure the <code>r.js</code> optimization task in our Gruntfile:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">requirejs</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">compile</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;main&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">baseUrl</span><span class="o">:</span> <span class="s1">&#39;scripts&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">out</span><span class="o">:</span> <span class="s1">&#39;scripts/main-built.js&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The supported configuration options are the same as when working directly with <code>r.js</code>. Note that if you do not explicitly set the base URL, the base URL will be equal to the path in which the <code>Gruntfile.js</code> file is located. As our main file is actually in the <code>scripts</code> directory, we needed to explicitly set the base URL.</p>
<p>Now we can build the optimized version of our main file using:</p>
<pre tabindex="0"><code>grunt requirejs
</code></pre><p>When this command finishes, an optimized <code>main-built.js</code> file will have been created.</p>
<h3 id="example-15-load-non-amd-module">Example 15: load non-AMD module</h3>
<p>Although many libraries define themselves as AMD modules, not all of them do. For those libraries, RequireJS supports the concept of a <em>shim</em>. Using <em>shims</em>, one can access non-AMD modules as if they were defined as AMD modules.</p>
<p>Take the <a href="https://github.com/lynaghk/singult"><code>singult</code></a> library (which can compile <a href="https://github.com/weavejester/hiccup">Hiccup</a> templates). Instead of registering itself as an AMD module, it exports a global variable named <code>singult</code>. We thus need to tell RequireJS that when the <code>singult</code> module is requested, it should return the global <code>singult</code> variable. We do this in the <code>shim</code> configuration section of our main file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">singult</span><span class="o">:</span> <span class="s2">&#34;../lib/singult.min&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">shim</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">singult</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">exports</span><span class="o">:</span> <span class="s2">&#34;singult&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>With this simple modification, we can now use the <code>singult</code> library like an AMD module:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;singult&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">singult</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">hiccup</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;div&#34;</span><span class="p">,</span> <span class="p">{</span> <span class="nx">a</span><span class="o">:</span> <span class="mi">1</span> <span class="p">},</span> <span class="s2">&#34;Hello World&#34;</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">  <span class="kd">var</span> <span class="nx">element</span> <span class="o">=</span> <span class="nx">singult</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">hiccup</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="example-16-unit-testing">Example 16: unit testing</h3>
<p>If you want to unit test using RequireJS, your unit test framework must support asynchronously loading tests. Luckily, most popular test frameworks <a href="https://github.com/jrburke/requirejs/wiki/Test-frameworks">support this</a>. In our example, we&rsquo;ll use <a href="http://qunitjs.com/">QUnit</a> as our test framework.</p>
<p>Let&rsquo;s start with the module we&rsquo;ll be testing:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">add</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nx">x</span> <span class="o">+</span> <span class="nx">y</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">};</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Well save this module in <code>scripts/math.js</code>. The next step is to define our test module:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;QUnit&#34;</span><span class="p">,</span> <span class="s2">&#34;scripts/math&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">QUnit</span><span class="p">,</span> <span class="nx">math</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">test</span><span class="p">(</span><span class="s2">&#34;add should add positive numbers.&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">equal</span><span class="p">(</span><span class="nx">math</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="mi">7</span><span class="p">,</span> <span class="s2">&#34;The return should be 7.&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">equal</span><span class="p">(</span><span class="nx">math</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="mi">8</span><span class="p">,</span> <span class="s2">&#34;The return should be 8.&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">test</span><span class="p">(</span><span class="s2">&#34;add should add negative numbers.&#34;</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">equal</span><span class="p">(</span><span class="nx">math</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">2</span><span class="p">),</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="s2">&#34;The return should be -3.&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="nx">equal</span><span class="p">(</span><span class="nx">math</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">),</span> <span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="s2">&#34;The return should be -8.&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The test module is a regular RequireJS module, with a dependency on the <code>'scripts/math'</code> module (whose functionality is tested) and the <code>'QUnit'</code> module for the <code>test()</code> function.</p>
<p>The next step is to create the HTML file that will be our test runner:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;lib/qunit-1.15.0.css&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- Include the RequireJS library. We supply the &#34;data-main&#34; attribute to 
</span></span></span><span class="line"><span class="cl"><span class="c">           let RequireJS know which file it should load. This file (runner.js) 
</span></span></span><span class="line"><span class="cl"><span class="c">           can be seen as the entry point (main) of the application. --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">data-main</span><span class="o">=</span><span class="s">&#34;runner&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;lib/require.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- This empty divs will be filled with the test results when QUnit 
</span></span></span><span class="line"><span class="cl"><span class="c">           has run its tests --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;qunit&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;qunit-fixture&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>This file is similar to the HTML files we used in other examples, with some small differences:</p>
<ul>
<li>A reference to the QUnit stylesheet has been added to style the test output</li>
<li>The RequireJS main file is now named <code>runner</code>. This is a convention, where the JavaScript file responsible for running the tests is called a <em>runner</em> (or <em>testrunner</em>)</li>
<li>Two empty <code>&lt;div&gt;</code> elements were added, which QUnit uses to display the test results</li>
</ul>
<p>The final step is to create the <code>runner.js</code> file, which is our RequireJS main file that acts as the test runner. In this file, we need to do several things:</p>
<ul>
<li>Allow QUnit to be loaded as an AMD module. This is done by defining a <code>shim</code> section for <code>'QUnit'</code> with an <code>exports</code> section</li>
<li>Configure QUnit to not immediately start running the tests, as they&rsquo;ll be loaded asynchronously later. For this, we use the <code>init</code> configuration option in the <code>shim</code> section, which takes a function to execute when the library has been loaded.</li>
<li>Load the test module(s) using RequireJS and, once they have been loaded, have QUnit start running its tests.</li>
</ul>
<p>We end up with the following <code>runner.js</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">QUnit</span><span class="o">:</span> <span class="s2">&#34;lib/qunit-1.15.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">shim</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">QUnit</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">exports</span><span class="o">:</span> <span class="s2">&#34;QUnit&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// When the QUnit module is loaded, we have to
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="c1">// configure it to not automatically start running
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="c1">// the tests as they&#39;ll be loaded later on
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="nx">QUnit</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">autoload</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nx">QUnit</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">autostart</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// require the QUnit library and all test module
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">require</span><span class="p">([</span><span class="s2">&#34;QUnit&#34;</span><span class="p">,</span> <span class="s2">&#34;tests/mathtests&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">QUnit</span><span class="p">,</span> <span class="nx">mathTests</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// Now that we have asynchronously loaded the tests
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="c1">// we can give QUnit the signal to start running the tests
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="nx">QUnit</span><span class="p">.</span><span class="nx">load</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="nx">QUnit</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now we are ready to run our tests by simply viewing our <code>index.html</code> test runner file in a browser.</p>
<h4 id="structure-2">Structure</h4>
<p>The resulting folder structure is as follows:</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<h3 id="example-17-unit-testing-using-grunt">Example 17: unit testing using Grunt</h3>
<p>In the previous example, we used a browser to run our unit tests. But what if you want to run RequireJS unit tests using Grunt, where code runs on the server and not in a browser?</p>
<p>For this purpose, you can use the <a href="https://github.com/gruntjs/grunt-contrib-qunit"><code>grunt-contrib-qunit</code></a> plug-in. This plug-in can run your test runner HTML file(s) in a <em>headless browser</em>, which is essentially a full-featured browser without a GUI. We configure the <code>grunt-contrib-qunit</code> plug-in as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">grunt</span><span class="p">.</span><span class="nx">initConfig</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">qunit</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">all</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">urls</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;http://localhost:8000/index.html&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now when you run <code>grunt qunit</code>, you&rsquo;ll probably get an exception that the specified URL failed to load. This is because the <code>grunt-contrib-qunit</code> doesn&rsquo;t actually host anything. For this, we can use the <a href="https://github.com/gruntjs/grunt-contrib-connect"><code>grunt-contrib-connect</code></a> plug-in, which is a simple, lightweight web-server. In our example, we configure the <code>connect</code> webserver to run at port <code>8000</code>, where the current directory is used as the webserver&rsquo;s root:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">grunt</span><span class="p">.</span><span class="nx">initConfig</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">connect</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">server</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">port</span><span class="o">:</span> <span class="mi">8000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">base</span><span class="o">:</span> <span class="s2">&#34;.&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>The next step is to register the plug-ins with Grunt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">grunt</span><span class="p">.</span><span class="nx">loadNpmTasks</span><span class="p">(</span><span class="s2">&#34;grunt-contrib-qunit&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="nx">grunt</span><span class="p">.</span><span class="nx">loadNpmTasks</span><span class="p">(</span><span class="s2">&#34;grunt-contrib-connect&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>The final step is to combine these two plug-ins and assign them to the <code>test</code> task:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">grunt</span><span class="p">.</span><span class="nx">registerTask</span><span class="p">(</span><span class="s2">&#34;test&#34;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&#34;connect&#34;</span><span class="p">,</span> <span class="s2">&#34;qunit&#34;</span><span class="p">]);</span>
</span></span></code></pre></div><p>Now, we can run <code>grunt test</code> which first starts the <code>connect</code> webserver and then runs the QUnit test runner. Unfortunately, if you try this you&rsquo;ll get the following error message:</p>
<p><code>PhantomJS timed out, possibly due to a missing QUnit start() call.</code></p>
<p>This is due to a race condition, where the code to disable automatically running the tests is executed too late. To work around this, we load and configure QUnit before we run our RequireJS code. This results in the following, modified <code>index.html</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="cp">&lt;!DOCTYPE html&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&#34;stylesheet&#34;</span> <span class="na">href</span><span class="o">=</span><span class="s">&#34;lib/qunit-1.15.0.css&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- Include the QUnit library. Ideally, we&#39;d include this as a
</span></span></span><span class="line"><span class="cl"><span class="c">           dependency in our RequireJS main file, but, due to a race condition
</span></span></span><span class="line"><span class="cl"><span class="c">           this would fail. --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/javascript&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;lib/qunit-1.15.0.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/javascript&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="c1">// Configure QUnit to delay running the tests. We will start running
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>      <span class="c1">// the tests when they have been asynchronously loaded using RequireJS
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>      <span class="nx">QUnit</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">autoload</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="nx">QUnit</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">autostart</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- Include the RequireJS library. We supply the &#34;data-main&#34; attribute to
</span></span></span><span class="line"><span class="cl"><span class="c">           let RequireJS know which file it should load. This file (runner.js) 
</span></span></span><span class="line"><span class="cl"><span class="c">           can be seen as the entry point (main) of the application. --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">script</span> <span class="na">data-main</span><span class="o">=</span><span class="s">&#34;runner&#34;</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;lib/require.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="c">&lt;!-- These empty divs will be filled with the test results when QUnit 
</span></span></span><span class="line"><span class="cl"><span class="c">           has run its tests --&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;qunit&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;qunit-fixture&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Of course, this also means that our <code>runner.js</code> changes, as we no longer need to load QUnit from it:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// require the test modules
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">require</span><span class="p">([</span><span class="s2">&#34;tests/mathtests&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">mathTest</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// Now that we have asynchronously loaded the tests
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="c1">// we can give QUnit the signal to start running the tests
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="nx">QUnit</span><span class="p">.</span><span class="nx">load</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">  <span class="nx">QUnit</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>With the modifications, we can now run <code>grunt test</code> and our tests will correctly execute.</p>
<h3 id="example-18-plug-ins">Example 18: plug-ins</h3>
<p>RequireJS also supports plug-ins, such as the <a href="https://github.com/requirejs/text">text</a> plug-in. This plug-in allows loading text resources, such as HTML or CSS files.</p>
<p>Working with the <code>text</code> plug-in is fairly simple. First, download the <a href="https://raw.github.com/requirejs/text/latest/text.js"><code>text.js</code></a> file. We&rsquo;ll save it to <code>lib/text.js</code>. Using a plug-in is similar to working with modules. We can thus configure an explicit module ID for our <code>text</code> plug-in in our main file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">text</span><span class="o">:</span> <span class="s2">&#34;../lib/text&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Now, we can use the <code>'text'</code> module ID to call the <code>text</code> plug-in. When using the <code>text</code> plug-in, you specify the text resource to load in the module ID. You do this by appending the <code>!</code> character followed by the text resource&rsquo;s path. Here is how we use the <code>text</code> plug-in to request the <code>main.html</code> file in our <code>'app.js'</code> module:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s2">&#34;text!main.html&#34;</span><span class="p">],</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">mainHtml</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// We alert the text retrieved from the &#34;main.html&#34; file
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="nx">alert</span><span class="p">(</span><span class="nx">mainHtml</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>When this module is requested, RequireJS will load the <code>'text'</code> module. This module then loads the text resource specified in the module ID. Once the text resource has been loaded, the callback function is called with the contents of the text resource passed as the argument.</p>
<p>Note that the text resource path is relative to the base URL.</p>
<h2 id="conclusion">Conclusion</h2>
<p>RequireJS is a very useful library that fills a gap in the JavaScript language: a missing module system. Its learning curve can be steep, but when mastered you&rsquo;ll have the tools to better structure your JavaScript applications.</p>
]]></content>
		</item>
		
		<item>
			<title>Fluent interfaces</title>
			<link>https://www.erikschierboom.com/2014/10/08/fluent-interfaces/</link>
			<pubDate>Wed, 08 Oct 2014 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2014/10/08/fluent-interfaces/</guid>
			<description>Fluent interfaces are software API&amp;rsquo;s designed to be readable and to flow. They are like a miniature domain-specific language, code structured for one specific purpose.
Flow Methods in fluent interfaces can often be chained, creating a flow of method calls. To allow a method to be chained, there is but one rule:
The method must return a non-void value.
As the return type of a method determines what method can be called next, it determines its flow.</description>
			<content type="html"><![CDATA[<p>Fluent interfaces are software API&rsquo;s designed to be readable and to <em>flow</em>. They are like a miniature <a href="http://en.wikipedia.org/wiki/Domain-specific_language">domain-specific language</a>, code structured for one specific purpose.</p>
<h2 id="flow">Flow</h2>
<p>Methods in fluent interfaces can often be chained, creating a <em>flow</em> of method calls. To allow a method to be chained, there is but one rule:</p>
<blockquote>
<p>The method must return a non-void value.</p>
</blockquote>
<p>As the return type of a method determines what method can be called next, it determines its flow.</p>
<p>Consider the following, non-flowing method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">NonFlowing</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Log</span><span class="p">(</span><span class="kt">string</span> <span class="n">str</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">       <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As the <code>Log()</code> method returns <code>void</code>, there can be no chain of method calls:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">NonFlowing</span> <span class="n">nonFlowing</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NonFlowing</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Error: fails to compile</span>
</span></span><span class="line"><span class="cl"><span class="n">nonFlowing</span><span class="p">.</span><span class="n">Log</span><span class="p">(</span><span class="s">&#34;line 1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="n">Log</span><span class="p">(</span><span class="s">&#34;line 2&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="n">Log</span><span class="p">(</span><span class="s">&#34;line 3&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>We can remedy this by returning a non-void type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Flowing</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">Flowing</span> <span class="n">Log</span><span class="p">(</span><span class="kt">string</span> <span class="n">str</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">       <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">       <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This <code>Log()</code> method returns a <code>Flowing</code> instance, which methods we can call when <code>Log()</code> has finished. We can now chain calls to the <code>Log()</code> method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Flowing</span> <span class="n">flowing</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Flowing</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">flowing</span><span class="p">.</span><span class="n">Log</span><span class="p">(</span><span class="s">&#34;line 1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">       <span class="p">.</span><span class="n">Log</span><span class="p">(</span><span class="s">&#34;line 2&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">       <span class="p">.</span><span class="n">Log</span><span class="p">(</span><span class="s">&#34;line 3&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>If we change the <code>Log()</code> method&rsquo;s return type, the flow changes to that type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">FlowingContext</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">string</span> <span class="n">Log</span><span class="p">(</span><span class="kt">string</span> <span class="n">str</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">       <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">       <span class="k">return</span> <span class="n">str</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">FlowingContext</span> <span class="n">flowing</span> <span class="p">=</span> <span class="k">new</span> <span class="n">FlowingContext</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Returns &#34;LINE&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">flowing</span><span class="p">.</span><span class="n">Log</span><span class="p">(</span><span class="s">&#34;line 1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">       <span class="p">.</span><span class="n">Substring</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">       <span class="p">.</span><span class="n">ToUpper</span><span class="p">();</span>
</span></span></code></pre></div><h3 id="more-complex-flows">More complex flows</h3>
<p>Some API&rsquo;s require a more complex flow, for example to build-up a complex structure. An example of this is a SQL query. A minimal SQL query has two required parts:</p>
<ul>
<li>The <code>SELECT</code> statement, indicating which column values to return.</li>
<li>The <code>FROM</code> statement, specifying the tables from which the results are returned.</li>
</ul>
<p>However, an SQL query also has two other, optional parts:</p>
<ul>
<li>The <code>WHERE</code> statement, which determines the filtering to apply.</li>
<li>The <code>ORDER BY</code> statement, which specifies how to order the results.</li>
</ul>
<p>A basic fluent API designed to meet these criteria could look like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">BasicQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">BasicQuery</span> <span class="n">Select</span><span class="p">(</span><span class="kt">string</span> <span class="n">selectSql</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">BasicQuery</span> <span class="n">From</span><span class="p">(</span><span class="kt">string</span> <span class="n">fromSql</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">BasicQuery</span> <span class="n">Where</span><span class="p">(</span><span class="kt">string</span> <span class="n">whereSql</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">BasicQuery</span> <span class="n">OrderBy</span><span class="p">(</span><span class="kt">string</span> <span class="n">orderBySql</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">dynamic</span> <span class="n">Execute</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now use this API as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">new</span> <span class="n">BasicQuery</span><span class="p">().</span><span class="n">Select</span><span class="p">(</span><span class="s">&#34;*&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">From</span><span class="p">(</span><span class="s">&#34;users&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="s">&#34;name = &#39;Shaq&#39;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">OrderBy</span><span class="p">(</span><span class="s">&#34;age&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span></code></pre></div><p>Although this works fine, we can still use this API in strange and incorrect ways:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="c1">// 1. Weird order</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="n">BasicQuery</span><span class="p">().</span><span class="n">OrderBy</span><span class="p">(</span><span class="s">&#34;age&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">From</span><span class="p">(</span><span class="s">&#34;users&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">Select</span><span class="p">(</span><span class="s">&#34;*&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 2. Missing required SELECT and FROM parts</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="n">BasicQuery</span><span class="p">().</span><span class="n">Where</span><span class="p">(</span><span class="s">&#34;name = &#39;Shaq&#39;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">OrderBy</span><span class="p">(</span><span class="s">&#34;age&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span></code></pre></div><p>What we want is two things:</p>
<ol>
<li>Force the method calls order to: <code>Select()</code>, <code>From()</code>, <code>Where()</code> and <code>OrderBy()</code>.</li>
<li>Only allow a query to be executed when, at least, <code>Select()</code> and <code>From()</code> were called.</li>
</ol>
<p>We can visualize these requirements in a state diagram:</p>
<p><img src="/images/posts/fluent-interfaces-states.png" alt="Fluent interface state diagram"></p>
<p>Let&rsquo;s start with the first requirement. We can force the order by creating an interface for each state, each of which has a method to move to the next state:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">ISelectQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">IFromQuery</span> <span class="n">From</span><span class="p">(</span><span class="kt">string</span> <span class="n">fromSql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">IFromQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">IWhereQuery</span> <span class="n">Where</span><span class="p">(</span><span class="kt">string</span> <span class="n">whereSql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">IOrderByQuery</span> <span class="n">OrderBy</span><span class="p">(</span><span class="kt">string</span> <span class="n">orderBySql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">IWhereQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">IOrderByQuery</span> <span class="n">OrderBy</span><span class="p">(</span><span class="kt">string</span> <span class="n">orderBySql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">IOrderByQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we start with an <code>ISelectQuery</code> instance, the method calls are always in our desired order:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">ISelectQuery</span> <span class="n">selectQuery</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">IFromQuery</span> <span class="n">fromQuery</span> <span class="p">=</span> <span class="n">selectQuery</span><span class="p">.</span><span class="n">From</span><span class="p">(</span><span class="s">&#34;users&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">IWhereQuery</span> <span class="n">whereQuery</span> <span class="p">=</span> <span class="n">fromQuery</span><span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="s">&#34;name = &#39;Shaq&#39;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">IOrderByQuery</span> <span class="n">orderByQuery</span> <span class="p">=</span> <span class="n">whereQuery</span><span class="p">.</span><span class="n">OrderBy</span><span class="p">(</span><span class="s">&#34;age&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>And only valid state transitions are allowed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="c1">// Compiler error</span>
</span></span><span class="line"><span class="cl"><span class="n">selectQuery</span><span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="s">&#34;name = &#39;Shaq&#39;&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">selectQuery</span><span class="p">.</span><span class="n">OrderBy</span><span class="p">(</span><span class="s">&#34;age&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>We can solve our second requirement by adding an interface for an executable query. We add this interface to each executable state&rsquo;s interface:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">IExecutableQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">dynamic</span> <span class="n">Execute</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">ISelectQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">IFromQuery</span> <span class="n">From</span><span class="p">(</span><span class="kt">string</span> <span class="n">fromSql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">IFromQuery</span> <span class="p">:</span> <span class="n">IExecutableQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">IWhereQuery</span> <span class="n">Where</span><span class="p">(</span><span class="kt">string</span> <span class="n">whereSql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">IOrderByQuery</span> <span class="n">OrderBy</span><span class="p">(</span><span class="kt">string</span> <span class="n">orderBySql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">IWhereQuery</span> <span class="p">:</span> <span class="n">IExecutableQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">IOrderByQuery</span> <span class="n">OrderBy</span><span class="p">(</span><span class="kt">string</span> <span class="n">orderBySql</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">interface</span> <span class="nc">IOrderByQuery</span> <span class="p">:</span> <span class="n">IExecutableQuery</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We have now ensured that all states except the <code>SELECT</code> state can be executed:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="c1">// Valid calls</span>
</span></span><span class="line"><span class="cl"><span class="n">fromQuery</span><span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="n">whereQuery</span><span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="n">orderByQuery</span><span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Compiler error</span>
</span></span><span class="line"><span class="cl"><span class="n">selectQuery</span><span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span></code></pre></div><p>Ignoring the implementation of the state interfaces, we can create a class <code>Query</code> to start the flow with:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">Query</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">ISelectQuery</span> <span class="n">Select</span><span class="p">(</span><span class="kt">string</span> <span class="n">selectSql</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">...</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Our API is now done and can be called like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Query</span><span class="p">.</span><span class="n">Select</span><span class="p">(</span><span class="s">&#34;*&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">     <span class="p">.</span><span class="n">From</span><span class="p">(</span><span class="s">&#34;users&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">     <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="s">&#34;name = &#39;Shaq&#39;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">     <span class="p">.</span><span class="n">OrderBy</span><span class="p">(</span><span class="s">&#34;age&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">     <span class="p">.</span><span class="n">Execute</span><span class="p">();</span>
</span></span></code></pre></div><h2 id="readability">Readability</h2>
<p>When designing fluent interfaces, it is very important to design for readability. Here are some examples.</p>
<h3 id="getters-and-setters">Getters and setters</h3>
<p>Take the following class with two flowing <em>setter</em> methods:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Player</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">Player</span> <span class="n">SetName</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">Player</span> <span class="n">SetAge</span><span class="p">(</span><span class="kt">int</span> <span class="n">age</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we want to create a new <code>Player</code> instance and set its name and age, we can do that as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Player</span> <span class="n">player</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Player</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="n">player</span><span class="p">.</span><span class="n">SetName</span><span class="p">(</span><span class="s">&#34;LeBron James&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="n">SetAge</span><span class="p">(</span><span class="m">27</span><span class="p">);</span>
</span></span></code></pre></div><p>The setters allow for a nice flow, but consider the following alternative:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">AlternativePlayer</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">AlternativePlayer</span> <span class="n">WithName</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">AlternativePlayer</span> <span class="n">WithAge</span><span class="p">(</span><span class="kt">int</span> <span class="n">age</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now create a new instance as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">AlternativePlayer</span> <span class="n">player</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AlternativePlayer</span><span class="p">().</span><span class="n">WithName</span><span class="p">(</span><span class="s">&#34;LeBron James&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                                  <span class="p">.</span><span class="n">WithAge</span><span class="p">(</span><span class="m">27</span><span class="p">);</span>
</span></span></code></pre></div><p>To me, this code has slightly better readability as its reads more like a sentence than the previous example. However, it comes at the cost of reduced discoverability as setter methods are usually prefixed with &ldquo;Set&rdquo;.</p>
<p>Another alternative would be to use a factory method to create new instances:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">FactoryPlayer</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">FactoryPlayer</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">FactoryPlayer</span> <span class="n">WithName</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">FactoryPlayer</span> <span class="n">WithAge</span><span class="p">(</span><span class="kt">string</span> <span class="n">age</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">FactoryPlayer</span> <span class="n">Create</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="k">new</span> <span class="n">FactoryPlayer</span><span class="p">();</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now create a new instance as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">FactoryPlayer</span> <span class="n">player</span> <span class="p">=</span> <span class="n">FactoryPlayer</span><span class="p">.</span><span class="n">Create</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">.</span><span class="n">WithName</span><span class="p">(</span><span class="s">&#34;LeBron James&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                                    <span class="p">.</span><span class="n">WithAge</span><span class="p">(</span><span class="m">27</span><span class="p">);</span>
</span></span></code></pre></div><p>In C#, we would probably use properties instead of setters and getters:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">PropertiesPlayer</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">string</span> <span class="n">Name</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Age</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">PropertiesPlayer</span> <span class="n">player</span> <span class="p">=</span> <span class="k">new</span> <span class="n">PropertiesPlayer</span> <span class="p">{</span> <span class="n">Name</span> <span class="p">=</span> <span class="s">&#34;LeBron James&#34;</span><span class="p">,</span> <span class="n">Age</span> <span class="p">=</span> <span class="m">27</span> <span class="p">};</span>
</span></span></code></pre></div><p>This looks good from a readability viewpoint, but limits your flow options as the type returned from the getters and setters cannot be different from the property type.</p>
<h3 id="higher-level-functions">Higher level functions</h3>
<p>Sometimes, a class has several lower level properties or functions that are often modified together. In those cases, readability can be improved by providing higher level abstractions. Take the following example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Window</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">IsTranslucent</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">OpacityPercentage</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Suppose we support two use cases: setting the window to be opaque (opacity percentage equal to 100) and setting the window to be translucent (opacity percentage less than 100). This can be done as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Window</span> <span class="n">window</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Window</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 1. opaque</span>
</span></span><span class="line"><span class="cl"><span class="n">window</span><span class="p">.</span><span class="n">IsTranslucent</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">window</span><span class="p">.</span><span class="n">OpacityPercentage</span> <span class="p">=</span> <span class="m">100</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 2. translucent</span>
</span></span><span class="line"><span class="cl"><span class="n">window</span><span class="p">.</span><span class="n">IsTranslucent</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">window</span><span class="p">.</span><span class="n">OpacityPercentage</span> <span class="p">=</span> <span class="m">50</span><span class="p">;</span>
</span></span></code></pre></div><p>Although this code seem pretty straightforward, it is easy to make the following mistake:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Window</span> <span class="n">window</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Window</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="n">window</span><span class="p">.</span><span class="n">IsTranslucent</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Forgot to set the opacity percentage!</span>
</span></span></code></pre></div><p>The following example does a much better job of explaining what the class can do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Window</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">IsTransparent</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">Opacity</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">MakeOpaque</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">IsTransparent</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">Opacity</span> <span class="p">=</span> <span class="m">100</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">MakeTransparent</span><span class="p">(</span><span class="kt">float</span> <span class="n">opacity</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">IsTransparent</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">Opacity</span> <span class="p">=</span> <span class="n">opacity</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This class shows its capabilities better and prevents the mistake mentioned earlier:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Window</span> <span class="n">window</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Window</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 1. opaque</span>
</span></span><span class="line"><span class="cl"><span class="n">window</span><span class="p">.</span><span class="n">MakeOpaque</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 2. translucent</span>
</span></span><span class="line"><span class="cl"><span class="n">window</span><span class="p">.</span><span class="n">MakeTransparent</span><span class="p">(</span><span class="m">50</span><span class="p">);</span>
</span></span></code></pre></div><h3 id="pre-populated-fields">Pre-populated fields</h3>
<p>In some cases, you can expect your code to be often called with a specific set of parameters. In this case, it can be convenient to provide a pre-populated instance with that set of parameters.</p>
<p>Consider the following class to filter a population:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">PopulationFilter</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">MinimumAge</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">MaximumAge</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If you know that users of your API will often filter out <a href="http://en.wikipedia.org/wiki/Toddler">toddlers</a>, you could add a pre-populated field:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">PopulationFilter</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">PopulationFilter</span> <span class="n">Toddlers</span> <span class="p">=</span> <span class="k">new</span> <span class="n">PopulationFilter</span>
</span></span><span class="line"><span class="cl">                                                    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                                                        <span class="n">MinimumAge</span> <span class="p">=</span> <span class="m">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                                        <span class="n">MaximumAge</span> <span class="p">=</span> <span class="m">2</span>
</span></span><span class="line"><span class="cl">                                                    <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">MinimumAge</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">MaximumAge</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Users can now easily filter on toddlers using <code>PopulationFilter.Toddlers</code>.</p>
<p>These examples show that simple refactorings can greatly influence readability. When developing a fluent API, one should try different API designs to find the one with the best readability.</p>
<h2 id="creating-a-fluent-api">Creating a fluent API</h2>
<p>With all that we now know about designing fluent API&rsquo;s, let&rsquo;s try to create one from scratch. Our goal is to create an image processor that can do some basic image transformations and save the result to a file.</p>
<p>Often, it is best to start with writing code how you&rsquo;d <em>want</em> to be calling the fluent API. Experiment with different options to see what works best.</p>
<p>Say we came up with this design:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">ImageProcessor</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="s">@&#34;c:\input.png&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Rotate</span><span class="p">(</span><span class="n">Degrees</span><span class="p">.</span><span class="n">FromAngle</span><span class="p">(</span><span class="m">90</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Save</span><span class="p">(</span><span class="s">@&#34;c:\output1.png&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">ImageProcessor</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="s">@&#34;c:\input.png&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Scale</span><span class="p">(</span><span class="n">Scale</span><span class="p">.</span><span class="n">Half</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Save</span><span class="p">(</span><span class="s">@&#34;c:\output2.png&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">ImageProcessor</span><span class="p">.</span><span class="n">FromImage</span><span class="p">(</span><span class="n">Image</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="s">@&#34;c:\input.png&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Scale</span><span class="p">(</span><span class="n">Scale</span><span class="p">.</span><span class="n">FromPercentage</span><span class="p">(</span><span class="m">75</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Rotate</span><span class="p">(</span><span class="n">Degrees</span><span class="p">.</span><span class="n">FromAngle</span><span class="p">(</span><span class="m">45</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Save</span><span class="p">(</span><span class="s">@&#34;c:\output3.png&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>Even if you would not know the API that is used, you&rsquo;d probably have a good idea of what this code does. Let start building it!</p>
<p>In our API design, we opted for factory methods instead of constructors, resulting in this class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">ImageProcessor</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="k">readonly</span> <span class="n">Image</span> <span class="n">image</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">ImageProcessor</span><span class="p">(</span><span class="n">Image</span> <span class="n">image</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">image</span> <span class="p">=</span> <span class="n">image</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">ImageProcessor</span> <span class="n">FromFile</span><span class="p">(</span><span class="kt">string</span> <span class="n">fileName</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">ImageProcessor</span><span class="p">(</span><span class="n">Image</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="n">fileName</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">ImageProcessor</span> <span class="n">FromImage</span><span class="p">(</span><span class="n">Image</span> <span class="n">image</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">ImageProcessor</span><span class="p">(</span><span class="n">image</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This allows us to do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">processorFromFile</span> <span class="p">=</span> <span class="n">ImageProcessor</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="s">@&#34;c:\input.png&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">processorFromImage</span> <span class="p">=</span> <span class="n">ImageProcessor</span><span class="p">.</span><span class="n">FromImage</span><span class="p">(</span><span class="k">new</span> <span class="n">Bitmap</span><span class="p">(</span><span class="m">100</span><span class="p">,</span> <span class="m">100</span><span class="p">));</span>
</span></span></code></pre></div><p>The next step is to add the transformation methods:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">ImageProcessor</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ImageProcessor</span> <span class="n">Rotate</span><span class="p">(</span><span class="n">Degrees</span> <span class="n">degrees</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">graphics</span> <span class="p">=</span> <span class="n">Graphics</span><span class="p">.</span><span class="n">FromImage</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">image</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">graphics</span><span class="p">.</span><span class="n">RotateTransform</span><span class="p">(</span><span class="n">degrees</span><span class="p">.</span><span class="n">Angle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ImageProcessor</span> <span class="n">Scale</span><span class="p">(</span><span class="n">Scale</span> <span class="n">scale</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">graphics</span> <span class="p">=</span> <span class="n">Graphics</span><span class="p">.</span><span class="n">FromImage</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">image</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">graphics</span><span class="p">.</span><span class="n">ScaleTransform</span><span class="p">(</span><span class="n">scale</span><span class="p">.</span><span class="n">ScaleFactorX</span><span class="p">,</span> <span class="n">scale</span><span class="p">.</span><span class="n">ScaleFactorY</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The implementation of these methods is straightforward, but now we need to define the <code>Degrees</code> and <code>Scale</code> classes. If we look back at our API design, the <code>Degrees</code> instance is created as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Degrees</span><span class="p">.</span><span class="n">FromAngle</span><span class="p">(</span><span class="m">90</span><span class="p">)</span>
</span></span></code></pre></div><p>Once again, can define a factory method to create new instances:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Degrees</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">Degrees</span><span class="p">(</span><span class="kt">float</span> <span class="n">angle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">Angle</span> <span class="p">=</span> <span class="n">angle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">Angle</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">Degrees</span> <span class="n">FromAngle</span><span class="p">(</span><span class="kt">float</span> <span class="n">angle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">Degrees</span><span class="p">(</span><span class="n">angle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The <code>Scale</code> class is similar:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Scale</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">Scale</span><span class="p">(</span><span class="kt">float</span> <span class="n">scaleFactorX</span><span class="p">,</span> <span class="kt">float</span> <span class="n">scaleFactorY</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">ScaleFactorX</span> <span class="p">=</span> <span class="n">scaleFactorX</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">ScaleFactorY</span> <span class="p">=</span> <span class="n">scaleFactorY</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">ScaleFactorX</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">ScaleFactorY</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">Scale</span> <span class="n">FromPercentage</span><span class="p">(</span><span class="kt">float</span> <span class="n">percentage</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">Scale</span><span class="p">(</span><span class="n">percentage</span> <span class="p">/</span> <span class="m">100.0f</span><span class="p">,</span>  <span class="n">percentage</span> <span class="p">/</span> <span class="m">100.0f</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>In our API design, we used <code>Scale.Half</code> as a shortcut for scaling images to half their size. For this, we add a public (readonly) instance of the <code>Scale</code> class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Scale</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="k">readonly</span> <span class="n">Scale</span> <span class="n">Half</span> <span class="p">=</span> <span class="n">Scale</span><span class="p">.</span><span class="n">FromPercentage</span><span class="p">(</span><span class="m">50.0f</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The final step is to add the <code>Save()</code> method, which is the logical end of the image processing:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">ImageProcessor</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Save</span><span class="p">(</span><span class="kt">string</span> <span class="n">fileName</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">image</span><span class="p">.</span><span class="n">Save</span><span class="p">(</span><span class="n">fileName</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>As this method should be the last method called in a method chain, it returns <code>void</code>.</p>
<p>The final fluent API implementation is as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">ImageProcessor</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="k">readonly</span> <span class="n">Image</span> <span class="n">image</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">ImageProcessor</span><span class="p">(</span><span class="n">Image</span> <span class="n">image</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">image</span> <span class="p">=</span> <span class="n">image</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">ImageProcessor</span> <span class="n">FromFile</span><span class="p">(</span><span class="kt">string</span> <span class="n">fileName</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">ImageProcessor</span><span class="p">(</span><span class="n">Image</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="n">fileName</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">ImageProcessor</span> <span class="n">FromImage</span><span class="p">(</span><span class="n">Image</span> <span class="n">image</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">ImageProcessor</span><span class="p">(</span><span class="n">image</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ImageProcessor</span> <span class="n">Rotate</span><span class="p">(</span><span class="n">Degrees</span> <span class="n">degrees</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">graphics</span> <span class="p">=</span> <span class="n">Graphics</span><span class="p">.</span><span class="n">FromImage</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">image</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">graphics</span><span class="p">.</span><span class="n">RotateTransform</span><span class="p">(</span><span class="n">degrees</span><span class="p">.</span><span class="n">Angle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ImageProcessor</span> <span class="n">Scale</span><span class="p">(</span><span class="n">Scale</span> <span class="n">scale</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">graphics</span> <span class="p">=</span> <span class="n">Graphics</span><span class="p">.</span><span class="n">FromImage</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">image</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">graphics</span><span class="p">.</span><span class="n">ScaleTransform</span><span class="p">(</span><span class="n">scale</span><span class="p">.</span><span class="n">ScaleFactorX</span><span class="p">,</span> <span class="n">scale</span><span class="p">.</span><span class="n">ScaleFactorY</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Save</span><span class="p">(</span><span class="kt">string</span> <span class="n">fileName</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">image</span><span class="p">.</span><span class="n">Save</span><span class="p">(</span><span class="n">fileName</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Degrees</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">Degrees</span><span class="p">(</span><span class="kt">float</span> <span class="n">angle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">Angle</span> <span class="p">=</span> <span class="n">angle</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">Angle</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">Degrees</span> <span class="n">FromAngle</span><span class="p">(</span><span class="kt">float</span> <span class="n">angle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">Degrees</span><span class="p">(</span><span class="n">angle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">Scale</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="k">readonly</span> <span class="n">Scale</span> <span class="n">Half</span> <span class="p">=</span> <span class="n">Scale</span><span class="p">.</span><span class="n">FromPercentage</span><span class="p">(</span><span class="m">50.0f</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">Scale</span><span class="p">(</span><span class="kt">float</span> <span class="n">scaleFactorX</span><span class="p">,</span> <span class="kt">float</span> <span class="n">scaleFactorY</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">ScaleFactorX</span> <span class="p">=</span> <span class="n">scaleFactorX</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">ScaleFactorY</span> <span class="p">=</span> <span class="n">scaleFactorY</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">ScaleFactorX</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">float</span> <span class="n">ScaleFactorY</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="kd">private</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">Scale</span> <span class="n">FromPercentage</span><span class="p">(</span><span class="kt">float</span> <span class="n">percentage</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">Scale</span><span class="p">(</span><span class="n">percentage</span> <span class="p">/</span> <span class="m">100.0f</span><span class="p">,</span>  <span class="n">percentage</span> <span class="p">/</span> <span class="m">100.0f</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="code-complexity">Code complexity</h3>
<p>The amount of code in this example shows that fluent API&rsquo;s often need quite a lot of code. This is in part due to us implementing the API in C#. The Objective-C language, for example, requires parameter names to always be explicitly passed. This is ideal for fluent API&rsquo;s, as function calls are thus more explicit and you have less need of factory methods to make things explicit.</p>
<p>In C#, you can also pass parameters by name. If we were to take advantage of this feature, we could rewrite our <code>Rotate()</code> method to:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="n">ImageProcessor</span> <span class="n">Rotate</span><span class="p">(</span><span class="kt">float</span> <span class="n">angle</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">using</span> <span class="p">(</span><span class="kt">var</span> <span class="n">graphics</span> <span class="p">=</span> <span class="n">Graphics</span><span class="p">.</span><span class="n">FromImage</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">image</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">graphics</span><span class="p">.</span><span class="n">RotateTransform</span><span class="p">(</span><span class="n">angle</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can then call this method as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">ImageProcessor</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="s">@&#34;c:\input.png&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Rotate</span><span class="p">(</span><span class="n">angle</span><span class="p">:</span> <span class="m">90</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Save</span><span class="p">(</span><span class="s">@&#34;c:\output1.png&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>This example is just as clear as the one with the <code>Degrees</code> class, but with less code. Unfortunately, it is also possible to call <code>Rotate()</code> without its parameter name, which greatly lessens its readability:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">ImageProcessor</span><span class="p">.</span><span class="n">FromFile</span><span class="p">(</span><span class="s">@&#34;c:\input.png&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Rotate</span><span class="p">(</span><span class="m">90</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">              <span class="p">.</span><span class="n">Save</span><span class="p">(</span><span class="s">@&#34;c:\output1.png&#34;</span><span class="p">);</span>
</span></span></code></pre></div><p>The design of a fluent API is thus also influenced by the language used.</p>
<h2 id="examples">Examples</h2>
<p>If you are designing a fluent API, it is useful to look at existing fluent API designs. Here are some good examples:</p>
<h4 id="jquery">jQuery</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="err">$</span><span class="p">(</span><span class="s">&#34;#p1&#34;</span><span class="p">).</span><span class="n">css</span><span class="p">(</span><span class="s">&#34;color&#34;</span><span class="p">,</span> <span class="s">&#34;red&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">.</span><span class="n">slideUp</span><span class="p">(</span><span class="m">2000</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">.</span><span class="n">slideDown</span><span class="p">(</span><span class="m">2000</span><span class="p">);</span>
</span></span></code></pre></div><h4 id="linq-net">LINQ (.NET)</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Enumerable</span><span class="p">.</span><span class="n">Range</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="m">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">n</span> <span class="p">=&gt;</span> <span class="n">n</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="n">OrderByDescending</span><span class="p">(</span><span class="n">n</span> <span class="p">=&gt;</span> <span class="n">n</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">.</span><span class="n">ToArray</span><span class="p">();</span>
</span></span></code></pre></div><h4 id="easymock-java">EasyMock (Java):</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="n">expect</span><span class="o">(</span><span class="n">mock</span><span class="o">.</span><span class="na">voteForRemoval</span><span class="o">(</span><span class="s">&#34;Document&#34;</span><span class="o">))</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="na">andReturn</span><span class="o">(</span><span class="mi">42</span><span class="o">).</span><span class="na">times</span><span class="o">(</span><span class="mi">3</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="na">andThrow</span><span class="o">(</span><span class="k">new</span> <span class="n">RuntimeException</span><span class="o">(),</span> <span class="mi">4</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">.</span><span class="na">andReturn</span><span class="o">(-</span><span class="mi">42</span><span class="o">);</span>
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Designing a good fluent API is not as easy as simply returning <code>this</code> from your methods. Readability is a key aspect of fluent API&rsquo;s and that requires you to pay attention to how you name and structure your code. Implementing a fluent API will also most likely increase the complexity of your code. However, when properly designed, fluent API&rsquo;s have great discoverability and improve the readability of the code.</p>
]]></content>
		</item>
		
		<item>
			<title>Numbers and culture</title>
			<link>https://www.erikschierboom.com/2014/09/01/numbers-and-culture/</link>
			<pubDate>Mon, 01 Sep 2014 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2014/09/01/numbers-and-culture/</guid>
			<description>Converting a string to a number is a common use case. This C# code converts a string to a double:
string numberString = &amp;#34;25.78&amp;#34;; double number = double.Parse(numberString); However, there is a potential bug in this code, can you spot it? If not, try to run the following code:
Thread.CurrentThread.CurrentCulture = new CultureInfo(&amp;#34;es&amp;#34;); string numberString = &amp;#34;25.78&amp;#34;; double number = double.Parse(numberString); You&amp;rsquo;ll see that the Parse() call throws a FormatException. This is due to the current culture (Spanish) using the &amp;quot;,&amp;quot; string as the decimal separator, whereas the string being parsed uses the &amp;quot;.</description>
			<content type="html"><![CDATA[<p>Converting a string to a number is a common use case. This C# code converts a string to a double:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25.78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="kt">double</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">numberString</span><span class="p">);</span>
</span></span></code></pre></div><p>However, there is a potential bug in this code, can you spot it? If not, try to run the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Thread</span><span class="p">.</span><span class="n">CurrentThread</span><span class="p">.</span><span class="n">CurrentCulture</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;es&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25.78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="kt">double</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">numberString</span><span class="p">);</span>
</span></span></code></pre></div><p>You&rsquo;ll see that the <code>Parse()</code> call throws a <code>FormatException</code>. This is due to the current culture (Spanish) using the <code>&quot;,&quot;</code> string as the decimal separator, whereas the string being parsed uses the <code>&quot;.&quot;</code> string.</p>
<p>There are two ways to solve this problem:</p>
<ol>
<li>Fix it for <em>all</em> <code>Parse()</code> calls by setting the current culture to one with the correct number format.</li>
<li>Fix it for each <code>Parse()</code> call individually by using an overload that lets you specify the culture to use.</li>
</ol>
<p>Although the first option might be tempting, one has to be very careful with this method as the current culture is used in more than just the parse methods. An example of this is the <code>ToString()</code> method, which also uses the current culture to determine its output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Thread</span><span class="p">.</span><span class="n">CurrentThread</span><span class="p">.</span><span class="n">CurrentCulture</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;en&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="m">25.78</span><span class="p">.</span><span class="n">ToString</span><span class="p">();</span> <span class="c1">// Returns &#34;25.78&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Thread</span><span class="p">.</span><span class="n">CurrentThread</span><span class="p">.</span><span class="n">CurrentCulture</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;es&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="m">25.78</span><span class="p">.</span><span class="n">ToString</span><span class="p">();</span> <span class="c1">// Returns &#34;25,78&#34;</span>
</span></span></code></pre></div><p>Unless you are sure you want to change the culture for all methods, the second option is thus more safe:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25,78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="kt">double</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">numberString</span><span class="p">,</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;es&#34;</span><span class="p">));</span>
</span></span></code></pre></div><h2 id="invariant-culture">Invariant culture</h2>
<p>With what we know now, you probably expect this code to be correct:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25.78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="kt">double</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">numberString</span><span class="p">,</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;en&#34;</span><span class="p">));</span>
</span></span></code></pre></div><p>Unfortunately, you would be wrong. The problem is that cultures are not fixed; they are subject to user modification and updates to the .NET framework or operating system. On systems where the decimal separator for the English culture was changed, the above code would throw a <code>FormatException</code>.</p>
<p>Luckily, the .NET framework contains a predefined culture that is almost identical to the English culture but is <em>not</em> subject to modification. This culture is known as the <em>invariant</em> culture, and can be used through the <a href="http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.invariantculture(v=vs.110).aspx"><code>CultureInfo.InvariantCulture</code></a> property.</p>
<p>As the invariant culture is guaranteed to use the <code>&quot;.&quot;</code> string as its decimal separator, we can fix our bug:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25.78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="kt">double</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">numberString</span><span class="p">,</span> <span class="n">CultureInfo</span><span class="p">.</span><span class="n">InvariantCulture</span><span class="p">);</span>
</span></span></code></pre></div><p>This code works on every system, no matter what changes were made to its configuration.</p>
<h2 id="retrieving-the-number-format">Retrieving the number format</h2>
<p>The decimal separator string used by a culture can be found by accessing its <code>NumberFormat.NumberDecimalSeparator</code> property:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="c1">// Returns: &#34;.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;en&#34;</span><span class="p">).</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberDecimalSeparator</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Returns: &#34;,&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;es&#34;</span><span class="p">).</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberDecimalSeparator</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Returns: &#34;.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">CultureInfo</span><span class="p">.</span><span class="n">InvariantCulture</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberDecimalSeparator</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Returns: &#34;&lt;depends on the current culture&gt;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">CultureInfo</span><span class="p">.</span><span class="n">CurrentCulture</span><span class="p">.</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberDecimalSeparator</span><span class="p">;</span>
</span></span></code></pre></div><p>The <code>NumberFormat</code> property also exposes other number related values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="c1">// Returns: &#34;$&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;en&#34;</span><span class="p">).</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">CurrencySymbol</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Returns: &#34;Infinito&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;es&#34;</span><span class="p">).</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">PositiveInfinitySymbol</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Returns: 2</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;fr&#34;</span><span class="p">).</span><span class="n">NumberFormat</span><span class="p">.</span><span class="n">NumberDecimalDigits</span><span class="p">;</span>
</span></span></code></pre></div><p>You can thus check a culture&rsquo;s number format at runtime. Note that the examples above asume an unmodified culture.</p>
<h2 id="defining-your-own-number-format">Defining your own number format</h2>
<p>When we passed a <code>CultureInfo</code> instance to our parse method, we were calling an overload that takes an <a href="http://msdn.microsoft.com/en-us/library/system.iformatprovider(v=vs.110).aspx"><code>IFormatProvider</code></a> instance. Interestingly, the culture&rsquo;s <code>NumberFormat</code> property is of type <code>NumberFormatInfo</code> which <em>also</em> implements <code>IFormatProvider</code>. This means that instead of supplying a culture, you could also pass its <code>NumberFormat</code> property to the parse methods:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25.78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="kt">double</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">numberString</span><span class="p">,</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;en&#34;</span><span class="p">).</span><span class="n">NumberFormat</span><span class="p">);</span>
</span></span></code></pre></div><p>The nice thing about the <code>NumberFormatInfo</code> type is that is easy to customize. Here we create a number format where the <code>&quot;#&quot;</code> string serves as the decimal separator:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">numberFormatInfo</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NumberFormatInfo</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="n">numberFormatInfo</span><span class="p">.</span><span class="n">NumberDecimalSeparator</span> <span class="p">=</span> <span class="s">&#34;#&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25#78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// This will correctly parse the number string to a double</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="kt">double</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">numberString</span><span class="p">,</span> <span class="n">numberFormatInfo</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">25.78</span><span class="p">.</span><span class="n">ToString</span><span class="p">(</span><span class="n">numberFormatInfo</span><span class="p">);</span> <span class="c1">// Returns &#34;25#78&#34;</span>
</span></span></code></pre></div><p>This approach gives your total freedom on which format to use for parsing and formatting numbers.</p>
<h2 id="temporarily-changing-culture">Temporarily changing culture</h2>
<p>If you want a block of code to execute using a different culture, the simple option is to store the current culture, set the new culture and finally restore the culture to its original value. This helper class makes changing the culture for a code block easy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">CultureScope</span> <span class="p">:</span> <span class="n">IDisposable</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="k">readonly</span> <span class="n">CultureInfo</span> <span class="n">originalCulture</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">CultureScope</span><span class="p">(</span><span class="kt">string</span> <span class="n">culture</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">this</span><span class="p">.</span><span class="n">originalCulture</span> <span class="p">=</span> <span class="n">Thread</span><span class="p">.</span><span class="n">CurrentThread</span><span class="p">.</span><span class="n">CurrentCulture</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Thread</span><span class="p">.</span><span class="n">CurrentThread</span><span class="p">.</span><span class="n">CurrentCulture</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="n">culture</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Dispose</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Thread</span><span class="p">.</span><span class="n">CurrentThread</span><span class="p">.</span><span class="n">CurrentCulture</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">originalCulture</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can now use this class as follows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Thread</span><span class="p">.</span><span class="n">CurrentThread</span><span class="p">.</span><span class="n">CurrentCulture</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;en&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Current culture is now English</span>
</span></span><span class="line"><span class="cl"><span class="m">25.78</span><span class="p">.</span><span class="n">ToString</span><span class="p">();</span> <span class="c1">// Returns &#34;25.78&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="p">(</span><span class="n">CultureScope</span> <span class="n">cultureScope</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CultureScope</span><span class="p">(</span><span class="s">&#34;es&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// All code executed in this block uses the Spanish culture</span>
</span></span><span class="line"><span class="cl">    <span class="m">25.78</span><span class="p">.</span><span class="n">ToString</span><span class="p">();</span> <span class="c1">// Returns &#34;25,78&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Current culture is once again English</span>
</span></span><span class="line"><span class="cl"><span class="m">25.78</span><span class="p">.</span><span class="n">ToString</span><span class="p">();</span> <span class="c1">// Returns &#34;25.78&#34;</span>
</span></span></code></pre></div><p>The trick we use is to have the <code>CultureScope</code> class implement <code>IDisposable</code>. This allows us to take advantage of the <code>using</code> keyword, which guarantees that at the end of its scope the <code>Dispose()</code> method is called, where the culture is restored to its original value.</p>
<h2 id="convert-methods">Convert methods</h2>
<p>In this article, we have focused on the <code>Parse()</code> method defined on the number types themselves. There is another common way to convert a string to a number, which is to use the <code>Convert</code> class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25.78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToDouble</span><span class="p">(</span><span class="n">numberString</span><span class="p">);</span>
</span></span></code></pre></div><p>Everything we have learned about cultures and the <code>Parse()</code> methods also applies to the <code>Convert</code> methods. Thus, the <code>Convert</code> methods also use the current culture when converting numbers and they also have overloads that take an <code>IFormatProvider</code> instance:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">numberString</span> <span class="p">=</span> <span class="s">&#34;25,78&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">double</span> <span class="n">number</span> <span class="p">=</span> <span class="n">Convert</span><span class="p">.</span><span class="n">ToDouble</span><span class="p">(</span><span class="n">numberString</span><span class="p">,</span> <span class="k">new</span> <span class="n">CultureInfo</span><span class="p">(</span><span class="s">&#34;es&#34;</span><span class="p">));</span>
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Converting strings to numbers and vice versa is a common use case. It is therefore important to know the potential pitfalls when dealing with cultures. Luckily, explicitly providing the culture is a simple solution to this problem, especially with the convenient invariant culture.</p>
]]></content>
		</item>
		
		<item>
			<title>Being lazy</title>
			<link>https://www.erikschierboom.com/2014/08/16/being-lazy/</link>
			<pubDate>Sat, 16 Aug 2014 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2014/08/16/being-lazy/</guid>
			<description>When optimizing software, code that is never executed can of course be removed. But how to optimize code that is used sometimes, but not all the time? Ideally, you&amp;rsquo;d only run that code when you need it; this is called lazy-loading or lazy-initialization.
Here is a sample that shows a naive loading strategy:
public class NaiveLoading { private int naiveResult = Calculate(); public int Result { get { return naiveResult; } } } // The result will be calculated when the instance is created, // even though we might never access the Result property var naiveLoading = new NaiveLoading(); A less naive solution would be to move the calculation to the Result property:</description>
			<content type="html"><![CDATA[<p>When optimizing software, code that is never executed can of course be removed. But how to optimize code that is used sometimes, but not all the time? Ideally, you&rsquo;d only run that code when you need it; this is called <a href="http://en.wikipedia.org/wiki/Lazy_loading"><em>lazy-loading</em></a> or <em>lazy-initialization</em>.</p>
<p>Here is a sample that shows a naive loading strategy:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">NaiveLoading</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">int</span> <span class="n">naiveResult</span> <span class="p">=</span> <span class="n">Calculate</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Result</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">naiveResult</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// The result will be calculated when the instance is created,</span>
</span></span><span class="line"><span class="cl"><span class="c1">// even though we might never access the Result property</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">naiveLoading</span> <span class="p">=</span> <span class="k">new</span> <span class="n">NaiveLoading</span><span class="p">();</span>
</span></span></code></pre></div><p>A less naive solution would be to move the calculation to the <code>Result</code> property:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">LessNaiveLoading</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Result</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Calculate</span><span class="p">();</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// This will NOT calculate the result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">lessNaiveLoading</span> <span class="p">=</span> <span class="k">new</span> <span class="n">LessNaiveLoading</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// First time calling will calculate result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">result1</span> <span class="p">=</span> <span class="n">lessNaiveLoading</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Second time calling will re-calculate result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">result2</span> <span class="p">=</span> <span class="n">lessNaiveLoading</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
</span></span></code></pre></div><p>We now only calculate the result when needed, but we do it every single time <code>Result</code> is accessed, which our naive example did not. The following example combines the best of both methods:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">LazyLoading</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">int?</span> <span class="n">lazyResult</span> <span class="p">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Result</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">lazyResult</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">lazyResult</span> <span class="p">=</span> <span class="n">Calculate</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">lazyResult</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// This will NOT calculate the result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">lazyLoading</span> <span class="p">=</span> <span class="k">new</span> <span class="n">LazyLoading</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// First time calling will calculate result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">result1</span> <span class="p">=</span> <span class="n">lazyLoading</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Second time calling will return the previously calculated result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">result2</span> <span class="p">=</span> <span class="n">lazyLoading</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
</span></span></code></pre></div><p>Through some simple boilerplate code, we managed to optimize our class: it will only calculate the result when needed and will only do so once.</p>
<h2 id="lazylttgt">Lazy&lt;T&gt;</h2>
<p>The .NET framework version 4.0 introduced the <code>Lazy&lt;T&gt;</code> class to easily enable lazy-loading in your code. Let&rsquo;s convert our previous example to a <code>Lazy&lt;T&gt;</code> version:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">class</span> <span class="nc">LazyTypeLoading</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="n">Lazy</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">lazyResult</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Lazy</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;(()</span> <span class="p">=&gt;</span> <span class="n">Calculate</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Result</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">lazyResult</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// This will NOT calculate the result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">lazyTypeLoading</span> <span class="p">=</span> <span class="k">new</span> <span class="n">LazyTypeLoading</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// First time calling will calculate result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">result1</span> <span class="p">=</span> <span class="n">lazyTypeLoading</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Second time calling will return the previously calculated result</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">result2</span> <span class="p">=</span> <span class="n">lazyTypeLoading</span><span class="p">.</span><span class="n">Result</span><span class="p">;</span>
</span></span></code></pre></div><p>We replaced our boilerplate code with a <code>Lazy&lt;int&gt;</code> instance. When creating this instance, we provide it with a lambda expression that will be used to compute the return value. Note that the lambda expression is <strong>not</strong> executed when the instance is created, it is only stored for later use.</p>
<p>When the <code>Value</code> property of a <code>Lazy&lt;T&gt;</code> instance is accessed, it checks if the value has already been calculated; if so, it returns that value and if not, it calculates the value, stores it and then returns it.</p>
<p>You can use the <code>IsValueCreated</code> property to check if the <code>Value</code> has already been calculated:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Lazy</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">lazy</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Lazy</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;(()</span> <span class="p">=&gt;</span> <span class="m">3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">lazy</span><span class="p">.</span><span class="n">IsValueCreated</span><span class="p">;</span> <span class="c1">// Returns false</span>
</span></span><span class="line"><span class="cl"><span class="n">lazy</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span>          <span class="c1">// Will execute the lambda, returns 3</span>
</span></span><span class="line"><span class="cl"><span class="n">lazy</span><span class="p">.</span><span class="n">IsValueCreated</span><span class="p">;</span> <span class="c1">// Returns true</span>
</span></span></code></pre></div><p>With lazy-loading, keep in mind that the value is calculated only once:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Lazy</span><span class="p">&lt;</span><span class="n">DateTime</span><span class="p">&gt;</span> <span class="n">lazy</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Lazy</span><span class="p">&lt;</span><span class="n">DateTime</span><span class="p">&gt;(()</span> <span class="p">=&gt;</span> <span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">value1</span> <span class="p">=</span> <span class="n">lazy</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span> <span class="c1">// First time, returns current time</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span><span class="p">(</span><span class="m">2000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">value2</span> <span class="p">=</span> <span class="n">lazy</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span> <span class="c1">// Second time, returns previous value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">value1</span> <span class="p">==</span> <span class="n">value2</span><span class="p">;</span> <span class="c1">// Returns true!</span>
</span></span></code></pre></div><p>Note that by default, <code>Lazy&lt;T&gt;</code> instances are thread safe. If you don&rsquo;t want it to be thread-safe, you can use one of the <a href="http://msdn.microsoft.com/en-us/library/dd642318(v=vs.110).aspx">constructor overloads</a> that let you specify the thread safety mode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">nonThreadSafeLazy</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Lazy</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;(</span><span class="n">LazyThreadSafetyMode</span><span class="p">.</span><span class="n">None</span><span class="p">);</span>
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Lazy loading can be a good optimization strategy, but you should only use if when performance is an issue. When you do have a use case for lazy-loading, the <code>Lazy&lt;T&gt;</code> class makes it easy to implement.</p>
]]></content>
		</item>
		
		<item>
			<title>Nullable&lt;T&gt; and the ?? operator</title>
			<link>https://www.erikschierboom.com/2014/08/04/nullable-and-null-coalescing-operator/</link>
			<pubDate>Mon, 04 Aug 2014 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2014/08/04/nullable-and-null-coalescing-operator/</guid>
			<description>Nullable value types The concept of a null value is simple: it denotes the absence of a value. In the first version of C#, you could not have null value types. However, C# 2.0 introduced the Nullable&amp;lt;T&amp;gt; type to remedy this:
Nullable&amp;lt;int&amp;gt; nullInt = new Nullable&amp;lt;int&amp;gt;(); nullInt.HasValue; // Returns false nullInt.Value; // Throws exception as no value has been set Nullable&amp;lt;int&amp;gt; nonNullInt = new Nullable&amp;lt;int&amp;gt;(2); nonNullInt.HasValue; // Returns true nonNullInt.Value; // Returns 2 You can also directly assign or retrieve the value:</description>
			<content type="html"><![CDATA[<h2 id="nullable-value-types">Nullable value types</h2>
<p>The concept of a <code>null</code> value is simple: it denotes the <em>absence</em> of a value. In the first version of C#, you could not have <code>null</code> value types. However, C# 2.0 introduced the <code>Nullable&lt;T&gt;</code> type to remedy this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Nullable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">nullInt</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Nullable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;();</span>
</span></span><span class="line"><span class="cl"><span class="n">nullInt</span><span class="p">.</span><span class="n">HasValue</span><span class="p">;</span>    <span class="c1">// Returns false</span>
</span></span><span class="line"><span class="cl"><span class="n">nullInt</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span>       <span class="c1">// Throws exception as no value has been set</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">Nullable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">nonNullInt</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Nullable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;(</span><span class="m">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">nonNullInt</span><span class="p">.</span><span class="n">HasValue</span><span class="p">;</span> <span class="c1">// Returns true</span>
</span></span><span class="line"><span class="cl"><span class="n">nonNullInt</span><span class="p">.</span><span class="n">Value</span><span class="p">;</span>    <span class="c1">// Returns 2</span>
</span></span></code></pre></div><p>You can also directly assign or retrieve the value:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Nullable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">nullInt</span> <span class="p">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">Nullable</span><span class="p">&lt;</span><span class="kt">double</span><span class="p">&gt;</span> <span class="n">nonNullDouble</span> <span class="p">=</span> <span class="m">2.0</span><span class="p">;</span>
</span></span></code></pre></div><p>Even better, appending the <strong>?</strong> keyword to a type makes it a <code>Nullable&lt;T&gt;</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">int?</span> <span class="n">nullInt</span> <span class="p">=</span> <span class="m">2</span><span class="p">;</span>         <span class="c1">// Type is Nullable&lt;int&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kt">bool?</span> <span class="n">nonNullBool</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span> <span class="c1">// Type is Nullable&lt;bool&gt;</span>
</span></span></code></pre></div><p>Comparing nullable types also works as expected:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">int?</span> <span class="n">nullInt</span> <span class="p">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">int?</span> <span class="n">nonNullInt</span> <span class="p">=</span> <span class="m">2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">nullInt</span> <span class="p">==</span> <span class="kc">null</span><span class="p">;</span>    <span class="c1">// Returns true</span>
</span></span><span class="line"><span class="cl"><span class="n">nonNullInt</span> <span class="p">==</span> <span class="m">2</span><span class="p">;</span>    <span class="c1">// Returns true</span>
</span></span><span class="line"><span class="cl"><span class="n">nonNullInt</span> <span class="p">==</span> <span class="kc">null</span><span class="p">;</span> <span class="c1">// Returns false</span>
</span></span></code></pre></div><p>The <code>Nullable&lt;T&gt;</code> class itself is implemented as a value type, so can we create a nullable <code>Nullable&lt;T&gt;</code>? Let&rsquo;s try:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Nullable</span><span class="p">&lt;</span><span class="n">Nullable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;&gt;</span> <span class="n">nullableInception</span> <span class="p">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span></code></pre></div><p>It turns out we can&rsquo;t; the above code does <em>not</em> compile. This is due to the fact that the <code>Nullable&lt;T&gt;</code> struct does not allow nullable types to be specified as its generic type parameter (see <a href="http://msdn.microsoft.com/en-us/library/d5x73970.aspx">MSDN</a>).</p>
<h3 id="the--operator">The <strong>??</strong> operator</h3>
<p>Besides adding <code>Nullable&lt;T&gt;</code>, C# 2.0 introduced another feature that deals with <code>null</code> values: the <strong>??</strong> operator (also known as the <em>null-coalescing</em> operator). It returns the left-hand operand if that is not null; otherwise it returns the right hand operand. This simple operator can greatly simplify your <code>null</code> checks:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">NullCheckWithIfStatement</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">str</span> <span class="p">==</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">str</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">NullCheckWithTernaryOperator</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">str</span> <span class="p">==</span> <span class="kc">null</span> <span class="p">?</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span> <span class="p">:</span> <span class="n">str</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">NullCheckWithNullCoalescingOperator</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">str</span> <span class="p">??</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The <strong>??</strong> operator manages to be both concise <em>and</em> very readable.</p>
<p>With more complex statements, the difference becomes even more striking:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">ComplexNullCheckWithIfStatement</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">string</span> <span class="n">result1</span> <span class="p">=</span> <span class="n">GetPotentiallyNullString1</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">result1</span> <span class="p">!=</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">result1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">string</span> <span class="n">result2</span> <span class="p">=</span> <span class="n">GetPotentiallyNullString2</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">result2</span> <span class="p">!=</span> <span class="kc">null</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">result2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">ComplexNullCheckWithNullCoalescingOperator</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">GetPotentiallyNullString1</span><span class="p">()</span> <span class="p">??</span>
</span></span><span class="line"><span class="cl">           <span class="n">GetPotentiallyNullString2</span><span class="p">()</span> <span class="p">??</span>
</span></span><span class="line"><span class="cl">           <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Of course, you can also use it on <code>Nullable&lt;T&gt;</code> values:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">int?</span> <span class="n">nullInt</span> <span class="p">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">int?</span> <span class="n">nonNullInt</span> <span class="p">=</span> <span class="m">2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">nullInt</span> <span class="p">??</span> <span class="m">8</span><span class="p">;</span>    <span class="c1">// Returns 8</span>
</span></span><span class="line"><span class="cl"><span class="n">nonNullInt</span> <span class="p">??</span> <span class="m">5</span><span class="p">;</span> <span class="c1">// Returns 2</span>
</span></span></code></pre></div><p>If you use the <strong>??</strong> operator to return a type&rsquo;s default value, you can also use the <code>GetValueOrDefault()</code> method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">int?</span> <span class="n">nullInt</span> <span class="p">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">int?</span> <span class="n">nonNullInt</span> <span class="p">=</span> <span class="m">2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">nullInt</span><span class="p">.</span><span class="n">GetValueOrDefault</span><span class="p">();</span>    <span class="c1">// Returns 0</span>
</span></span><span class="line"><span class="cl"><span class="n">nullInt</span> <span class="p">??</span> <span class="k">default</span><span class="p">(</span><span class="kt">int</span><span class="p">);</span>        <span class="c1">// Returns 0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">nonNullInt</span><span class="p">.</span><span class="n">GetValueOrDefault</span><span class="p">();</span> <span class="c1">// Returns 2</span>
</span></span><span class="line"><span class="cl"><span class="n">nonNullInt</span> <span class="p">??</span> <span class="k">default</span><span class="p">(</span><span class="kt">int</span><span class="p">);</span>     <span class="c1">// Returns 2</span>
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Adding support for nullable value types was a very useful addition to C#. I use it often when dealing with databases, where nullable value types are common.</p>
<p>The <strong>??</strong> operator is a personal favorite of mine due to its conciseness and usefulness.</p>
]]></content>
		</item>
		
		<item>
			<title>Extension methods - advanced</title>
			<link>https://www.erikschierboom.com/2014/07/07/extension-methods-advanced/</link>
			<pubDate>Sun, 27 Jul 2014 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2014/07/07/extension-methods-advanced/</guid>
			<description>Previously, the Extension methods - An introduction post showed the basics of extension methods. This post will show more advanced usages of extension methods.
Gracefully handle null values Regular instance methods throw a NullReferenceException when called on a null instance. However, extension methods are static methods and thus can choose how to handle null values. We can use this to create methods that appear to be instance methods, but don&amp;rsquo;t throw a NullReferenceException when invoked on a null instance.</description>
			<content type="html"><![CDATA[<p>Previously, the <a href="https://www.erikschierboom.com/2014/06/23/extension-methods-an-introduction/">Extension methods - An introduction</a> post showed the basics of extension methods. This post will show more advanced usages of extension methods.</p>
<h2 id="gracefully-handle-null-values">Gracefully handle null values</h2>
<p>Regular instance methods throw a <code>NullReferenceException</code> when called on a <code>null</code> instance. However, extension methods are static methods and thus can choose how to handle <code>null</code> values. We can use this to create methods that appear to be instance methods, but don&rsquo;t throw a <code>NullReferenceException</code> when invoked on a <code>null</code> instance.</p>
<p>As an example, this extension method defines a null-safe wrapper for the existing <a href="http://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.110).aspx"><code>GetHashCode()</code></a> method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">ObjectExtensions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">GetHashCodeNullSafe</span><span class="p">(</span><span class="k">this</span> <span class="kt">object</span> <span class="n">obj</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">obj</span> <span class="p">==</span> <span class="kc">null</span> <span class="p">?</span> <span class="m">0</span> <span class="p">:</span> <span class="n">obj</span><span class="p">.</span><span class="n">GetHashCode</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">3.</span><span class="n">GetHashCodeNullSafe</span><span class="p">());</span> <span class="c1">// Returns 3</span>
</span></span><span class="line"><span class="cl"><span class="m">3.</span><span class="n">GetHashCode</span><span class="p">());</span>         <span class="c1">// Returns 3</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">string</span> <span class="n">nullString</span> <span class="p">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">nullString</span><span class="p">.</span><span class="n">GetHashCodeNullSafe</span><span class="p">()</span> <span class="c1">// Returns 0</span>
</span></span><span class="line"><span class="cl"><span class="n">nullString</span><span class="p">.</span><span class="n">GetHashCode</span><span class="p">()</span>         <span class="c1">// Throws NullReferenceException</span>
</span></span></code></pre></div><p>Note: be careful when using this technique, as people expect a <code>NullReferenceException</code> to be thrown when an instance method is called on a <code>null</code> instance.</p>
<h2 id="hiding-functionality">Hiding functionality</h2>
<p>Sometimes, you want to hide advanced functionality of a class by default. You could do this by creating two classes: a <code>Basic</code> class with only basic methods and an <code>Advanced</code> class that extends the <code>Basic</code> class and adds the advanced methods.</p>
<p>Extension methods allow you to do this without inheritance. You define the <code>Basic</code> class as before, but the advanced methods are now defined as extension methods in a <em>different namespace</em> from the <code>Basic</code> class. This means that for users to be able to access the advanced methods, they have to explicitly include the namespace in which the advanced methods are defined.</p>
<p>As an example, say that we have the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">namespace</span> <span class="nn">Core</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">class</span> <span class="nc">Basic</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kd">public</span> <span class="k">void</span> <span class="n">BasicMethod</span><span class="p">()</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">namespace</span> <span class="nn">Core.Advanced</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">BasicExtensions</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kd">public</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">AdvancedMethod</span><span class="p">(</span><span class="k">this</span> <span class="n">Basic</span> <span class="n">instance</span><span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This setup means that by default, only <code>BasicMethod()</code> can be called on <code>Basic</code> class instances. However, when the <code>Core.Advanced</code> namespace is included, <code>AdvancedMethod()</code> will also be available.</p>
<p>This approach has one clear disadvantage: the advanced methods can only work on public members of the class they are extending.</p>
<h2 id="creating-fluent-interfaces">Creating fluent interfaces</h2>
<p><a href="http://en.wikipedia.org/wiki/Fluent_interface">Fluent interfaces</a> allow chaining of methods. They do this by returning a value from the method (usually the instance on which the method was called), which can then be used to call members on.</p>
<p>The extension methods provided by <a href="http://msdn.microsoft.com/en-us/library/bb397926.aspx">LINQ</a> form a fluent interface:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">numbers</span> <span class="p">=</span> <span class="k">new</span> <span class="p">[]</span> <span class="p">{</span> <span class="m">1</span><span class="p">,</span> <span class="m">2</span><span class="p">,</span> <span class="m">3</span><span class="p">,</span> <span class="m">4</span><span class="p">,</span> <span class="m">5</span> <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Will return [5, 3, 1]</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">orderedNumbers</span> <span class="p">=</span> <span class="n">numbers</span><span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">n</span> <span class="p">=&gt;</span> <span class="n">n</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                            <span class="p">.</span><span class="n">OrderByDescending</span><span class="p">(</span><span class="n">n</span> <span class="p">=&gt;</span> <span class="n">n</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                            <span class="p">.</span><span class="n">ToArray</span><span class="p">();</span>
</span></span></code></pre></div><p>However, sometimes you might want methods to be chainable but they are not:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">list</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="m">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="m">3</span><span class="p">);</span>
</span></span></code></pre></div><p>This will lead to a compile-time error:</p>
<p><code>Operator '.' cannot be applied to operand of type 'void'</code></p>
<p>If we look at the <a href="http://msdn.microsoft.com/en-us/library/3wcytfd1(v=vs.110).aspx">definition</a> of the <code>Add()</code> method, we can see that it returns <code>void</code> and thus is not chainable:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="k">void</span> <span class="n">Add</span><span class="p">(</span><span class="n">T</span> <span class="n">item</span><span class="p">);</span>
</span></span></code></pre></div><p>The following extension method <em>does</em> allow fluently adding items:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">ListExtensions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">AddFluent</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="k">this</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">list</span><span class="p">,</span> <span class="n">T</span> <span class="n">item</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">list</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">item</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">list</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>We can use this extension method to fluently add items:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">list</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list</span><span class="p">.</span><span class="n">AddFluent</span><span class="p">(</span><span class="m">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">AddFluent</span><span class="p">(</span><span class="m">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">AddFluent</span><span class="p">(</span><span class="m">3</span><span class="p">);</span>
</span></span></code></pre></div><h2 id="use-in-older-versions-of-the-net-framework">Use in older versions of the .NET framework</h2>
<p>As extension methods are compiled to plain static method calls, they can be used in .NET 2.0. However, if you try to compile an extension method in a .NET 2.0 project, you&rsquo;ll get the following error:</p>
<p><code>Cannot define a new extension method because the compiler required type 'System.Runtime.CompilerServices.ExtensionAttribute' cannot be found. Are you missing a reference to System.Core.dll?</code></p>
<p>It turns out that the compiler tries to add the <code>ExtensionAttribute</code> type to compiled extension methods, but can&rsquo;t find that type (it expects to find it in <code>System.Core.Dll</code>).</p>
<p>The solution is simple: define the <code>ExtensionAttribute</code> yourself:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="k">namespace</span> <span class="nn">System.Runtime.CompilerServices</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="na">    [AttributeUsageAttribute(AttributeTargets.Assembly |
</span></span></span><span class="line"><span class="cl"><span class="na">                             AttributeTargets.Class |
</span></span></span><span class="line"><span class="cl"><span class="na">                             AttributeTargets.Method)]</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">class</span> <span class="nc">ExtensionAttribute</span> <span class="p">:</span> <span class="n">Attribute</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Now your code should compile and you can use extension methods on .NET 2.0.</p>
<h2 id="find-extensions-methods-at-runtime">Find extensions methods at runtime</h2>
<p>As discussed in the previous section, extension methods are automatically decorated with the <code>ExtensionAttribute</code> class. This means that at runtime, you can find extension methods using the following code:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">Assembly</span><span class="p">.</span><span class="n">GetExecutingAssembly</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">GetTypes</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">t</span> <span class="p">=&gt;</span> <span class="n">Attribute</span><span class="p">.</span><span class="n">IsDefined</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="k">typeof</span><span class="p">(</span><span class="n">ExtensionAttribute</span><span class="p">)))</span>
</span></span></code></pre></div><h2 id="conclusion">Conclusion</h2>
<p>Of these advanced techniques, the one that is probably most useful is the graceful null-handling. It has the potential of making your code less prone to the infamous <code>NullReferenceException</code> without much effort.</p>
]]></content>
		</item>
		
		<item>
			<title>Extension methods - an introduction</title>
			<link>https://www.erikschierboom.com/2014/06/23/extension-methods-an-introduction/</link>
			<pubDate>Mon, 23 Jun 2014 00:00:00 +0000</pubDate>
			
			<guid>https://www.erikschierboom.com/2014/06/23/extension-methods-an-introduction/</guid>
			<description>Extension methods were introduced in C# 3.0. The MSDN defines it as follows:
Extension methods are static methods that can be invoked using instance method syntax. In effect, extension methods make it possible to extend existing types and constructed types with additional methods. —[emphasis mine]
So extension methods allow you to extend existing types by defining static methods, which can then be called as if they were instance methods. Let&amp;rsquo;s see how this works.</description>
			<content type="html"><![CDATA[<p>Extension methods were introduced in C# 3.0. The <a href="http://msdn.microsoft.com/en-us/library/bb308966.aspx#csharp3.0overview_topic3">MSDN</a> defines it as follows:</p>
<blockquote>
<p>Extension methods are static methods that can be invoked using instance method syntax. In effect, extension methods make it possible to <strong>extend existing types</strong> and constructed types with additional methods. —[emphasis mine]</p>
</blockquote>
<p>So extension methods allow you to extend existing types by defining static methods, which can then be called as if they were instance methods. Let&rsquo;s see how this works.</p>
<h2 id="example-1-simple-extension-method">Example 1: simple extension method</h2>
<p>Suppose we want to write a function to check if a <code>string</code>&rsquo;s length is even. As the <code>string</code> class is part of the .NET framework, we can&rsquo;t add this new method by modifying its source code. Furthermore, as the <code>string</code> class is marked as <code>sealed</code>, it can&rsquo;t be extended. Our last resort is to define a static helper method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">StringHelper</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">bool</span> <span class="n">HasEvenLength</span><span class="p">(</span><span class="kt">string</span> <span class="n">str</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">str</span><span class="p">.</span><span class="n">Length</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Invoking this method is simple:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">StringHelper</span><span class="p">.</span><span class="n">HasEvenLength</span><span class="p">(</span><span class="s">&#34;abcd&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p>There is nothing wrong with this approach, but extension methods can improve upon this. First, we convert our static helper method to an extension method by prefixing the first parameter with <code>this</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">StringExtensions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">bool</span> <span class="n">HasEvenLength</span><span class="p">(</span><span class="k">this</span> <span class="kt">string</span> <span class="n">str</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">str</span><span class="p">.</span><span class="n">Length</span> <span class="p">%</span> <span class="m">2</span> <span class="p">==</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Then we can call this (extension) method as if it was a regular instance method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="s">&#34;abcd&#34;</span><span class="p">.</span><span class="n">HasEvenLength</span><span class="p">()</span>
</span></span></code></pre></div><p>How does this work? Well, behind the scenes extension method calls are converted to regular static method calls:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">StringExtensions</span><span class="p">.</span><span class="n">HasEvenLength</span><span class="p">(</span><span class="s">&#34;abcd&#34;</span><span class="p">)</span>
</span></span></code></pre></div><p>Extension methods are thus nothing more that static methods in disguise. As such, everything you know about static methods also applies to extension methods.</p>
<h2 id="example-2-multiple-parameters">Example 2: multiple parameters</h2>
<p>Our previous example used a single parameter, but it is perfectly valid to create extension methods with more than one parameter (but not with less obviously):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">StringExtensions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">bool</span> <span class="n">StartsWithFromIndex</span><span class="p">(</span><span class="k">this</span> <span class="kt">string</span> <span class="n">str</span><span class="p">,</span> <span class="kt">string</span> <span class="n">expectedStart</span><span class="p">,</span> <span class="kt">int</span> <span class="n">index</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">str</span><span class="p">.</span><span class="n">Substring</span><span class="p">(</span><span class="n">index</span><span class="p">).</span><span class="n">StartsWith</span><span class="p">(</span><span class="n">expectedStart</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="s">&#34;Hello, World&#34;</span><span class="p">.</span><span class="n">StartsWithFromIndex</span><span class="p">(</span><span class="s">&#34;World&#34;</span><span class="p">,</span> <span class="m">7</span><span class="p">)</span> <span class="c1">// Returns true</span>
</span></span></code></pre></div><p>This will get converted by the compiler to:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="n">StringExtensions</span><span class="p">.</span><span class="n">StartsWithFromIndex</span><span class="p">(</span><span class="s">&#34;Hello, World&#34;</span><span class="p">,</span> <span class="s">&#34;World&#34;</span><span class="p">,</span> <span class="m">7</span><span class="p">)</span>
</span></span></code></pre></div><h2 id="example-3-extending-value-types">Example 3: extending value types</h2>
<p>Extension methods can be defined for any type. For example, if you often convert integers to their hexadecimal representation, you could define this extension method:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">IntExtensions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">ToHex</span><span class="p">(</span><span class="k">this</span> <span class="kt">int</span> <span class="n">val</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">val</span><span class="p">.</span><span class="n">ToString</span><span class="p">(</span><span class="s">&#34;X&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="m">10.</span><span class="n">ToHex</span><span class="p">()</span> <span class="c1">// Returns A</span>
</span></span></code></pre></div><h2 id="example-4-using-generics">Example 4: using generics</h2>
<p>Extension methods can also use generics. As an example, here&rsquo;s an extension method to convert an <code>IEnumerable&lt;T&gt;</code> to an <code>HashSet&lt;T&gt;</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-csharp" data-lang="csharp"><span class="line"><span class="cl"><span class="kd">public</span> <span class="kd">static</span> <span class="k">class</span> <span class="nc">EnumerableExtensions</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kd">static</span> <span class="n">HashSet</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">ToSet</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="k">this</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">source</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">new</span> <span class="n">HashSet</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">source</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Returns a HashSet&lt;int&gt; containing 1, 2 and 3</span>
</span></span><span class="line"><span class="cl"><span class="k">new</span> <span class="kt">int</span><span class="p">[]</span> <span class="p">{</span> <span class="m">1</span><span class="p">,</span> <span class="m">2</span><span class="p">,</span> <span class="m">2</span><span class="p">,</span> <span class="m">3</span><span class="p">,</span> <span class="m">3</span> <span class="p">}.</span><span class="n">ToSet</span><span class="p">();</span>
</span></span></code></pre></div><h2 id="limitations">Limitations</h2>
<ul>
<li>
<p>Extension methods can only be defined in static classes.</p>
</li>
<li>
<p>You can only access public members of the class the extension method is applied to. This follows from the fact that extension methods are nothing more than plain static methods defined in static classes.</p>
</li>
<li>
<p>You can only create extensions for methods; properties, indexers, operators and constructors cannot be extended.</p>
</li>
<li>
<p>If an extension method has the exact same signature as a method defined in the extended type, the extension method will never be called.</p>
</li>
<li>
<p>When you import a namespace containing extension methods, you automatically include <em>all</em> of them. You can&rsquo;t choose the ones you want to import, it is all or nothing.</p>
</li>
</ul>
<h2 id="warning-prevent-overuse">Warning: prevent overuse</h2>
<p>Once people learn about extension methods, they often convert all their static helper methods to extension methods. However, this can lead to situations where a single type has over a hundred different methods, which makes finding methods harder.</p>
<p>To prevent this, ask yourself the following simple questions when deciding if a method should be defined as an extension method:</p>
<ul>
<li>
<p>Does it make sense as an extension method? Not all methods work well as instance methods. If so, don&rsquo;t make it an extension method.</p>
</li>
<li>
<p>How often do I use this method? If the method is not used often, don&rsquo;t make it an extension method.</p>
</li>
<li>
<p>How much does it improve the clarity of the code? If the improvement is not self-evident, don&rsquo;t make it an extension method.</p>
</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>All in all, extension methods are a great and very useful feature of C#. If used carefully and sparingly, they can really improve the clarity of your code.</p>
]]></content>
		</item>
		
	</channel>
</rss>
