<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gabriel Lebec</title>
    <description>The latest articles on DEV Community by Gabriel Lebec (@glebec).</description>
    <link>https://dev.to/glebec</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F61078%2F239af147-dfbd-4dd7-bddb-37033082cc9f.jpeg</url>
      <title>DEV Community: Gabriel Lebec</title>
      <link>https://dev.to/glebec</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/glebec"/>
    <language>en</language>
    <item>
      <title>When Nesting Promises is Correct</title>
      <dc:creator>Gabriel Lebec</dc:creator>
      <pubDate>Sat, 20 Apr 2019 04:01:35 +0000</pubDate>
      <link>https://dev.to/glebec/when-nesting-promises-is-correct-h8f</link>
      <guid>https://dev.to/glebec/when-nesting-promises-is-correct-h8f</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;By now, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"&gt;promises&lt;/a&gt; are well-established in the JS ecosystem, not only being officially specified in &lt;a href="https://www.ecma-international.org/publications/standards/Ecma-262.htm"&gt;ECMAScript&lt;/a&gt;, but even having a first-class syntactic sugar in the form of &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await"&gt;&lt;code&gt;async&lt;/code&gt;&lt;/a&gt; functions.&lt;/p&gt;

&lt;p&gt;When learning promises, many JS developers are told that a major advantage of promise chaining is that it keeps the code "flat", avoiding the &lt;a href="https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming)"&gt;pyramid of doom&lt;/a&gt; of nested callbacks. While this is partly true, it also puts undue emphasis on code &lt;em&gt;appearance&lt;/em&gt;, running the risk of &lt;a href="https://blog.domenic.me/youre-missing-the-point-of-promises/"&gt;missing the point&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;True &lt;a href="http://callbackhell.com/"&gt;"callback hell"&lt;/a&gt; is less about indentation – in fact, by naming callback functions and factoring them out to the top level, one can often flatten out async code &lt;em&gt;without&lt;/em&gt; the need for promises. Instead, callback hell is when we lose the composable vanilla function API (pass in data, receive result), where returned values can be bound to variables, aggregated in collections, passed to other functions, and combined in first-class ways.&lt;/p&gt;

&lt;p&gt;All of this preamble is to give context to the following statement: nesting promises is &lt;em&gt;often&lt;/em&gt; an antipattern, but &lt;em&gt;not always&lt;/em&gt;. In fact, there is a common situation in which a little nesting can make perfect sense, though there exist several alternatives. This short article will demonstrate a common scoping issue with promises and multiple solutions for that issue.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Setup
&lt;/h1&gt;

&lt;p&gt;For these examples, we will imagine that the function &lt;code&gt;getPuppyById&lt;/code&gt; is an AJAX method returning some data via a promise. Puppies will be objects with a &lt;code&gt;bestFriend&lt;/code&gt; foreign key to another puppy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;               &lt;span class="c1"&gt;// this puppy's id&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mr. Wiggles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// this puppy's name&lt;/span&gt;
    &lt;span class="nx"&gt;bestFriend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;       &lt;span class="c1"&gt;// id of this puppy's best friend (another puppy)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If we wish to fetch puppy #1's best friend's name, we can chain calls to &lt;code&gt;getPuppyById&lt;/code&gt;:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
const friendNameP =
    getPuppyById(1)                               // first fetch
    .then(pup1 =&amp;gt; getPuppyById(pup1.bestFriend))  // second fetch
    .then(friend =&amp;gt; friend.name)                  // data transformation

friendNameP  // our goal, a promise for the best friend name
    .then(name =&amp;gt; console.log('friend name', name))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;This works just fine when our early results are just discardable steps towards our desired final result.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;However, what if we wanted to produce a promise for &lt;em&gt;both puppies' names&lt;/em&gt; – the original and the friend? Because the callback passed to &lt;code&gt;then&lt;/code&gt; introduces a function scope, the first puppy may no longer be in scope further down the chain.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
const twoPuppyNamesP =
    getPuppyById(1)                               // first fetch
    .then(pup1 =&amp;gt; getPuppyById(pup1.bestFriend))  // second fetch
    .then(friend =&amp;gt; {
        return [pup1.name, friend.name] // ERROR – pup1 no longer in scope!
    })

// DO NOT EDIT BELOW

twoPuppyNamesP  // our goal, a promise for the puppy and friend names
    .then(names =&amp;gt; console.log('puppy names', names))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;There are multiple ways to solve this, which we will examine in a moment. Before we do so, go ahead and fix the above code snippet using whatever technique &lt;em&gt;you&lt;/em&gt; may prefer. Only edit the top half of the snippet; you are trying to make &lt;code&gt;twoPuppyNamesP&lt;/code&gt; fulfill its promise (hah) of delivering &lt;em&gt;both&lt;/em&gt; puppies.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solutions
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Library-Specific: Bluebird &lt;code&gt;bind&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Before promises became official in ES2015, third-party implementations like &lt;a href="http://bluebirdjs.com/docs/getting-started.html"&gt;Bluebird&lt;/a&gt; were popular. Bluebird is still used by some codebases for its speed and wide array of utility methods.&lt;/p&gt;

&lt;p&gt;Though it breaks &lt;a href="https://promisesaplus.com/#point-35"&gt;section 2.2.5 of the A+ promise spec&lt;/a&gt; to do so, Bluebird includes a special feature in which you can set the &lt;code&gt;this&lt;/code&gt; value of a promise chain – providing a shared mutable namespace in which to save intermediate results. The specific method is named &lt;a href="http://bluebirdjs.com/docs/api/promise.bind.html"&gt;&lt;code&gt;bind&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;.bind&lt;/code&gt; also has a useful side purpose - promise handlers don't need to share a function to use shared state&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
const P = require('bluebird')
const toBluebird = p =&amp;gt; P.resolve(p)

const twoPuppyNamesP =
    toBluebird(getPuppyById(1))                   // first fetch
    .bind({})                                     // set 'this' for chain
    .then(function (pup1) {                       // arrows don't have 'this'
        this.pup1 = pup1                          // saving state for later
        return getPuppyById(pup1.bestFriend)      // second fetch
    })
    .then(function (friend) {
        return [this.pup1.name, friend.name]  // accessing 'pup1' in shared state
    })

twoPuppyNamesP  // our goal, a promise for the puppy and friend names
    .then(names =&amp;gt; console.log('puppy names', names))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;While this &lt;em&gt;works&lt;/em&gt;, it has significant drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it complicates the promise chain with spec-breaking features&lt;/li&gt;
&lt;li&gt;it requires using &lt;code&gt;function&lt;/code&gt; functions to access &lt;code&gt;this&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;it is non-portable knowledge tied to a specific library&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A+-Compliant, ECMA-Approved: &lt;code&gt;Promise.all&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If only we could pass &lt;em&gt;multiple values&lt;/em&gt; down through a promise chain – even when one of those values is a pending promise, whose value we wish to access further down the chain.&lt;/p&gt;

&lt;p&gt;Of course, we do not need to wish for such a feature, as it is available via the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all"&gt;&lt;code&gt;Promise.all&lt;/code&gt;&lt;/a&gt; static method. By returning an array of both &lt;em&gt;synchronous values&lt;/em&gt; and &lt;em&gt;promise values&lt;/em&gt;, wrapped in a call to &lt;code&gt;all&lt;/code&gt;, we get access to an array of &lt;em&gt;synchronous values&lt;/em&gt; in the next &lt;code&gt;then&lt;/code&gt;.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
const twoPuppyNamesP =
    getPuppyById(1)                                   // first fetch
    .then(pup1 =&amp;gt; {
        const friendP = getPuppyById(pup1.bestFriend) // second fetch
        return Promise.all([pup1, friendP])           // collect both results
    })
    .then(([pup1, friend]) =&amp;gt; {                       // array destructuring
        return [pup1.name, friend.name]               // data transformation
    })

twoPuppyNamesP  // our goal, a promise for the puppy and friend names
    .then(names =&amp;gt; console.log('puppy names', names))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Even though the array passed to &lt;code&gt;.all&lt;/code&gt; has a mix of normal and promise values, the resulting overall promise is for an array of normal values.&lt;/p&gt;

&lt;p&gt;This strategy will work in any setting that supports ES2015, and is thus much more portable than the Bluebird &lt;code&gt;bind&lt;/code&gt; trick. Unfortunately, it too has cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more verbose return lines&lt;/li&gt;
&lt;li&gt;more complex function parameters and destructuring&lt;/li&gt;
&lt;li&gt;as the chain grows, passing down multiple results does not scale well&lt;/li&gt;
&lt;li&gt;overall, a lot of redundant "plumbing" of early values through the chain&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Controlled State, Shared Scope
&lt;/h2&gt;

&lt;p&gt;We now come to one of the most common and viable techniques for sharing state through a promise chain – use a mutable or reassignable variable(s) in a higher scope. As each handler in a &lt;code&gt;then&lt;/code&gt; chain is invoked, it will set and/or read the values of a shared &lt;code&gt;let&lt;/code&gt; binding or the properties of a shared object.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
let pup1                                              // shared binding

const twoPuppyNamesP =
    getPuppyById(1)                                   // first fetch
    .then(gotPup1 =&amp;gt; {
        pup1 = gotPup1                                // save state
        return getPuppyById(pup1.bestFriend)          // second fetch
    })
    .then(friend =&amp;gt; {
        return [pup1.name, friend.name]               // data transformation
    })

twoPuppyNamesP  // our goal, a promise for the puppy and friend names
    .then(names =&amp;gt; console.log('puppy names', names))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;This may seem "illegal" considering how we normally consider async code to work, but in fact it is guaranteed to work as expected as later callbacks in a &lt;code&gt;then&lt;/code&gt; chain can only be invoked after earlier callbacks. So the usage of &lt;code&gt;pup1&lt;/code&gt; in the second &lt;code&gt;then&lt;/code&gt; will work because &lt;code&gt;pup1&lt;/code&gt; is guaranteed to have been assigned in the callback of the previous &lt;code&gt;then&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This has some distinct advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is relatively clear even for people without advanced knowledge of promises&lt;/li&gt;
&lt;li&gt;it is setting-agnostic&lt;/li&gt;
&lt;li&gt;it is relatively light on syntax&lt;/li&gt;
&lt;li&gt;the chain remains flat, reducing mental load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As always, there are still tradeoffs to consider, however.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shared mutable state is risky; care should be taken to &lt;em&gt;only&lt;/em&gt; allow the promise chain to read or modify these variables

&lt;ul&gt;
&lt;li&gt;reading outside the chain is not guaranteed to work due to indeterminate timing&lt;/li&gt;
&lt;li&gt;writing outside the chain can break guarantees within the chain&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;we now need two versions of the variable name – a parameter name like &lt;code&gt;gotPup1&lt;/code&gt; and a shared state variable like &lt;code&gt;pup1&lt;/code&gt; – to avoid &lt;a href="https://en.wikipedia.org/wiki/Variable_shadowing"&gt;shadowing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the promise chain is itself contained within a short function scope, disciplined use of shared state in a local setting can be concise and easy way to solve the issue of passing information down the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Punchline: Nested Promises
&lt;/h2&gt;

&lt;p&gt;This article opened with the promise (hah) of showing a situation in which a small bit of nesting can be a valid and useful technique. The key point is that with a nested chain, an inner &lt;code&gt;then&lt;/code&gt; still has scope access to the results from an outer &lt;code&gt;then&lt;/code&gt;.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
const twoPuppyNamesP =
    getPuppyById(1)                                   // first fetch
    .then(pup1 =&amp;gt; getPuppyById(pup1.bestFriend)       // second fetch
        .then(friend =&amp;gt; [pup1.name, friend.name])     // nested then
    )

twoPuppyNamesP  // our goal, a promise for the puppy and friend names
    .then(names =&amp;gt; console.log('puppy names', names))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;In such cases, it is &lt;strong&gt;crucial to remember to &lt;code&gt;return&lt;/code&gt;&lt;/strong&gt; the nested promise chain to the parent promise chain. In the example above we use the implicit return of an arrow function to accomplish this, but it is a common error to forget the &lt;code&gt;return&lt;/code&gt; keyword when in a bracket-enclosed function body.&lt;/p&gt;

&lt;p&gt;The biggest advantage that the above pattern has over an outer-scope variable is that it is stateless – there is no explicit mutation occurring in the visible code, only a declarative sequence of functional transformations.&lt;/p&gt;

&lt;p&gt;As always, we can identify some disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;this approach does not scale well for passing down each result from many &lt;code&gt;then&lt;/code&gt; calls – one quickly returns to the "pyramid of doom" for such cases&lt;/li&gt;
&lt;li&gt;with nesting comes increased mental load in parsing and understanding the logic of the promise chain&lt;/li&gt;
&lt;li&gt;as is often the case with promise chains, it can be especially difficult to decide on a sensible formatting scheme with respect to where &lt;code&gt;.then&lt;/code&gt; appears (same line? next line? indented?) and where to position the callback function&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Silly Experiment: Formatting Tricks
&lt;/h2&gt;

&lt;p&gt;Speaking of formatting, there is no reason why one cannot format a nested promise chain in a "flat" way, if we allow for piling up of parentheses:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
const twoPuppyNamesP =
    getPuppyById(1)                              // first fetch
    .then(pup1 =&amp;gt; getPuppyById(pup1.bestFriend)  // second fetch (missing closing paren)
    .then(friend =&amp;gt; [pup1.name, friend.name]))   // nested then (extra closing paren)

twoPuppyNamesP  // our goal, a promise for the puppy and friend names
    .then(names =&amp;gt; console.log('puppy names', names))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;The longer the nested chain, the more we defer closing parens to the last line, where they will pile up like afterthoughts. In a language like &lt;a href="http://haskell.org"&gt;Haskell&lt;/a&gt; in which function application doesn't &lt;em&gt;use&lt;/em&gt; parens, this isn't a problem! But for JavaScript, it gets a little silly. Compare and contrast:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Haskell&lt;/span&gt;

&lt;span class="n"&gt;_then&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- renaming for JS readers; can't use 'then' b/c it's a keyword&lt;/span&gt;

&lt;span class="n"&gt;pupsIO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;getPuppyById&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;_then&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pup1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPuppyById&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bestFriend&lt;/span&gt; &lt;span class="n"&gt;pup1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;_then&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pup2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPuppyById&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bestFriend&lt;/span&gt; &lt;span class="n"&gt;pup2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;_then&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pup3&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPuppyById&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bestFriend&lt;/span&gt; &lt;span class="n"&gt;pup3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;_then&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pup4&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPuppyById&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bestFriend&lt;/span&gt; &lt;span class="n"&gt;pup4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;_then&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;pup5&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pup1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pup2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pup3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pup4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pup5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JavaScript&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pupsP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;getPuppyById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getPuppyById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bestFriend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup2&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getPuppyById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bestFriend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup3&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getPuppyById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bestFriend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup4&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getPuppyById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bestFriend&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pup5&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pup1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pup2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pup3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pup4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pup5&lt;/span&gt;&lt;span class="p"&gt;])))))&lt;/span&gt; &lt;span class="c1"&gt;// lol&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Promised Land: Async/Await
&lt;/h2&gt;

&lt;p&gt;Moving past our promise chain woes, we return to the real issue at hand – promise chains are composed from callback functions, and functions syntactically introduce new scopes. If we didn't have sibling scopes, we could share access to previous results.&lt;/p&gt;

&lt;p&gt;Lo and behold, this is one of the problems solved by &lt;code&gt;async&lt;/code&gt; functions.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const getPuppyById = (id) =&amp;gt; new Promise((res) =&amp;gt; {
    const time = Math.random() * 500 + 500
    setTimeout(() =&amp;gt; res({
        1: { name: 'Floof', id: 1, bestFriend: 7 },
        7: { name: 'Rex', id: 7, bestFriend: 1 }
    }[id]), time)
})

  &lt;/code&gt;
  &lt;code&gt;
    
const getTwoPuppyNamesP = async () =&amp;gt; {  // a shared async function scope
    const pup1 = await getPuppyById(1)                 // first fetch
    const friend = await getPuppyById(pup1.bestFriend) // second fetch
    return [pup1.name, friend.name]                    // data transformation
}

const twoPuppyNamesP = getTwoPuppyNamesP() // async funcs return promises

twoPuppyNamesP  // our goal, a promise for the puppy and friend names
    .then(names =&amp;gt; console.log('puppy names', names))
    .catch(e =&amp;gt; console.error(e))

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;The advantages are substantial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;far less noise (no &lt;code&gt;.then&lt;/code&gt; calls or callback functions)&lt;/li&gt;
&lt;li&gt;synchronous-looking code with access to previous results in scope&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost is pretty minimal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;await&lt;/code&gt; keyword may only be used inside an &lt;code&gt;async&lt;/code&gt; function, so we need to wrap our promise code in a function body&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Async/await is analogous to Haskell's &lt;code&gt;do&lt;/code&gt;-notation, where &lt;code&gt;do&lt;/code&gt; is like &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;&amp;lt;-&lt;/code&gt; is like &lt;code&gt;await&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Haskell&lt;/span&gt;

&lt;span class="n"&gt;twoPuppyNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;pup1&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getPuppyById&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;friend&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;getPuppyById&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bestFriend&lt;/span&gt; &lt;span class="n"&gt;pup1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pure&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;pup1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;friend&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One major difference is that &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; in JS is only for promises, whereas Haskell's &lt;code&gt;do&lt;/code&gt; notation works with any &lt;a href="https://wiki.haskell.org/Monad"&gt;monad&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;With the advent of async/await, programmers are using raw promise chains less often. Async/await has its own subtleties to master, but it neatly solves at least one awkward aspect of promise chains, namely accessing previous async results in a sequence of operations.&lt;/p&gt;

&lt;p&gt;As the title to this article suggested, when writing a manual promise chain it is sometimes perfectly valid to use a little local nesting. Doing so keeps multiple results in scope, without needing special library tricks or stateful assignments.&lt;/p&gt;

&lt;p&gt;In any case, I hope that these examples will help people learning JS promises to understand them a little better and use them more confidently.&lt;/p&gt;

</description>
      <category>promises</category>
      <category>javascript</category>
      <category>async</category>
      <category>scope</category>
    </item>
    <item>
      <title>The FP Papers: Hughes Lists</title>
      <dc:creator>Gabriel Lebec</dc:creator>
      <pubDate>Wed, 17 Apr 2019 00:32:15 +0000</pubDate>
      <link>https://dev.to/glebec/the-fp-papers-hughes-lists-3ada</link>
      <guid>https://dev.to/glebec/the-fp-papers-hughes-lists-3ada</guid>
      <description>&lt;p&gt;Sitting on my drive is an ever-expanding collection of papers related to functional programming and related topics. Some of these papers are considered classics in the field, having introduced or popularized techniques which are now staples of FP. Others provide rich perspectives on familiar topics, revealing deep mathematical principles embedded in common programming patterns.&lt;/p&gt;

&lt;p&gt;Partly as motivation to actually read through these papers, and partly because I enjoy breaking down and translating such material for a wider community (e.g. in JavaScript), I am beginning a new article series, tentatively titled "The FP Papers" (imaginative, I know). This is the first entry in that series.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Novel Representation of Lists and its Application to the Function "Reverse"
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Authors&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;DOI&lt;/th&gt;
&lt;th&gt;Pages&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;R. John Muir Hughes&lt;/td&gt;
&lt;td&gt;1986&lt;/td&gt;
&lt;td&gt;&lt;a href="https://doi.org/10.1016/0020-0190(86)90059-1"&gt;https://doi.org/10.1016/0020-0190(86)90059-1&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A representation of lists as first-class functions is proposed. Lists represented in this way can be appended together in constant time, and can be converted back into ordinary lists in time proportional to their length. Programs which construct lists using append can often be improved by using this representation. For example, naive reverse can be made to run in linear time, and the conventional ‘fast reverse’ can then be derived easily. Examples are given in KRC (Turner, 1982), the notation being explained as it is introduced. The method can be compared to Sleep and Holmström's proposal (1982) to achieve a similar effect by a change to the interpreter.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/John_Hughes_(computer_scientist)"&gt;John Hughes&lt;/a&gt; is an author and co-author of several of my favorite FP papers, including "Why Functional Programming Matters" and "QuickCheck: A Lightweight Tool for Random Testing of Haskell Programs". In this paper, he introduces a rather clever data structure – an immutable list with a &lt;em&gt;constant time (&lt;code&gt;O(1)&lt;/code&gt;) append operation&lt;/em&gt;. These lists are frequently referred to as &lt;em&gt;difference lists&lt;/em&gt; (DLists) or sometimes &lt;em&gt;Hughes lists&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mutation?
&lt;/h2&gt;

&lt;p&gt;Even in a mutable setting, this would be a challenge. Consider a singly-linked list class with handles to the first and last nodes; append could conceivably done in constant time by "re-wiring" the first list's &lt;code&gt;last&lt;/code&gt; node to point to the second list's &lt;code&gt;first&lt;/code&gt; node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List A:                       List B:
first         last            first         last
&amp;lt;1&amp;gt; -&amp;gt; &amp;lt;2&amp;gt; -&amp;gt; &amp;lt;3&amp;gt;             &amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt; -&amp;gt; &amp;lt;c&amp;gt;
               |               ^
               —————append—————|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;List A's &lt;code&gt;last&lt;/code&gt; pointer would be updated accordingly (to point to &lt;code&gt;&amp;lt;c&amp;gt;&lt;/code&gt;). Yet the above implementation has a glaring flaw; it uses &lt;a href="https://en.wikipedia.org/wiki/Persistent_data_structure"&gt;structural sharing&lt;/a&gt; in a mutable setting. If anything modifies List B, the changes will now &lt;em&gt;also&lt;/em&gt; show up in List A!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List A:              (List B)
&amp;lt;1&amp;gt; -&amp;gt; &amp;lt;2&amp;gt; -&amp;gt; &amp;lt;3&amp;gt; -&amp;gt; &amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt; -&amp;gt; &amp;lt;c&amp;gt;
                             |
                           change (List B)
                             |
List A:                      V
&amp;lt;1&amp;gt; -&amp;gt; &amp;lt;2&amp;gt; -&amp;gt; &amp;lt;3&amp;gt; -&amp;gt; &amp;lt;a&amp;gt; -&amp;gt; &amp;lt;x&amp;gt; -&amp;gt; &amp;lt;c&amp;gt;
             (oops — List A now modified too)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In some cases this may be intended, but it is very easy to accidentally begin changing lists. Even if we never change node &lt;em&gt;values&lt;/em&gt;, the act of appending itself is a mutation, so for instance if someone appended a List C to List B, they would accidentally be affecting List A &lt;em&gt;also&lt;/em&gt;. Oops!&lt;/p&gt;

&lt;p&gt;To get around this risk, a mutable linked list will typically &lt;strong&gt;copy&lt;/strong&gt; nodes to be appended:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List A:                       List B:
first         last            first         last
&amp;lt;1&amp;gt; -&amp;gt; &amp;lt;2&amp;gt; -&amp;gt; &amp;lt;3&amp;gt;             &amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt; -&amp;gt; &amp;lt;c&amp;gt;
               |               |      |      |
               —————append————copy   copy   copy
                               |      |      | 
                               V      V      V
                              &amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt; -&amp;gt; &amp;lt;c&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The operation is now "safe" as modifying the original List B will not affect A (and vice-versa), but it is linear (&lt;code&gt;O(n)&lt;/code&gt; time) with respect to List B's length.&lt;/p&gt;
&lt;h2&gt;
  
  
  Purity?
&lt;/h2&gt;

&lt;p&gt;Perhaps there exists a reasonable implementation for constant-time-appendable mutable lists, but that isn't the point of Hughes's paper. In purely functional code, there aren't any (direct) mutations. The classical functional list structure (aka a &lt;a href="https://en.wikipedia.org/wiki/Cons"&gt;Cons list&lt;/a&gt;) is a singly-linked list implemented as nested pairs; the first cell of each pair is a value, the second cell is a pointer to the next pair (or to the empty list). In Scheme, Haskell, and JS respectively:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scheme"&gt;&lt;code&gt;&lt;span class="c1"&gt;; Scheme&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="c1"&gt;; (list 1 2 3)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Haskell&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;span class="c1"&gt;-- [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JavaScript&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="c1"&gt;// { val: 1, next: { val: 2, next: { val: 3, next: null }}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The restriction of no mutation means that to append two such lists (producing a new List C) is &lt;code&gt;O(n)&lt;/code&gt; where &lt;code&gt;n&lt;/code&gt; is the length of the &lt;em&gt;first&lt;/em&gt; list.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List A:                       List B:
first         last            first         last
&amp;lt;1&amp;gt; -&amp;gt; &amp;lt;2&amp;gt; -&amp;gt; &amp;lt;3&amp;gt;       ———&amp;gt;  &amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt; -&amp;gt; &amp;lt;c&amp;gt;
 |      |      |        |
copy   copy   copy   append
 |      |      |        | 
 V      V      V        |
&amp;lt;1&amp;gt; -&amp;gt; &amp;lt;2&amp;gt; -&amp;gt; &amp;lt;3&amp;gt; ——————|
List C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We &lt;em&gt;must&lt;/em&gt; copy &lt;code&gt;&amp;lt;3&amp;gt;&lt;/code&gt; to change its &lt;code&gt;next&lt;/code&gt; pointer, and we must in turn copy &lt;code&gt;&amp;lt;2&amp;gt;&lt;/code&gt; to change &lt;em&gt;its&lt;/em&gt; &lt;code&gt;next&lt;/code&gt; to point to the new &lt;code&gt;&amp;lt;3&amp;gt;&lt;/code&gt;, and so on. Yet we can safely share List B's nodes because nothing will ever actually change them.&lt;/p&gt;

&lt;p&gt;Overall, this is quite similar to our first attempt at appending mutable lists, but reversed – we have to copy the &lt;em&gt;left&lt;/em&gt; list rather than the right.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Paper
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Representations
&lt;/h3&gt;

&lt;p&gt;With the context established, we can start actually reading this paper. Hughes begins by discussing a general notion of &lt;em&gt;abstract&lt;/em&gt; data types, represented by &lt;em&gt;concrete&lt;/em&gt; data types. Perhaps confusingly, Hughes's choice of "abstract" and "concrete/representational" will refer to familiar &lt;em&gt;Cons lists&lt;/em&gt; and the titular &lt;em&gt;novel list representation&lt;/em&gt; respectively.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Whenever an abstract data type A is represented by a concrete data type R, two functions must be defined:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;abs: R -&amp;gt; A&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rep: A -&amp;gt; R&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this case, the &lt;code&gt;abs&lt;/code&gt; function will convert a Hughes list (aka DList) to a Cons list; the &lt;code&gt;rep&lt;/code&gt; function will convert a Cons list to a DList. The &lt;code&gt;abs&lt;/code&gt; function must be a &lt;a href="https://en.wikipedia.org/wiki/Inverse_function#Left_and_right_inverses"&gt;left inverse&lt;/a&gt; of &lt;code&gt;rep&lt;/code&gt;; that is, when round tripping a Cons list to DList (via &lt;code&gt;rep&lt;/code&gt;) and back ( via &lt;code&gt;abs&lt;/code&gt;), then you must end up where you started. In this sense, &lt;code&gt;abs&lt;/code&gt; "undoes" &lt;code&gt;rep&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, suppose we want to have an &lt;code&gt;append&lt;/code&gt; function for Cons lists. Hughes makes the point that if we can define an &lt;code&gt;append&lt;/code&gt; function for DLists, we get the Cons version for free – we can convert Cons lists to DLists, &lt;code&gt;append&lt;/code&gt; them, and then convert the resulting DList back to a Cons List.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             ————— ConsListAppend ————————————————————————————————
             |                                                   |
ConsListA —&amp;gt; | —rep—&amp;gt; DListA —&amp;gt; ———————————————                  |
             |                  | DListAppend | —&amp;gt; DListC —abs—&amp;gt; | —&amp;gt; ConsListC
ConsListB —&amp;gt; | —rep—&amp;gt; DListB —&amp;gt; ———————————————                  |
             |                                                   |
             —————————————————————————————————————————————————————
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Hughes frames this relationship in terms of an interesting general law:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[given &lt;code&gt;f: A -&amp;gt; A&lt;/code&gt; and &lt;code&gt;g: R -&amp;gt; R&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt; "implements" &lt;code&gt;f&lt;/code&gt; precisely if:]&lt;/p&gt;

&lt;p&gt;FORALL r: R.f(abs r) = abs(g r)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This law is stated in terms of &lt;a href="http://2ality.com/2011/09/currying-vs-part-eval.html"&gt;partially applied&lt;/a&gt; functions, a topic slightly out of scope for this article. Thankfully, partial application isn't strictly necessary to understand DLists per se; the main takeaway for this law is that a "correct" DListAppend would &lt;em&gt;give us&lt;/em&gt; ConsListAppend as previously illustrated.&lt;/p&gt;
&lt;h3&gt;
  
  
  The DList, Defined
&lt;/h3&gt;

&lt;p&gt;Hughes now drops, with almost no ceremony, the actual "novel representation of lists" promised.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;…the representation function, rep, is just append.&lt;/p&gt;

&lt;p&gt;rep L = append L&lt;/p&gt;

&lt;p&gt;(Here we are making use of the KRC convention that all functions are curried.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Careful! There are some subtleties packed into this short snippet. Hughes uses &lt;code&gt;append L&lt;/code&gt; to mean &lt;em&gt;a function that &lt;strong&gt;prepends&lt;/strong&gt; &lt;code&gt;L&lt;/code&gt;&lt;/em&gt; (to an implicit list &lt;code&gt;L2&lt;/code&gt;). This might clarify why that is so:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;append&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt; &lt;span class="kt"&gt;B&lt;/span&gt; &lt;span class="c1"&gt;-- a list     (A ++ B / append B to A / prepend A to B)&lt;/span&gt;
&lt;span class="n"&gt;append&lt;/span&gt; &lt;span class="kt"&gt;A&lt;/span&gt;   &lt;span class="c1"&gt;-- a function (A ++ ? / append ? to A / prepend A to ?)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In JavaScript, we might write this &lt;code&gt;rep&lt;/code&gt; function as follows:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;consList1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;consList2&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;consList1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;consList2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;//              ^        \                                         /&lt;/span&gt;
&lt;span class="c1"&gt;//              |         —————————————————————————————————————————&lt;/span&gt;
&lt;span class="c1"&gt;//              |                            |&lt;/span&gt;
&lt;span class="c1"&gt;//         input list L                output DList&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This underscores a very important point – &lt;strong&gt;a DList is a function&lt;/strong&gt;. If we called &lt;code&gt;rep(cons(1, cons(2, cons(3, null)))&lt;/code&gt; we'd get back a DList &lt;em&gt;representing&lt;/em&gt; the Cons list [1, 2, 3]; yet the &lt;code&gt;typeof&lt;/code&gt; that DList value would be &lt;code&gt;'function'&lt;/code&gt;. How can this be? Well, as Hughes points out, we can easily convert the DList &lt;em&gt;back&lt;/em&gt; to a Cons list – by passing in the empty list &lt;code&gt;null&lt;/code&gt;. Try it below:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
// Cons list implementation
const cons = (val, next) =&amp;gt; ({ val, next })
const append = (c1, c2) =&amp;gt; {
    if (!c1) return c2
    return cons(c1.val, append(c1.next, c2)) // recursively copies c1 nodes
}

// convert  Cons List -&amp;gt; DList
const rep = consList1 =&amp;gt; (consList2 =&amp;gt; append(consList1, consList2))

// convert  DList -&amp;gt; Cons List
const abs = DList =&amp;gt; DList(null)

// create a Cons list and its DList equivalent
const cl1 = cons(1, cons(2, cons(3)))
const dl1 = rep(cl1)
console.log(typeof dl1) // 'function'

// convert from the DList back to a Cons list
const cl2 = abs(dl1)
console.log(cl2) // { val: 1, next: { val: 2, next: { val: 3, next: null }}}

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;Or in Haskell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- (:) is Cons, ([]) is empty list "Nil"&lt;/span&gt;
&lt;span class="c1"&gt;-- [1, 2, 3] is a Cons list (1 : 2 : 3 : [])&lt;/span&gt;
&lt;span class="c1"&gt;-- (++) is append&lt;/span&gt;

&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;DList&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;repr&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;DList&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;repr&lt;/span&gt; &lt;span class="n"&gt;cl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cl&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;abst&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;DList&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;abst&lt;/span&gt; &lt;span class="n"&gt;dl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dl&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;cl1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;dl1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repr&lt;/span&gt; &lt;span class="n"&gt;cl1&lt;/span&gt;
&lt;span class="n"&gt;cl2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abst&lt;/span&gt; &lt;span class="n"&gt;dl1&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cl1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;cl2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The "trick" is that a DList function captures the passed-in Cons list used to construct it via &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"&gt;closure&lt;/a&gt;. So a DList "contains" a Cons list, which can be recovered by applying the DList.&lt;/p&gt;
&lt;h3&gt;
  
  
  Constant Time Append
&lt;/h3&gt;

&lt;p&gt;Once again, Hughes introduces the killer feature of DLists with little fanfare:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The new representation is interesting because two representations can be appended together by composing them as functions, so we can define&lt;/p&gt;

&lt;p&gt;appendR f g = f · g&lt;/p&gt;

&lt;p&gt;(Function composition is written using a dot in KRC.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Function composition is the act of creating a new function which connects the output of function &lt;code&gt;g&lt;/code&gt; to the input of function &lt;code&gt;f&lt;/code&gt;. In JS:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;//              \    /    \           /&lt;/span&gt;
&lt;span class="c1"&gt;//               ————      ———————————&lt;/span&gt;
&lt;span class="c1"&gt;//                |             |&lt;/span&gt;
&lt;span class="c1"&gt;//           input funcs     the composition (a fn)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Notice that function composition &lt;em&gt;returns a new function&lt;/em&gt; but it does NOT invoke either &lt;code&gt;f&lt;/code&gt; or &lt;code&gt;g&lt;/code&gt; to do so. Rather, the resulting composition &lt;em&gt;when applied&lt;/em&gt; calls &lt;code&gt;g&lt;/code&gt; and then &lt;code&gt;f&lt;/code&gt; in that order. So regardless of how expensive &lt;code&gt;f&lt;/code&gt; or &lt;code&gt;g&lt;/code&gt; are, the act of composing them is free – that is, constant time. Actually using the composition will still be expensive, however.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//                   O(1)   O(f) + O(g)&lt;/span&gt;
&lt;span class="c1"&gt;//                   ————   ———————————&lt;/span&gt;
&lt;span class="c1"&gt;//                     |     |&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;How does this apply to DLists? Since DLists are functions, they can be composed together in constant time… and the result is &lt;em&gt;a new DList&lt;/em&gt;:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
// Cons list implementation
const cons = (val, next) =&amp;gt; ({ val, next })
const append = (c1, c2) =&amp;gt; {
    if (!c1) return c2
    return cons(c1.val, append(c1.next, c2)) // recursively copies c1 nodes
}

// convert  Cons List -&amp;gt; DList
const rep = consList1 =&amp;gt; (consList2 =&amp;gt; append(consList1, consList2))

// convert  DList -&amp;gt; Cons List
const abs = DList =&amp;gt; DList(null)

  &lt;/code&gt;
  &lt;code&gt;
    
// 'cons', 'append', 'rep', and 'abs' in scope

const compose = (f, g) =&amp;gt; (x =&amp;gt; f(g(x)))

const c12 = cons(1, cons(2, null))
const c34 = cons(3, cons(4, null))

const d12 = rep(c12)
const d34 = rep(c34)

// O(1)
const d1234 = compose(d12, d34)

// O(n)
const c1234 = abs(d1234)

console.log(c1234)

  &lt;/code&gt;
&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- in Haskell:&lt;/span&gt;
&lt;span class="n"&gt;c12&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;c34&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;d12&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repr&lt;/span&gt; &lt;span class="n"&gt;c12&lt;/span&gt;
&lt;span class="n"&gt;d34&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repr&lt;/span&gt; &lt;span class="n"&gt;c34&lt;/span&gt;

&lt;span class="n"&gt;d1234&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d12&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;d34&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abst&lt;/span&gt; &lt;span class="n"&gt;d1234&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- [1, 2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;How does this work? Hughes lays out a short and clear logical proof in his paper, but we can informally note that since a DList &lt;em&gt;prepends its internal list&lt;/em&gt;, composing two DLists is a function which first prepends the &lt;em&gt;right&lt;/em&gt; list, then prepends the &lt;em&gt;left&lt;/em&gt; list, to whatever list is passed in:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DListA:                   DListB:
prepend (&amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;)      prepend (&amp;lt;c&amp;gt; -&amp;gt; &amp;lt;d&amp;gt;)

DListC = (DListA · DListB):
prepend (&amp;lt;c&amp;gt; -&amp;gt; &amp;lt;d&amp;gt;) then prepend (&amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;)

abs DListC (i.e., apply DListC to Nil):
prepend (&amp;lt;c&amp;gt; -&amp;gt; &amp;lt;d&amp;gt;) to Nil
then prepend (&amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt;) to the above
result is (&amp;lt;a&amp;gt; -&amp;gt; &amp;lt;b&amp;gt; -&amp;gt; &amp;lt;c&amp;gt; -&amp;gt; &amp;lt;d&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The careful reader will probably have some concerns at this point. As Hughes notes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Function composition is an efficient operation. It can always be performed in constant time, so it remains to be shown that abs is reasonably efficient.&lt;/p&gt;

&lt;p&gt;Provided that a 'functional list' is built using only rep and appendR, abs can convert it into an ordinary list in time proportional to its length.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This seems like a cheat. Sure, DLists can be composed in &lt;code&gt;O(1)&lt;/code&gt; time, but we still need &lt;code&gt;O(n)&lt;/code&gt; time to convert a Cons list to a DList or vice-versa! What's the point? &lt;/p&gt;

&lt;p&gt;The answer is that functions are &lt;em&gt;lazy&lt;/em&gt;. The code "inside" of a DList – the body of the function, containing the append operation – does not execute just because a DList is constructed. And we can build a DList &lt;em&gt;without starting from a Cons list&lt;/em&gt;!&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
// Cons list implementation
const cons = (val, next) =&amp;gt; ({ val, next })
const append = (c1, c2) =&amp;gt; {
    if (!c1) return c2
    return cons(c1.val, append(c1.next, c2)) // recursively copies c1 nodes
}

// convert  Cons List -&amp;gt; DList
const rep = consList1 =&amp;gt; (consList2 =&amp;gt; append(consList1, consList2))

// convert  DList -&amp;gt; Cons List
const abs = DList =&amp;gt; DList(null)

  &lt;/code&gt;
  &lt;code&gt;
    
// 'cons', 'append', 'rep', and 'abs' in scope

// O(1) creation of two DLists: remember, function body does not run YET
const d12 = c2 =&amp;gt; append(cons(1, cons(2, null)), c2)
const d34 = c2 =&amp;gt; append(cons(3, cons(4, null)), c2)

const compose = (f, g) =&amp;gt; (x =&amp;gt; f(g(x)))
const appendD = compose

const d1234 = appendD(d12, d34)

  &lt;/code&gt;
&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Haskell&lt;/span&gt;
&lt;span class="n"&gt;d12&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt;
&lt;span class="n"&gt;d34&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt;

&lt;span class="n"&gt;d1234&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d12&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;d34&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the above example, no actual Cons list was ever constructed. Two functions that &lt;em&gt;could&lt;/em&gt; produce Cons lists were defined, but neither function body actually ran, so the runtime cost remained hypothetical. Yet we defined a new DList which represents the concatenation of the two hypothetical Cons lists, and all of this in constant time.&lt;/p&gt;

&lt;p&gt;Converting this list back down to a Cons list does take linear time, of course.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JS: O(n)&lt;/span&gt;
&lt;span class="nx"&gt;d1234&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// cons(1, cons(2, cons(3, cons(4, null))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- HS: O(n)&lt;/span&gt;
&lt;span class="n"&gt;d1234&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;-- [1, 2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;When abs applies such a function to the empty list to convert it back into an ordinary list, it computes&lt;/p&gt;

&lt;p&gt;append L1 (append L2 … (append Ln []) …).&lt;/p&gt;

&lt;p&gt;The cost of computing (append A B) is independent of B—it is just the length of A. Therefore, the cost of computing the expression above is the sum of the lengths of L1,L2,…,Ln, that is, the length of the final list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that is one of the primary tradeoffs of the DList: if you expect to perform &lt;em&gt;many&lt;/em&gt; append operations, and only need the final result at the very end, a DList can prevent duplicate work; often this will reduce an overall &lt;code&gt;O(n^2)&lt;/code&gt; algorithm to &lt;code&gt;O(n)&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reverse
&lt;/h2&gt;

&lt;p&gt;"A Novel Representation of Lists" is just the first half of this paper's title; the second half is "and its Application to the Function 'Reverse'". Hughes uses a naive singly-linked list &lt;code&gt;reverse&lt;/code&gt; function to illustrate an &lt;code&gt;O(n^2)&lt;/code&gt; algorithm which can be improved via DLists.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// JS&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cl&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cl&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Haskell&lt;/span&gt;
&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Consider the the following pseudocode expansion of the &lt;code&gt;reverse&lt;/code&gt; call on a cons list [1, 2, 3, 4]:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;reverse [1, 2, 3, 4]

// recursive applications of reverse
append(reverse [2, 3, 4], [1])
append(append(reverse [3, 4], [2]), [1])
append(append(append(reverse [4], [3]), [2]), [1])

// sequential applications of append
append(append(append([4], [3]), [2]), [1])
  - append(append([_, 3], [2]), [1])
  - append(append([4, 3], [2]), [1])
append(append([4, 3], [2]), [1])
  - append([_, _, 2], [1])
  - append([_, 3, 2], [1])
  - append([4, 3, 2], [1])
append([4, 3, 2], [1])
  - [_, _, _, 1]
  - [_, _, 2, 1]
  - [_, 3, 2, 1]
  - [4, 3, 2, 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Because a Cons list &lt;code&gt;append&lt;/code&gt; is proportional to the left list length, and as we keep building up a bigger and bigger list, we end up performing the same work. &lt;code&gt;append&lt;/code&gt; takes an average of &lt;code&gt;O(n/2)&lt;/code&gt; time, and we do it for &lt;code&gt;n&lt;/code&gt; elements, resulting in &lt;code&gt;O(n^2)&lt;/code&gt; time overall.&lt;/p&gt;

&lt;p&gt;Using DLists, we switch to an &lt;code&gt;O(1)&lt;/code&gt; append:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
// Cons list implementation
const cons = (val, next) =&amp;gt; ({ val, next })
const append = (c1, c2) =&amp;gt; {
    if (!c1) return c2
    return cons(c1.val, append(c1.next, c2)) // recursively copies c1 nodes
}

// convert  Cons List -&amp;gt; DList
const rep = consList1 =&amp;gt; (consList2 =&amp;gt; append(consList1, consList2))

// convert  DList -&amp;gt; Cons List
const abs = DList =&amp;gt; DList(null)

// DList append
const compose = (f, g) =&amp;gt; (x =&amp;gt; f(g(x)))
const appendD = compose

  &lt;/code&gt;
  &lt;code&gt;
    
// 'cons', 'append', 'rep', 'abs', and 'appendD' in scope

// Cons List -&amp;gt; reversed Cons List
const reverse = consList =&amp;gt; {
    return abs(rev(consList))
}

// Cons List -&amp;gt; reversed DList
const rev = consList =&amp;gt; {
    if (!consList) return (c2 =&amp;gt; c2) // O(1) empty DList, prepends nothing
    return appendD(                  // O(1) append (function composition)
        rev(consList.next),          // O(n) recursive reversal
        c2 =&amp;gt; cons(consList.val, c2) // O(1) DList of one value
    )
}

const c1234 = cons(1, cons(2, cons(3, cons(4, null))))
const c4321 = reverse(c1234) // O(n)

console.log(c4321)

  &lt;/code&gt;
&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Haskell&lt;/span&gt;

&lt;span class="n"&gt;reverseC&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;reverseC&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abst&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;DList&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rev&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reverseC&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;-- [4, 3, 2, 1]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It should be noted that this is not the only way to define an efficient &lt;code&gt;reverse&lt;/code&gt; function; this problem is used mostly as a small, familiar example to illustrate how DLists work. The DList solution generalizes a hand-coded tail-recursive &lt;code&gt;reverse&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initList&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;oldList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newList&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newerList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newerList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or using &lt;code&gt;foldl&lt;/code&gt; in Haskell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foldl&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flip&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hughes also goes on to demonstrate another use case for DLists, breaking up a line of text (in the form of a list of characters) into words (separated by a space).&lt;/p&gt;

&lt;p&gt;The paper finishes with some notes regarding performance – namely, that a hand-coded efficient &lt;code&gt;reverse&lt;/code&gt; was faster than using DLists, but of course DLists were significantly faster than the naive approach. At the time of publication (1986), DLists were found to have a practical performance improvement for certain applications.&lt;/p&gt;

&lt;p&gt;What about DLists today? As the popular Haskell package &lt;a href="http://hackage.haskell.org/package/dlist"&gt;&lt;code&gt;dlist&lt;/code&gt;&lt;/a&gt; notes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Difference lists are a list-like type supporting O(1) append. This is particularly useful for efficient logging and pretty printing (e.g. with the Writer monad), where list append quickly becomes too expensive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That package hides the clever yet tiny implementation of DLists behind an easy-to-use API; similar work could be done easily enough in JavaScript.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;dlist&lt;/code&gt; README has links to additional interesting resources on the subject. Ultimately I think that the DList implementation is worth examining because it show how representing data lazily, &lt;em&gt;as a function&lt;/em&gt;, can unlock new and surprising capabilities. This shows up in other functional representations, such as &lt;a href="https://en.wikipedia.org/wiki/Church_encoding"&gt;Church encodings&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hughes's paper is a small 4-page gem, and this article is… not. Hopefully however it makes the idea more accessible to a typical JavaScript programmer. If so, I may add more entries to this series in the future.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>dlist</category>
      <category>cons</category>
      <category>encodings</category>
    </item>
    <item>
      <title>Property Testing with JSVerify · Part III</title>
      <dc:creator>Gabriel Lebec</dc:creator>
      <pubDate>Mon, 25 Mar 2019 02:25:18 +0000</pubDate>
      <link>https://dev.to/glebec/property-testing-with-jsverify-part-iii-5bp0</link>
      <guid>https://dev.to/glebec/property-testing-with-jsverify-part-iii-5bp0</guid>
      <description>&lt;h1&gt;
  
  
  Part III: Intermediate JSVerify Usage
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;In &lt;a href="https://dev.to/glebec/property-testing-with-jsverify-part-i-3one"&gt;Part I&lt;/a&gt;, we explored the concept of property testing and saw basic JSVerify usage.&lt;/li&gt;
&lt;li&gt;In &lt;a href="https://dev.to/glebec/property-testing-with-jsverify-part-ii-1jcg"&gt;Part II&lt;/a&gt;, we took a detailed look at the language of JSVerify's README, including the meaning of types like &lt;code&gt;generator&lt;/code&gt;, &lt;code&gt;shrink&lt;/code&gt;, and &lt;code&gt;arbitrary&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Armed with both conceptual knowledge and library-specific jargon, we are now ready to take a deeper dive into using JSVerify.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Built-In Arbitraries
&lt;/h2&gt;

&lt;p&gt;JSVerify features a string-based &lt;a href="https://en.wikipedia.org/wiki/Domain-specific_language"&gt;Domain-Specific Language&lt;/a&gt; (DSL) documented &lt;a href="https://github.com/jsverify/jsverify#dsl-for-input-parameters"&gt;here&lt;/a&gt; for describing the desired arbitrary data you want to test. The simplest possible examples use built-in &lt;a href="https://github.com/jsverify/jsverify#primitive-arbitraries"&gt;primitive arbitraries&lt;/a&gt; by name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// a dummy property used to produce example output&lt;/span&gt;
&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;falsy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;char&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;int&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;nat&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;num&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;fls&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;chr&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-5.293295592069626&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;''&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;´&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6.371534138917923&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6.8075778381899&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NaN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.37970419274643064&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ø&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-8.00378399901092&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\u001e&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;11.162152161821723&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;n&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-8.52733048191294&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;NaN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Z&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;14&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-20.764524302445352&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;' '&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;14&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-2.3603379679843783&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;«&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note, however, that using the DSL is optional; the functions the DSL refers to are available for direct use, and are also valid inputs to &lt;code&gt;forall&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// equivalent to previous example&lt;/span&gt;
&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;falsy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the built-in primitive arbitraries are parameterized – they act as functions with parameters, for things like min and max bounds or to choose from an array of options. Expressing this using the string DSL can be tricky or unsupported, however. In such cases it is often easier to use the ordinary JS function equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// a dummy property used to produce example output&lt;/span&gt;
&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;trueOrNull&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;trueOrNull&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;int&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;nat&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;trueOrNull&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;null&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Combinators: Deriving New Arbitraries from Existing Arbitraries
&lt;/h2&gt;

&lt;p&gt;We have seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;atomic ("primitive") arbitraries, e.g.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;jsc.bool : arbitrary bool&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jsc.integer : arbitrary integer&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;functions which map vanilla values to arbitraries, e.g.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;jsc.integer(min: integer, max: integer) : arbitrary integer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jsc.elements(args: array a): arbitrary a&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The next level in this hierarchy would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functions which &lt;em&gt;take arbitraries&lt;/em&gt; and return &lt;em&gt;new arbitraries&lt;/em&gt;, e.g.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;jsc.array(arb: arbitrary a): arbitrary (array a)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dict(arb: arbitrary a): arbitrary (dict a)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This kind of library design is known as the &lt;a href="https://wiki.haskell.org/Combinator_pattern"&gt;combinator pattern&lt;/a&gt;, and is a powerful yet concise way to build up complex functionality. Given a variety of primitive values and a selection of combinators, new values can be produced that can be fed back into those combinators, and so on – a self-reinforcing loop which creates a combinatorial explosion of possibilities.&lt;/p&gt;

&lt;p&gt;We have already seen one example combinator: the &lt;code&gt;jsc.array&lt;/code&gt; function takes an arbitrary (e.g. &lt;code&gt;jsc.nat&lt;/code&gt;) and returns a new arbitrary (which generates &lt;em&gt;arrays of that arbitrary value&lt;/em&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[nat]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// these are both equivalent&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrayOfNats1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arrayOfNats2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* use generated values */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;arrayOfNats1&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;arrayOfNats2&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[7, 40, 4, 2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[18, 40, 15, 6]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[11]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[26]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[14, 13, 17, 12]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[3]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[3, 6, 5]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Since the return value of &lt;code&gt;jsc.array&lt;/code&gt; is itself an &lt;code&gt;arbitrary&lt;/code&gt;, it can become the input to &lt;code&gt;jsc.array&lt;/code&gt; again, to yield arrays-of-arrays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[[nat]]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="c1"&gt;// again, equivalent&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrArrNat1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arrArrNat2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* use generated values */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;arrArrNat1&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;arrArrNat2&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[ [], [ 2, 10 ] ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ [ 1 ] ]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[ [ 10, 26, 9, 7 ] ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[ [ 22, 3, 17, 16 ], [ 13 ], [ 0, 23 ] ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ [ 5, 10, 18, 4, 17 ], [ 17, 21 ] ]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At this point we can begin to see why JSVerify includes a string-based DSL for specifying input types. &lt;code&gt;'[[nat]]'&lt;/code&gt; is much more concise than &lt;code&gt;jsc.array(jsc.array(jsc.nat))&lt;/code&gt;. On the other hand, method calls can be typed (e.g. for TypeScript), don't require learning a new syntax, and are a superset of what is possible with the DSL.&lt;/p&gt;

&lt;p&gt;Some more examples of combinators are demonstrated below:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Combinator&lt;/th&gt;
&lt;th&gt;String DSL Form&lt;/th&gt;
&lt;th&gt;Method Call Form&lt;/th&gt;
&lt;th&gt;Two Example Generated Values&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pair&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'pair nat bool'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jsc.pair(jsc.nat, jsc.bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;① &lt;code&gt;[4, false]&lt;/code&gt; ② &lt;code&gt;[0, true]&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tuple&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'nat &amp;amp; nat &amp;amp; bool'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jsc.tuple([jsc.nat, jsc.nat, jsc.bool])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;① &lt;code&gt;[0, 18, true]&lt;/code&gt; ② &lt;code&gt;[9, 2, true]&lt;/code&gt; (all types will be used per generation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sum&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'char ¦ nat ¦ bool'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jsc.sum([jsc.char, jsc.nat, jsc.bool])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;① &lt;code&gt;9&lt;/code&gt; ② &lt;code&gt;'h'&lt;/code&gt; (a random type will be chosen per generation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'a -&amp;gt; bool'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jsc.fn(jsc.bool)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;① a function which maps &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;'hi'&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;… ② a function which maps all inputs to &lt;code&gt;false&lt;/code&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;record&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;'{ name: asciinestring; age: nat }'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;jsc.record({ name: jsc.asciinestring, age: jsc.nat })&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;① &lt;code&gt;{ name: 'KUW&amp;lt;.', age: 0 }&lt;/code&gt; ② &lt;code&gt;{ name: '^L', age: 37 }&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;⚠️ (&lt;em&gt;NB: for the &lt;code&gt;sum&lt;/code&gt; type, we have substituted the "broken bar" symbol &lt;code&gt;¦&lt;/code&gt; for the pipe character &lt;code&gt;|&lt;/code&gt; because Markdown syntax uses the pipe character in tables.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Putting it all together, you can specify reasonably complex arbitrary data with a minimal amount of work. And if your property fails, the failing input case can be automatically shrunk by JSVerify.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[{ start: integer &amp;amp; integer; end: integer &amp;amp; integer }]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lineSegments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* use generated values */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;lineSegments&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[ {start: [26, 6], end: [20, -4]} ]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[ {start: [11, -6], end: [-14, 8]}, {start: [-14, -15], end: [11, -15]} ]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Transforming Arbitraries
&lt;/h2&gt;

&lt;p&gt;With the supplied primitive arbitraries and combinators, you can do a lot, but not everything. As a very small example, what if very specifically want arbitrary &lt;em&gt;even natural numbers&lt;/em&gt;? One strategy is to start with something close (integers) and transform them inside your property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;integer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;evenInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;integer&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;funcThatUsesEvens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evenInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works (for some problems), but has a downside: if we ever encounter a failure, the failing input case that is logged is &lt;em&gt;pre-transformation&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Failed after 13 tests and 9 shrinks. rngState: 93bc7e5e6160384cf8;
Counterexample: 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we would really like is a value of type &lt;em&gt;arbitrary even&lt;/em&gt;, so the failing cases are the even numbers fed into our function under test. JSVerify gives the capability to transform an existing arbitrary into a new arbitrary via &lt;a href="https://github.com/jsverify/jsverify#arbitrary-data"&gt;the &lt;code&gt;.smap&lt;/code&gt; (surjective map) prototypal method&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.smap(f: a -&amp;gt; b, g: b -&amp;gt; a, newShow: (b -&amp;gt; string)?): arbitrary b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, given &lt;code&gt;arbA : arbitrary a&lt;/code&gt;, you can create a transformed &lt;code&gt;arbB : arbitrary b&lt;/code&gt; by providing (at least) two functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;f: a -&amp;gt; b&lt;/code&gt; is a function that transforms the input case to the form you desire&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;g: b -&amp;gt; a&lt;/code&gt; is a function that maps derived values back to the original type (necessary for shrinking)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Applied to our example of even numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// arbitrary even&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbEven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;smap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// function to transform integer numbers to evens&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="c1"&gt;// function to map even numbers back to integers&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arbEven&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;funcThatUsesEvens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the docs note, the first function passed to &lt;code&gt;smap&lt;/code&gt; should be &lt;a href="https://en.wikipedia.org/wiki/Surjective_function#Surjections_as_right_invertible_functions"&gt;&lt;em&gt;surjective&lt;/em&gt;&lt;/a&gt;. If you "map back" your derived value &lt;code&gt;x&lt;/code&gt; using the second function, then the first function should bring you &lt;strong&gt;back to &lt;code&gt;x&lt;/code&gt;&lt;/strong&gt; exactly. That is, &lt;code&gt;f(g(x))&lt;/code&gt; always equals &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With our &lt;code&gt;arbitrary even&lt;/code&gt; type implemented, our failures now show actual even numbers which fail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Failed after 13 tests and 9 shrinks. rngState: 93bc7e5e6160384cf8;
Counterexample: 14
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining Custom Arbitraries from Scratch
&lt;/h2&gt;

&lt;p&gt;In Part II, we saw an example generator, shrink, and show function for a hypothetical "hydra"-type value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generatorHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="c1"&gt;// valid but inefficient&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`{ heads: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; }`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Together, these three functions &lt;em&gt;almost&lt;/em&gt; make up the complete manual definition of a custom &lt;code&gt;arbitrary hydra&lt;/code&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;almostArbitraryHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;generatorHydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;shrinkHydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showHydra&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, there is one bit of spice we need to apply before this can actually be used in JSVerify as an &lt;code&gt;arbitrary hydra&lt;/code&gt;. JSVerify assumes that generators, shrinks, and arbitraries will have certain methods – for example, arbitraries will have &lt;code&gt;.smap&lt;/code&gt; as shown earlier. In order to add these methods to your own from-scratch arbitraries, JSVerify provides three helper functions named &lt;code&gt;bless&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbitraryHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bless&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bless&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;generatorHydra&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bless&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shrinkHydra&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showHydra&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;code&gt;jsc.bless(arbLike: {...}) : arbitrary a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jsc.generator.bless(genLike: (size: nat) -&amp;gt; a) : generator a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jsc.shrink.bless(shrinkLike: a -&amp;gt; [a]) : shrink a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;(there is no &lt;code&gt;bless&lt;/code&gt; for &lt;code&gt;show&lt;/code&gt; – it doesn't need it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;bless&lt;/code&gt; functions "upgrade" pseudo-generators / pseudo-shrinks / pseudo-arbitraries into bona-fide full versions suitable for use by e.g. &lt;code&gt;jsc.forall&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With our holy hydra fully evolved, we can use it in a property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we wanted to refer to the hydra arbitrary by name using the String DSL, we would add it to a namespace object and pass in that map as our penultimate &lt;code&gt;env&lt;/code&gt; argument to &lt;code&gt;forall&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hydra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deriving Generators
&lt;/h2&gt;

&lt;p&gt;When defining new arbitraries, it was sometimes useful to start with existing arbitraries and use either combinators (like &lt;code&gt;array&lt;/code&gt;) or transformations (like &lt;code&gt;smap&lt;/code&gt;) on them. Similarly, when defining our own generators, it is sometimes useful to start with an existing generator.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generator Combinators
&lt;/h3&gt;

&lt;p&gt;Some of the same &lt;a href="https://github.com/jsverify/jsverify#generator-functions"&gt;combinators&lt;/a&gt; exist for generators as for arbitraries. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jsc.generator.array(gen: generator a): generator (array a)&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;"given a &lt;strong&gt;generator of &lt;code&gt;a&lt;/code&gt;&lt;/strong&gt;, the &lt;code&gt;array&lt;/code&gt; method returns a generator for &lt;strong&gt;arrays of &lt;code&gt;a&lt;/code&gt;&lt;/strong&gt;"&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jsc.generator.tuple(gens: (generator a, generator b...)): generator (a, b...)&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;"given an &lt;strong&gt;array of generators&lt;/strong&gt; for &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, etc., the &lt;code&gt;tuple&lt;/code&gt; method returns a generator for &lt;strong&gt;arrays of form&lt;/strong&gt; &lt;code&gt;[a, b]&lt;/code&gt; etc."
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// (size: nat) -&amp;gt; [char, [nat], bool]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generatorCharNatsBool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="c1"&gt;// example outputs:&lt;/span&gt;
&lt;span class="c1"&gt;// ['h', [0, 3], true]&lt;/span&gt;
&lt;span class="c1"&gt;// ['#', [91, 3, 84], false]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that generator combinator methods live on &lt;code&gt;jsc.generator.COMBINATOR_NAME&lt;/code&gt; whereas existing generators for a primitive can be found as &lt;code&gt;jsc.PRIMITIVE_NAME.generator&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transforming Generators
&lt;/h3&gt;

&lt;p&gt;Transforming a generator is easier than transforming a full arbitrary. With an arbitrary value, &lt;code&gt;smap&lt;/code&gt; needed a pair of functions – one to derive data, and one to map derived data back to the original type. Generators have a &lt;code&gt;map&lt;/code&gt; method which just needs the transformer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gen: generator a).map(f: a -&amp;gt; b): generator b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// (size : nat) -&amp;gt; nat&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;evenGenerator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// example outputs:&lt;/span&gt;
&lt;span class="c1"&gt;// 12&lt;/span&gt;
&lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="c1"&gt;// 54&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;yellGenerator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// example outputs:&lt;/span&gt;
&lt;span class="c1"&gt;// '!'&lt;/span&gt;
&lt;span class="c1"&gt;// 'c&amp;gt;&amp;lt;92&amp;amp;X.!'&lt;/span&gt;
&lt;span class="c1"&gt;// 's'72$!'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given a generator of &lt;code&gt;a&lt;/code&gt;-type values, and a transforming function &lt;code&gt;a -&amp;gt; b&lt;/code&gt;, the &lt;code&gt;map&lt;/code&gt; method will give you a generator of &lt;code&gt;b&lt;/code&gt;-type values.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;As a side note: this is precisely the type needed to define a &lt;a href="https://medium.com/@tzehsiang/javascript-functor-applicative-monads-in-pictures-b567c6415221#e4de"&gt;functor&lt;/a&gt; – a structure which can be mapped over. Just like arrays can be mapped (transforming the values in the array, but leaving the array structure alone), generators can be mapped (transforming the output of the function, but leaving its function nature / input type alone). Functors show up extensively in functional programming, but you don't need to know their theory in order to use &lt;code&gt;map&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Dependently-Generated Values
&lt;/h3&gt;

&lt;p&gt;Let's consider something more challenging – a generator customized by other generators. As an example, we might want to generate both a nonempty array of values, and a random index on that array, e.g. to pass into &lt;code&gt;includes&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for all a ∈ Array x | a.length &amp;gt; 0,
    for all i ∈ Nat | i &amp;lt; a.length,
        a.includes(a[i])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We know how to generate arbitrary nonempty arrays, e.g. &lt;code&gt;jsc.nearray(jsc.bool)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We know how to generate arbitrary naturals with a max size, e.g. &lt;code&gt;jsc.nat(8)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we haven't seen yet is how to make the input of one generator (e.g. &lt;code&gt;nat&lt;/code&gt;) rely on values from the output of another generator (e.g. &lt;code&gt;nearray&lt;/code&gt;). As a first attempt, something like &lt;code&gt;map&lt;/code&gt; seems promising:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Will not work&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genArrIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nearray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// gen [bool]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrBools&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// [bool] -&amp;gt;&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrBools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxIdx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arbIdx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt; &lt;span class="c1"&gt;// gen nat&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; gen (gen nat)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, this does quite not work – we have actually created a &lt;em&gt;generator of (generator of nat)&lt;/em&gt;. Consider this analogous example of returning an array from array map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// array int&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// int -&amp;gt;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// array int&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; array (array int)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [[1, 1], [2, 2], [3, 3]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just as mapping an array to arrays returns a nested array, mapping a generator to generators returns a nested generator. To un-do this nesting, we need a new function, &lt;code&gt;.flatMap&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt; Almost there…
&lt;span class="p"&gt;const genArrIdx =
&lt;/span&gt;    jsc.generator.nearray(jsc.bool.generator)
&lt;span class="gd"&gt;-       .map(    arrBools =&amp;gt; {
&lt;/span&gt;&lt;span class="gi"&gt;+       .flatMap(arrBools =&amp;gt; {
&lt;/span&gt;            const maxIdx = arrBools.length - 1
            const arbIdx = jsc.nat(maxIdx)
            return arbIdx.generator // gen nat
&lt;span class="gd"&gt;-       }) // -&amp;gt; gen (gen nat)
&lt;/span&gt;&lt;span class="gi"&gt;+       }) // -&amp;gt; gen nat
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us a &lt;code&gt;generator nat&lt;/code&gt; with no nesting. But as you may recall, we really wanted an array alongside a randomly-generated valid index on that array, not just the index alone. To solve this, we can use an inner &lt;code&gt;map&lt;/code&gt; to combine our two results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt; Works
&lt;span class="p"&gt;const genArrIdx =
&lt;/span&gt;    jsc.generator.nearray(jsc.bool.generator)
        .flatMap(arrBools =&amp;gt; {
            const maxIdx = arrBools.length - 1
            const arbIdx = jsc.nat(maxIdx)
            return arbIdx.generator
&lt;span class="gi"&gt;+               .map(idx =&amp;gt; {
+                   return [arrBools, idx]
+               }) // -&amp;gt; gen [array bool, nat]
&lt;/span&gt;&lt;span class="gd"&gt;-       }) // -&amp;gt; gen nat
&lt;/span&gt;&lt;span class="gi"&gt;+       }) // -&amp;gt; gen [array bool, nat]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A bit more tersely, and with JS syntax highlighting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// generator [array bool, nat]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genArrIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nearray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrBools&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrBools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxIdx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arbIdx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arrBools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;flatMap&lt;/code&gt; method is just like &lt;code&gt;map&lt;/code&gt; except the function passed to it should return &lt;strong&gt;generators of values&lt;/strong&gt; rather than just plain values. Where &lt;code&gt;map&lt;/code&gt; would produce a nested generator, &lt;code&gt;flatMap&lt;/code&gt; removes the nesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(generator a)    .map(a -&amp;gt;            b ) : generator b
(generator a).flatMap(a -&amp;gt; (generator b)) : generator b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;As a side note: this is precisely the type needed to define a &lt;a href="https://medium.com/@tzehsiang/javascript-functor-applicative-monads-in-pictures-b567c6415221#42a9"&gt;monad&lt;/a&gt; – a structure which can be un-nested after mapping. Like functors, monads show up often in functional programming, though again all you really need to know practically for this library is "return a generator in the function passed to flatMap".&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Technically, &lt;code&gt;flatMap&lt;/code&gt; is just a convenience method. We could have defined our array+index generator manually as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genArrIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bless&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// create and use array generator:&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genArrBool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nearray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrBools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;genArrBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrBools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="c1"&gt;// create and use index generator:&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxIdx&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;genIdx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// return resulting generated values&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arrBools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how we pass the &lt;code&gt;size&lt;/code&gt; parameter through all the generators ourself; &lt;code&gt;flatMap&lt;/code&gt; handles this for us.&lt;/p&gt;

&lt;p&gt;Regardless of which style (applying &lt;code&gt;size&lt;/code&gt; or using &lt;code&gt;flatMap&lt;/code&gt;) you prefer, when you sequence dependent generators you must write your own corresponding shrink function for the result. Shrinks aren't provided automatically, like they are with &lt;code&gt;smap&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Shrinks
&lt;/h2&gt;

&lt;p&gt;Like full &lt;code&gt;arbitrary a&lt;/code&gt; and lower-level &lt;code&gt;generator a&lt;/code&gt; functions, &lt;code&gt;shrink&lt;/code&gt; functions can be written from scratch or &lt;a href="https://github.com/jsverify/jsverify#shrink-functions"&gt;derived from existing shrinks&lt;/a&gt;. The derivation method is &lt;code&gt;smap&lt;/code&gt;, like with arbitraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(shrink a).smap(f: a -&amp;gt; b, g: b -&amp;gt; a): shrink b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkEven&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;smap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// convert nat to even&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="c1"&gt;// convert even to nat&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shrinkEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// [ 16, 24, 28, 30 ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Earlier, we defined our own &lt;code&gt;generator [array bool, nat]&lt;/code&gt; function for constructing pairs of random arrays with random valid indexes (less than the array length). A corresponding shrink would have to preserve the property that the &lt;code&gt;nat&lt;/code&gt; value remains a valid index. In this case, a first attempt might re-use existing shrinks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Looks good, but there is an error…&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkArrIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bless&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// shrink arrays, ensure valid index&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkArrBool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nearray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkArrs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shrinkArrBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkArrsWithIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shrunkArrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;shrunkArr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shrunkArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;shrunkArr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validIdx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// shrink index, re-use existing array&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdxs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdxsWithArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdxs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;shrunkIdx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// flat list of shrunk values? nope, this breaks:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;shrunkArrsWithIdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;shrunkIdxsWithArr&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, this fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeError: shrunkArrsWithIdx is not iterable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How odd – doesn't a shrink function return an array? That's what the type annotation seems to promise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"shrink is a function &lt;code&gt;a -&amp;gt; [a]&lt;/code&gt;, returning smaller values."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In reality, though, the array-based shrinks &lt;a href="https://github.com/jsverify/jsverify/blob/c03a67efe525e79ec37b3f314fc9f6a30182be70/lib/shrink.js#L189-L197"&gt;currently return &lt;em&gt;lazy sequences&lt;/em&gt;&lt;/a&gt; as defined by &lt;a href="https://github.com/phadej/lazy-seq"&gt;the &lt;code&gt;lazy-seq&lt;/code&gt; package&lt;/a&gt;, by the same author as JSVerify. This improves the performance of shrinking arrays, which could otherwise be combinatorially expensive.&lt;/p&gt;

&lt;p&gt;Looking at the &lt;a href="https://github.com/phadej/lazy-seq#api"&gt;&lt;code&gt;lazy-seq&lt;/code&gt; API docs&lt;/a&gt;, we can see that lazy sequences can be combined using an &lt;code&gt;append&lt;/code&gt; method – so that's what we'll do here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const shrinkArrIdx = jsc.shrink.bless(([arr, idx]) =&amp;gt; {
&lt;/span&gt;    if (!arr.length) return []
    const shrinkArrBool = jsc.shrink.nearray(jsc.bool.shrink)
    const shrunkArrs = shrinkArrBool(arr)
    const shrunkArrsWithIdx = shrunkArrs.map((shrunkArr) =&amp;gt; {
        const validIdx = Math.min(shrunkArr.length - 1, idx)
        return [shrunkArr, validIdx]
    })
    const shrunkIdxs = jsc.nat.shrink(idx)
    const shrunkIdxsWithArr = shrunkIdxs.map((shrunkIdx) =&amp;gt; {
        return [arr, shrunkIdx]
    })
&lt;span class="gd"&gt;-   return [...shrunkArrsWithIdx, ...shrunkIdxsWithArr]
&lt;/span&gt;&lt;span class="gi"&gt;+   return shrunkArrsWithIdx.append(shrunkIdxsWithArr)
&lt;/span&gt;&lt;span class="err"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not yet documented in JSVerify, so again be aware that the use of &lt;code&gt;lazy-seq&lt;/code&gt; methods on shrunk arrays may not be officially supported or subject to &lt;a href="https://semver.org/"&gt;SEMVER&lt;/a&gt; rules. &lt;a href="https://github.com/jsverify/jsverify/issues/297"&gt;Cf. issue #297&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting It All Together
&lt;/h2&gt;

&lt;p&gt;Below is a complete, working implementation of our relatively involved &lt;code&gt;arbitrary &amp;lt;array bool, index&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// generator &amp;lt;array bool, index&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genArrIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nearray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;flatMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrBools&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;maxIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrBools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxIdx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;arbIdx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arrBools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// shrink &amp;lt;array bool, index&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkArrIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bless&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// shrink arrays, ensure valid index&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkArrBool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nearray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkArrs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shrinkArrBool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkArrsWithIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shrunkArrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;shrunkArr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shrunkArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;shrunkArr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validIdx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// shrink index, re-use existing array&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdxs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdxsWithArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdxs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;shrunkIdx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shrunkIdx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// lazy sequence of shrunk values&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;shrunkArrsWithIdx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shrunkIdxsWithArr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// arbitrary &amp;lt;array bool, index&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbArrIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bless&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;genArrIdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;shrinkArrIdx&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The moral of the story here might be "arbitraries whose generators sequence other generators are more trouble than they are worth." Of course, it will depend on the actual problem at hand, and in practice, it seems that such sequenced generators are not often needed. Much of the time, a new arbitrary value can be derived using &lt;code&gt;smap&lt;/code&gt;. Also, strictly speaking an arbitrary may omit the shrink, but that reduces the usefulness of property testing to an extent. Ultimately it is up to the developer to weigh the options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Arbitraries: "blessed" objects with generator, shrink, and show fns

&lt;ul&gt;
&lt;li&gt;JSVerify ships with a selection of primitive (atomic) arbitraries like &lt;code&gt;jsc.nat&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Combine arbitraries into more complex arbitraries using combinator functions like &lt;code&gt;jsc.array&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Transform arbitraries into new arbitraries using the &lt;code&gt;.smap&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Define custom arbitraries from complete scratch by using the &lt;code&gt;jsc.bless&lt;/code&gt; method on an object wrapping a generator, shrink, and optional show function.&lt;/li&gt;
&lt;li&gt;Arbitraries can be passed in directly to &lt;code&gt;forall&lt;/code&gt;, or else referenced by string DSL name with the help of an &lt;code&gt;env&lt;/code&gt; argument.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Generators: "blessed" functions from size to pseudorandom data

&lt;ul&gt;
&lt;li&gt;The generators for built-in arbitraries can be accessed as &lt;code&gt;jsc.ARB_NAME.generator&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Combine generators using provided combinators such as &lt;code&gt;jsc.generator.array&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Transform generators using the &lt;code&gt;map&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Sequence generators using the &lt;code&gt;flatMap&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Define custom from-scratch generators by calling &lt;code&gt;jsc.generator.bless&lt;/code&gt; on a function from size to random data.&lt;/li&gt;
&lt;li&gt;Randomness in a from-scratch generator should be accomplished using &lt;code&gt;jsc.random&lt;/code&gt; and/or by calling existing generators with the &lt;code&gt;size&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Shrinks: "blessed" functions from data to a collection of smaller data

&lt;ul&gt;
&lt;li&gt;The shrinks for built-in arbitraries can be accessed as &lt;code&gt;jsc.ARB_NAME.shrink&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Combine shrinks using provided combinators such as &lt;code&gt;jsc.shrink.array&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Transform shrinks using the &lt;code&gt;smap&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Define custom from-scratch shrinks by calling &lt;code&gt;jsc.shrink.bless&lt;/code&gt; on a function from data to arrays (or &lt;code&gt;lazy-seq&lt;/code&gt; values) of "smaller" values.&lt;/li&gt;
&lt;li&gt;A good shrink should put small and/or likely-to-fail values near the start of the output collection.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Shows: functions from data to a string

&lt;ul&gt;
&lt;li&gt;The default &lt;code&gt;show&lt;/code&gt; function is &lt;code&gt;JSON.stringify&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;It is good practice, though not absolutely required, for a &lt;code&gt;show&lt;/code&gt; function to output valid JS code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using existing arbitrary values is quick, easy, and powerful on its own. Combinators and &lt;code&gt;smap&lt;/code&gt; can also sometimes be a relatively painless way to yield the arbitrary value desired. More advanced use cases, building up complex data with interdependencies, can require more fluent wielding of &lt;code&gt;flatMap&lt;/code&gt; and/or manual definition of the shrink function. However, the benefits of having a fully-defined arbitrary for your property tests might be worth the extra difficulty.&lt;/p&gt;

&lt;p&gt;At its best, property testing can provide a large amount of value and confidence for a small degree of effort and code. It is my hope that with greater knowledge of this approach in the JavaScript community, libraries like JSVerify may be more widely explored, maintained, extended and supported. Consider using JSVerify to augment your next project's test suite – you might find it catching mistakes you wouldn't have noticed with just a few unit tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Addendum
&lt;/h3&gt;

&lt;p&gt;In the process of writing this article, I came to appreciate that JSVerify is useful but also has a few rough edges and outstanding issues. I would encourage anyone interested in JS property testing to also take a look at some of the competing tools in this space, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dubzzz/fast-check/"&gt;Fast-Check&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/leebyron/testcheck-js"&gt;TestCheck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jsverify</category>
      <category>quickcheck</category>
      <category>testing</category>
      <category>functional</category>
    </item>
    <item>
      <title>Property Testing with JSVerify · Part II</title>
      <dc:creator>Gabriel Lebec</dc:creator>
      <pubDate>Mon, 25 Mar 2019 02:21:31 +0000</pubDate>
      <link>https://dev.to/glebec/property-testing-with-jsverify-part-ii-1jcg</link>
      <guid>https://dev.to/glebec/property-testing-with-jsverify-part-ii-1jcg</guid>
      <description>&lt;h1&gt;
  
  
  Part II: JSVerify Docs and Details
&lt;/h1&gt;

&lt;p&gt;In &lt;a href="https://dev.to/glebec/property-testing-with-jsverify-part-i-3one"&gt;Part I&lt;/a&gt; we explored what property checking is, its benefits over traditional unit testing, and saw some of the basics of using the JSVerify library.&lt;/p&gt;

&lt;p&gt;JSVerify's official description is "Property-based checking. Like QuickCheck." Since QuickCheck is a &lt;a href="http://haskell.org"&gt;Haskell&lt;/a&gt; library, JSVerify uses functional jargon and idioms that may be unfamiliar to JavaScript developers. In Part II, we take a close look at the language and concepts of &lt;a href="https://github.com/jsverify/jsverify#readme"&gt;JSVerify's API documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Documentation
&lt;/h2&gt;

&lt;p&gt;Functional programming and static types are highly complementary. Type signatures specify sets of allowed inputs and resulting outputs for a given function, which in turn inform the programmer how functions can be used and combined.&lt;/p&gt;

&lt;p&gt;In the JSVerify docs, "types and function signatures are written in Coq/Haskell-influenced style". One of the best explanations of Haskell-style type signatures in JS is the &lt;a href="https://github.com/ramda/ramda/wiki/Type-Signatures"&gt;Ramda Wiki&lt;/a&gt;. However, JSVerify's style differs somewhat from Ramda, so below is a short introduction to its particular type syntax.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Documentation&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x : y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;x&lt;/code&gt; is of type &lt;code&gt;y&lt;/code&gt; / must be of type &lt;code&gt;y&lt;/code&gt; / returns type &lt;code&gt;y&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;myFunc(   )&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A library method with the name &lt;code&gt;myFunc&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;myFunc(thing: string) : bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;myFunc&lt;/code&gt; takes a parameter &lt;code&gt;thing&lt;/code&gt; which must be a &lt;code&gt;string&lt;/code&gt;, and returns a &lt;code&gt;bool&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;any type at all, so long as it consistent with other "&lt;code&gt;a&lt;/code&gt;"s in the type signature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a -&amp;gt; [a]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A (possibly-anonymous) function which takes in a param of any type &lt;code&gt;a&lt;/code&gt; and returns an array of &lt;code&gt;a&lt;/code&gt;-type values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a -&amp;gt; array a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same as above&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a -&amp;gt; b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A function which takes in params of any type &lt;code&gt;a&lt;/code&gt; and returns values of any type &lt;code&gt;b&lt;/code&gt; (possibly the same as &lt;code&gt;a&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;message: string?&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;An &lt;strong&gt;optional&lt;/strong&gt; parameter &lt;code&gt;message&lt;/code&gt; that must be a &lt;code&gt;string&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a variadic number of additional arguments or elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;= true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a default value for the preceding parameter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;arbLike: {…}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;a parameter &lt;code&gt;arbLike&lt;/code&gt; which must be an Object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;{ b: bool }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;an object whose &lt;code&gt;b&lt;/code&gt; property is of type &lt;code&gt;bool&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;void&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here is an actual line from the documentation, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assert(prop: property, opts: checkoptions?) : void
  ^      ^       ^       ^         ^     ^      ^
  A      B       C       D         E     F      G

A. documenting the `jsc.assert` function
B. first parameter, named `prop`
C. `prop` must be of type `property` (see below)
D. second parameter, named `opts`
E. `opts` must be of type `checkoptions` (see below)
F. `opts` is an optional parameter
G. `jsc.assert` returns `void` (i.e. `undefined`)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key JSVerify Types
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;property&lt;/code&gt; and &lt;code&gt;checkoptions&lt;/code&gt; types above certainly don't sound like the more familiar &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, etc. In typed functional languages, we often invent our own types as needed to be concise yet unambiguous about which functions work with which values.&lt;/p&gt;

&lt;p&gt;Vanilla JS doesn't have a first-class notion of custom types. However, &lt;a href="https://github.com/jsverify/jsverify#types"&gt;JSVerify's docs&lt;/a&gt; use custom type names as aliases for the specific values returned from or expected by certain functions. Below are some of the most important examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;generator a&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"a function &lt;code&gt;(size: nat) -&amp;gt; a&lt;/code&gt;"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A &lt;em&gt;generator of type &lt;code&gt;a&lt;/code&gt;&lt;/em&gt; is any function mapping a "size" (natural number, int &amp;gt;= 0) to a pseudorandom value of type &lt;code&gt;a&lt;/code&gt;. For example, a function of type &lt;code&gt;generator string&lt;/code&gt; might map &lt;code&gt;0&lt;/code&gt; to the empty string, &lt;code&gt;1&lt;/code&gt; to a randomly-chosen character, and &lt;code&gt;2&lt;/code&gt; to a randomly-constructed two-character string.&lt;/p&gt;

&lt;p&gt;In reality, the &lt;code&gt;size&lt;/code&gt; input can be interpreted differently depending on the generator, and does not have to literally mean length or value. Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jsc.generator.array&lt;/code&gt;: the length of generated arrays will be up to the &lt;em&gt;logarithm&lt;/em&gt; of the size param. This is presumably a performance-related restriction.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jsc.number.generator&lt;/code&gt;: size is the maximum absolute value, e.g. a size of &lt;code&gt;5&lt;/code&gt; could result in any number between &lt;code&gt;-5&lt;/code&gt; and &lt;code&gt;+5&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jsc.bool.generator&lt;/code&gt;: the size parameter is ignored, and each bool is returned at a probability of 0.5.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example `generator hydra`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;generatorHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Deterministic Randomness
&lt;/h4&gt;

&lt;p&gt;A major feature of QuickCheck-like property testing libraries is that they are deterministically pseudorandom. Given a seed string (via the options object for &lt;code&gt;jsc.assert&lt;/code&gt;, or the &lt;code&gt;--jsverifyRngState&lt;/code&gt; CLI flag), they will reproduce failing test cases exactly, helping the developer to investigate the failure.&lt;/p&gt;

&lt;p&gt;When implementing a custom generator, it is important to adhere to this implementation detail, and &lt;strong&gt;not&lt;/strong&gt; use &lt;code&gt;Math.random&lt;/code&gt;. JSVerify provides utility functions &lt;a href="https://github.com/jsverify/jsverify#random-functions"&gt;&lt;code&gt;jsc.random&lt;/code&gt; and &lt;code&gt;jsc.random.number&lt;/code&gt;&lt;/a&gt; instead, which internally use the seed to produce replicable results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomGreetingGenerator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ignoredSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pseudoRandomIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;pseudoRandomIndex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;shrink a&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"a function &lt;code&gt;a -&amp;gt; [a]&lt;/code&gt;, returning &lt;em&gt;smaller&lt;/em&gt; values"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A &lt;em&gt;shrink of type &lt;code&gt;a&lt;/code&gt;&lt;/em&gt; is a function which given a value of type &lt;code&gt;a&lt;/code&gt; returns an array of "smaller" values of type &lt;code&gt;a&lt;/code&gt;. "Smaller" is an abstract concept which will vary for each type, but in general will mean fewer elements, numbers closer to zero, etc.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jsc.shrink.integer&lt;/code&gt;: if the input integer &lt;code&gt;i&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, the shrink returns an empty array &lt;code&gt;[]&lt;/code&gt;; else, &lt;code&gt;i&lt;/code&gt; is mapped to the finite series &lt;code&gt;[0, ⌊1/2·i⌋, -⌊1/2·i⌋, ⌊3/4·i⌋, -⌊3/4·i⌋, …]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jsc.bool.shrink&lt;/code&gt;: in essence, &lt;code&gt;bool =&amp;gt; bool ? [false] : []&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jsc.elements.shrink&lt;/code&gt;: the elements generator returns randomly-selected values from an array, e.g. &lt;code&gt;[a, b, c]&lt;/code&gt;; the elements shrink returns the sub array to the left of whatever element is being shrunk. Shrinking &lt;code&gt;c&lt;/code&gt; would return &lt;code&gt;[a, b]&lt;/code&gt;; shrinking &lt;code&gt;a&lt;/code&gt; returns &lt;code&gt;[]&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example `shrink hydra`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="c1"&gt;// theoretically valid but impractically inefficient:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an input case fails a property check, JSVerify uses the shrink function to search for smaller cases that also fail. If JSVerify finds that an early value in the output array fails, it can skip property-checking and shrinking of the later values. Good shrinks therefore place small, likely-to-fail values near the start of their output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example `shrink hydra`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shrinkHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="c1"&gt;// a more practical shrink:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// a common &amp;amp; minimal edge case&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// potential time-saver&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// thorough search&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;show&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"a function &lt;code&gt;a -&amp;gt; string&lt;/code&gt;"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In Haskell, the &lt;code&gt;show&lt;/code&gt; function converts any data structure in the &lt;code&gt;Show&lt;/code&gt; class to a &lt;code&gt;String&lt;/code&gt;. Best practice is for the string to be valid Haskell code, so you could reconstruct the data by copying the string into your program.&lt;/p&gt;

&lt;p&gt;For JSVerify, &lt;code&gt;show&lt;/code&gt; will be called whenever a failing case is reported, with the resulting string included in the error message as the &lt;code&gt;counterexample&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jsc.show.array&lt;/code&gt;: essentially &lt;code&gt;arr =&amp;gt; '[' + arr.join(', ') + ']'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;by default, most built-in &lt;code&gt;show&lt;/code&gt; functions are just &lt;code&gt;JSON.stringify&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example `show : hydra -&amp;gt; string`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`{ heads: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; }`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because failing cases can be replicated using the reported PRNG seed, it is not strictly necessary for &lt;code&gt;show&lt;/code&gt; to return valid JS code, but it is often good practice for the same reasons as in Haskell.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;arbitrary a&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"a triple of generator, shrink and show functions."&lt;br&gt;
&lt;code&gt;{generator: nat -&amp;gt; a, shrink: a -&amp;gt; array a, show: a -&amp;gt; string}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An &lt;em&gt;arbitrary value of type &lt;code&gt;a&lt;/code&gt;&lt;/em&gt; is a concept tying together the generator, shrink and show functions for a type &lt;code&gt;a&lt;/code&gt;. It is implemented in JSVerify via an object wrapping those three functions. For example, the &lt;code&gt;abitrary string&lt;/code&gt; type is any object which can generate, shrink, and show strings on demand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// example `arbitrary hydra`&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbitraryHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;generatorHydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;shrinkHydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showHydra&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some contexts, the shrink and show functions are actually optional. Without a shrink, however, JSVerify will be unable to simplify failing cases; they will be reported as they are.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;property&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;As of this writing, &lt;code&gt;property&lt;/code&gt; is used in at least three distinct ways in the JSVerify docs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to refer to the &lt;strong&gt;library method&lt;/strong&gt; &lt;code&gt;jsc.property&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;as the overall &lt;strong&gt;return type&lt;/strong&gt; for &lt;code&gt;jsc.forall&lt;/code&gt; (see &lt;code&gt;Y&lt;/code&gt; below)&lt;/li&gt;
&lt;li&gt;as the &lt;strong&gt;return type&lt;/strong&gt; for the &lt;code&gt;prop&lt;/code&gt; parameter of &lt;code&gt;forall&lt;/code&gt; (see &lt;code&gt;X&lt;/code&gt; below)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forall(
    arbs: arbitrary a ...,
    userenv: (map arbitrary)?,
    prop : a -&amp;gt; property       // X
): property                    // Y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt; do not actually refer to the same type, so in my humble opinion &lt;a href="https://github.com/jsverify/jsverify/issues/295"&gt;the &lt;code&gt;X&lt;/code&gt; type should be renamed &lt;code&gt;verification&lt;/code&gt;&lt;/a&gt;. In the remainder of this article, a &lt;code&gt;property&lt;/code&gt; type will refer to &lt;code&gt;Y&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So what is this &lt;code&gt;property&lt;/code&gt; type anyway? In short, &lt;code&gt;forall&lt;/code&gt; acts as a "property constructor", and other methods like &lt;code&gt;assert&lt;/code&gt; and &lt;code&gt;check&lt;/code&gt; act as "property consumers". In terms of official JS types, the values returned by &lt;code&gt;forall&lt;/code&gt; are of type &lt;code&gt;function&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prop_strSliceEql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;prop_strSliceEql&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it is not the role of the developer to manually invoke a &lt;code&gt;property&lt;/code&gt;. Rather, &lt;code&gt;property&lt;/code&gt; values will be passed to &lt;code&gt;check&lt;/code&gt; or &lt;code&gt;assert&lt;/code&gt; to actually use them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// assert(prop: property, opts: checkoptions?) : void&lt;/span&gt;
&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop_strSliceEql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// runs without error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Being able to navigate type-based documentation, noting which function outputs and inputs line up, is a key skill in the typed functional programming world. It isn't actually necessary for us to know how &lt;code&gt;property&lt;/code&gt;-type values are implemented, because they are an intermediate value both produced by and consumed by JSVerify library methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;forall( ... ) → property
                   ↓
         assert(property, ...) → void
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verification (unofficial)
&lt;/h3&gt;

&lt;p&gt;As mentioned above, the &lt;code&gt;property&lt;/code&gt; returned from &lt;code&gt;prop&lt;/code&gt; and the &lt;code&gt;property&lt;/code&gt; returned from &lt;code&gt;forall&lt;/code&gt; are not the same type, so for our purposes we will (informally) refer to the former as "verifications."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;forall(
&lt;/span&gt;    arbs: arbitrary a ...,
    userenv: (map arbitrary)?,
&lt;span class="gd"&gt;-   prop : a -&amp;gt; property
&lt;/span&gt;&lt;span class="gi"&gt;+   prop : a -&amp;gt; verification
&lt;/span&gt;&lt;span class="err"&gt;):&lt;/span&gt; property
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verification values can be any type at all, but JSVerify exhibits different behaviors depending on the type:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Verification&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;property is considered verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;falsy values&lt;/td&gt;
&lt;td&gt;property is considered failed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;most truthy values&lt;/td&gt;
&lt;td&gt;property is considered failed, with the value appended to the error message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;thenable which fulfills&lt;/td&gt;
&lt;td&gt;property depends on fulfillment value (see above)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;thenable which rejects&lt;/td&gt;
&lt;td&gt;property is considered failed, with the reason appended to the error message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;function&lt;/td&gt;
&lt;td&gt;property verification depends on function return value&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Some of the above behaviors are not explicitly documented, and may act in unspecified or unintended ways depending on usage. Caveat emptor.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;checkoptions&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The options object optionally object passed to &lt;code&gt;check&lt;/code&gt; or &lt;code&gt;assert&lt;/code&gt;, used to configure number of tests run, the size parameter for generators, an rng seed, etc. Documented &lt;a href="https://github.com/jsverify/jsverify#properties"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;env&lt;/code&gt; / &lt;code&gt;typeEnv&lt;/code&gt; / &lt;code&gt;map arbitrary&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;An optional argument to the following library methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;forall&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assertForall&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;checkForall&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;record&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;suchthat&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;env&lt;/code&gt; type is an object which maps &lt;strong&gt;names of arbitraries&lt;/strong&gt; (as string keys) to &lt;strong&gt;definitions for arbitraries&lt;/strong&gt; (as objects). For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arbitraryHydra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;generatorHydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;shrinkHydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showHydra&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// : env&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;arbitraryHydra&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Environment objects extend JSVerify's built-in DSL of arbitrary data (e.g. strings, numbers, arrays of arbitraries) with new, custom arbitraries. When you pass in an environment to &lt;code&gt;forall&lt;/code&gt;, it is merged with the defaults, so you can specify any mix of data from both sets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exampleProp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// asking for built-in `arbitrary natural`&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hydra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// asking for custom `arbitrary hydra`&lt;/span&gt;
    &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;               &lt;span class="c1"&gt;// object providing the `hydra` arbitrary&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// property verifier receiving both data&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;strong&gt;Note that the above example will not yet work,&lt;/strong&gt; because we have not covered JSVerify's concept of &lt;a href="https://github.com/jsverify/jsverify#blessing"&gt;"blessing"&lt;/a&gt; generators, shrinks, and arbitraries. We will cover the &lt;code&gt;bless&lt;/code&gt; methods later in &lt;a href="https://dev.to/glebec/property-testing-with-jsverify-part-iii-5bp0"&gt;Part III&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;On the other hand, instead of using the string DSL, you can pass custom arbitraries to &lt;code&gt;forall&lt;/code&gt; directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exampleProp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;             &lt;span class="c1"&gt;// asking for built-in `arbitrary natural`&lt;/span&gt;
    &lt;span class="nx"&gt;arbitraryHydra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// asking for custom `arbitrary hydra`&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// property verifier receiving both data&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hydra&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heads&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;nat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will see more about using the DSL vs. JS values in &lt;a href="https://dev.to/glebec/property-testing-with-jsverify-part-iii-5bp0"&gt;Part III&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>jsverify</category>
      <category>quickcheck</category>
      <category>testing</category>
      <category>functional</category>
    </item>
    <item>
      <title>Property Testing with JSVerify · Part I</title>
      <dc:creator>Gabriel Lebec</dc:creator>
      <pubDate>Mon, 25 Mar 2019 02:19:21 +0000</pubDate>
      <link>https://dev.to/glebec/property-testing-with-jsverify-part-i-3one</link>
      <guid>https://dev.to/glebec/property-testing-with-jsverify-part-i-3one</guid>
      <description>&lt;p&gt;&lt;strong&gt;Abstract&lt;/strong&gt;: &lt;a href="https://github.com/jsverify/jsverify"&gt;JSVerify&lt;/a&gt; is a JavaScript library for &lt;em&gt;property-based testing&lt;/em&gt;, inspired by the classic &lt;a href="https://www.haskell.org/"&gt;Haskell&lt;/a&gt; library &lt;a href="http://hackage.haskell.org/package/QuickCheck"&gt;QuickCheck&lt;/a&gt;. JSVerify's API documentation appears to assume a certain level of familiarity with "type tetris" and functional idioms like &lt;a href="https://fsharpforfunandprofit.com/posts/elevated-world-2/"&gt;monads&lt;/a&gt;. This article demonstrates the basics of the JSVerify library API, including how to create and use &lt;em&gt;arbitrary&lt;/em&gt; values, &lt;em&gt;data generators&lt;/em&gt;, and &lt;em&gt;data shrinks&lt;/em&gt;, in ways that a typical JavaScript developer can understand.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part I: What is Property Testing?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/John_Hughes_(computer_scientist)"&gt;John Hughes&lt;/a&gt;, one of the &lt;a href="http://users.cs.northwestern.edu/~robby/courses/395-495-2009-fall/quick.pdf"&gt;original authors&lt;/a&gt; of QuickCheck, gives a compelling demonstration of the power of property tests in the following video. Watch if you wish, or read on – we will cover the essentials further below.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/AfaNEebCDos"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In short, property tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Specify&lt;/strong&gt; expected laws (aka properties) for all intended inputs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate&lt;/strong&gt; large numbers of random inputs to check, usually via a convenient DSL or API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; that the expected properties hold for all generated cases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplify&lt;/strong&gt; failing cases progressively, to find a boundary that introduces the failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Property testing is a form of evidence by example that code might be correct, or is definitely incorrect. It lies between the two extremes of unit tests (manually-specified individual cases) and formal machine-checked logic proofs (impractical in some languages or systems).&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit Testing
&lt;/h2&gt;

&lt;p&gt;Let's consider a small example. If we wanted to verify the correctness of a custom &lt;code&gt;sort&lt;/code&gt; function, we might write a unit test in the form of a &lt;a href="https://www.chaijs.com/"&gt;Chai assertion&lt;/a&gt; executed via the &lt;a href="https://mochajs.org/"&gt;Mocha test framework&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;`sort`&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// unit test:&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transforms `[2, 1, 3]` to `[1, 2, 3]`&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deep&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;How confident are you that &lt;code&gt;sort&lt;/code&gt; is correct? Probably not very. &lt;code&gt;Sort&lt;/code&gt; could easily be broken &lt;em&gt;without&lt;/em&gt; failing this test, if it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;merely swaps the first two elements&lt;/li&gt;
&lt;li&gt;always returns &lt;code&gt;[1, 2, 3]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fails on two-digit numbers (or higher)&lt;/li&gt;
&lt;li&gt;fails on a list containing duplicate elements&lt;/li&gt;
&lt;li&gt;fails on lists with only the first (or last) item out of order&lt;/li&gt;
&lt;li&gt;fails on an empty list&lt;/li&gt;
&lt;li&gt;fails on lists of even length&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As humans, we tend to fall short of imagining every possible edge and corner case. This is partly because we make assumptions about how code will be used, focusing on the &lt;a href="https://en.wikipedia.org/wiki/Happy_path"&gt;happy path&lt;/a&gt;. Writing multiple unit tests for each of the above would help, but is a lot of work for only a moderate increase in confidence that &lt;code&gt;sort&lt;/code&gt; is generally correct.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ad-Hoc Property Testing via Dynamic Assertions
&lt;/h2&gt;

&lt;p&gt;When a programmer specifies that sorting &lt;code&gt;[2, 1, 3]&lt;/code&gt; returns &lt;code&gt;[1, 2, 3]&lt;/code&gt;, they don't necessarily care about that one specific array. Rather, the point is to verify certain properties (characteristics) of sorting, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sort&lt;/code&gt; results in an ordered array&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort&lt;/code&gt;ing an already-sorted array does nothing (idempotence)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort&lt;/code&gt; merely moves elements without addition, change, or removal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Such properties describe what actually matters conceptually, far more than any one specific case. Testing veterans will sometimes have developed ad-hoc techniques for confirming such concepts, for example by dynamically generating inputs and assertions.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TESTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LIMIT_LEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LIMIT_NUM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;LIMIT_NUM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;LIMIT_LEN&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;randomInt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isOrdered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;`sort`&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;TESTS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;outputs ordered arrays`&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isOrdered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;randomArr&lt;/span&gt;&lt;span class="p"&gt;())).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is a step in the direction of full-blown property testing, but if the spec fails, all we see is the following opaque message:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR: expected `false` to be `true`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;There are some nontrivial downsides to the above attempt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a lot of ad-hoc code for generating random inputs&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;randomArray&lt;/code&gt; function probably produced the empty list more than necessary (once suffices)&lt;/li&gt;
&lt;li&gt;did you notice that the &lt;code&gt;randomInt&lt;/code&gt; function never produces negative numbers? Oops!&lt;/li&gt;
&lt;li&gt;failure is non-instructive, what input caused it?&lt;/li&gt;
&lt;li&gt;what did &lt;code&gt;sort&lt;/code&gt; actually return for that input?&lt;/li&gt;
&lt;li&gt;if the random input which failed is large, which part of it actually caused the failure?&lt;/li&gt;
&lt;li&gt;if the suite is run multiple times, randomness means we may never encounter that failure case again&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of this can be mitigated, e.g. by &lt;a href="https://www.chaijs.com/guide/helpers/"&gt;writing custom Chai matchers&lt;/a&gt; (extra work), logging (polluting test output), or other means. However, some of these issues have already been addressed by property-testing systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  First-Class Property Testing with JSVerify
&lt;/h2&gt;

&lt;p&gt;Here is the same check for ordering, written using a dedicated generative testing library.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsverify&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isOrdered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;`sort`&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;outputs ordered arrays&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// property test:&lt;/span&gt;
        &lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[integer]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isOrdered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note that we did not need to write our own &lt;code&gt;randomInt&lt;/code&gt; and &lt;code&gt;randomArr&lt;/code&gt; functions – JSVerify handled this for us. Breaking it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;jsc.forall&lt;/code&gt; – the heart and soul of this library, it ties together data generators with a property-checking function; &lt;code&gt;forall&lt;/code&gt; returns a "Property" value (meant to be used by other JSVerify functions).

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'[integer]'&lt;/code&gt; – a string declaration of what data we want JSVerify to generate, specifically an &lt;em&gt;array of integers&lt;/em&gt;. &lt;a href="https://github.com/jsverify/jsverify#dsl-for-input-parameters"&gt;JSVerify parses a Domain-Specific Language (DSL)&lt;/a&gt; for describing input data (more on this later).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(arr) =&amp;gt; { ... }&lt;/code&gt; – a function which will receive the randomly-generated data, responsible for verifying the expected property by returning &lt;code&gt;true&lt;/code&gt; if that property holds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jsc.assert&lt;/code&gt; – takes the "Property" returned by &lt;code&gt;forall&lt;/code&gt;, and executes the logic it represents as an &lt;em&gt;assertion&lt;/em&gt; (throwing an error on failure). This lets JSVerify integrate with test frameworks like Mocha.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running this code gives us a more telling result:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Failed after 7 tests and 3 shrinks. rngState: 86ac1d5e6093784bf2;
Counterexample: [2, 10]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Interesting! What does it all mean?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Error&lt;/code&gt; – Mocha is reporting that our assertion failed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Failed after 7 tests&lt;/code&gt; – JSVerify generated six input cases before it discovered a seventh case that violated our property.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;and 3 shrinks.&lt;/code&gt; – The failing counterexample could be simplified in three steps to reach a minimal failing counterexample (JSVerify actually took more steps than this, but who's counting?).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rngState: 86ac1d5e6093784bf2;&lt;/code&gt; – JSVerify uses a seed-based pseudo-random generator to produce values. Unlike &lt;code&gt;Math.random()&lt;/code&gt;, we can deliberately use this seed to deterministically reproduce the failing test, if desired.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Counterexample: [2, 10]&lt;/code&gt;. JSVerify indicates that &lt;code&gt;[2, 10]&lt;/code&gt; is the smallest &lt;em&gt;input&lt;/em&gt; data it could find that failed our property check.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we (temporarily) instrument our code as follows, we can investigate a bit deeper:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;describe('`sort`', () =&amp;gt; {
&lt;/span&gt;    it('outputs ordered arrays', () =&amp;gt; {
        jsc.assert(jsc.forall('[integer]', (arr) =&amp;gt; {
            const output = sort(arr)
            const ok = isOrdered(output)
&lt;span class="gi"&gt;+           console.log(
+               ok ? '✔️' : '❌',
+              'input:', arr,
+              'output:', output
+           )
&lt;/span&gt;            return ok
&lt;span class="gd"&gt;-       }))
&lt;/span&gt;&lt;span class="gi"&gt;+       }), {
+           rngState: '86ac1d5e6093784bf2'
+       })
&lt;/span&gt;    })
&lt;span class="err"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note the second parameter to &lt;code&gt;jsc.assert&lt;/code&gt; is an &lt;strong&gt;options object&lt;/strong&gt; permitting us to manually set the pseudorandom seed, replicating the results we saw previously. (Alternatively, &lt;a href="https://github.com/jsverify/jsverify#usage-with-mocha"&gt;when using Mocha&lt;/a&gt; you can force the use of a particular &lt;code&gt;rngState&lt;/code&gt; using &lt;code&gt;--jsverifyRngState&lt;/code&gt;.) When this modified test is run, we see the following logged:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OK&lt;/th&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSVerify begins with "small" inputs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The first six cases are all ok.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[23]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[23]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-9, 33, 33, 18, 31]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-9, 18, 31, 33, 33]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[3]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[3]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[20, 9, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10, 20, 9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Oops! Our property failed on the seventh case.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[9, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10, 9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSVerify "shrinks" the array, but it still fails.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shrunk again, but now the prop holds. Back up.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSVerify shrinks the values &lt;em&gt;in&lt;/em&gt; the array. &lt;code&gt;9&lt;/code&gt; -&amp;gt; &lt;code&gt;0&lt;/code&gt; is still ok.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[4, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10, 4]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Halving &lt;code&gt;9&lt;/code&gt; -&amp;gt; &lt;code&gt;4&lt;/code&gt; fails, so shrinking restarts from here.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JSverify isn't perfect; we see some redundant checks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10, 2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Halving &lt;code&gt;4&lt;/code&gt; -&amp;gt; &lt;code&gt;2&lt;/code&gt; fails again; shrink from here.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;More redundant checks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[1, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[1, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This time, &lt;code&gt;2&lt;/code&gt; -&amp;gt; &lt;code&gt;1&lt;/code&gt; results in a passing output.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-1, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-1, 10]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What about negative ints? Still ok.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;From here on, JSVerify does a logarithmic search of integers between &lt;code&gt;-10&lt;/code&gt; and &lt;code&gt;10&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 0]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 5]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 5]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, -5]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-5, 2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 7]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 7]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, -7]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-7, 2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 8]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 8]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, -8]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-8, 2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, 9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✔️&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[2, -9]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[-9, 2]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No failures, so JSVerify concludes &lt;code&gt;[2, 10]&lt;/code&gt; is a minimal counterexample.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This experiment demonstrates several clever aspects of JSVerify's shrinking procedure for arrays of integers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It checks for both smaller arrays and smaller values in the array&lt;/li&gt;
&lt;li&gt;It checks commonly-neglected edge cases like &lt;code&gt;[]&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, and negative integers&lt;/li&gt;
&lt;li&gt;It uses binary search for good performance&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Diagnosing the Problem
&lt;/h2&gt;

&lt;p&gt;Revisiting our original test, the combination of global &lt;code&gt;it&lt;/code&gt; + &lt;code&gt;jsc.assert(jsc.forall(...))&lt;/code&gt; is common enough that JSVerify offers a &lt;code&gt;property&lt;/code&gt; method for it. (Using this convenience method means you can no longer pass in the options object to &lt;code&gt;assert&lt;/code&gt;, so keep that in mind.)&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;describe('`sort`', () =&amp;gt; {
&lt;/span&gt;&lt;span class="gd"&gt;-   it('outputs ordered arrays', () =&amp;gt; {
-       jsc.assert(jsc.forall('[integer]', (arr) =&amp;gt; {
-           return isOrdered(sort(arr))
-       }))
-   })
&lt;/span&gt;&lt;span class="gi"&gt;+   jsc.property('outputs ordered arrays', '[string]', (arr) =&amp;gt; {
+       return isOrdered(sort(arr))
+   })
&lt;/span&gt;&lt;span class="err"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Manually running our test suite (without fixing the PRNG seed) multiple times eventually generates at least two distinct minimal failing input cases for us to consider:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Failed after 4 tests and 13 shrinks. rngState: 04214a57f39806becd;
Counterexample: [2, 10]
...
Error: Failed after 1 tests and 8 shrinks. rngState: 0092ae01573f6d84bc;
Counterexample: [-1, -2]
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Sorting aficionados may already have figured out what's going on – like &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;&lt;code&gt;Array#sort&lt;/code&gt;&lt;/a&gt;, our &lt;code&gt;sort&lt;/code&gt; operates &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Description"&gt;&lt;em&gt;lexicographically&lt;/em&gt; rather than &lt;em&gt;numerically&lt;/em&gt;&lt;/a&gt;. If the developer didn't intuit this issue, they could manually trace the logic of their sorting function on these inputs, either on paper or using debugging tools. Since JSVerify "shrunk" the counterexamples, debugging them will be simpler than if the original failure was reported.&lt;/p&gt;
&lt;h3&gt;
  
  
  But Wait, There's More!™ Check Out This One Weird Trick™
&lt;/h3&gt;

&lt;p&gt;There is (apparently undocumented, as of yet) a feature that can make failure reporting more informative. If you return anything other than a boolean from your property check, it is appended as a string to the error message. This lets us include the &lt;strong&gt;output&lt;/strong&gt; (or anything else we care to log) upon failure.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;jsc.property('outputs ordered arrays', '[string]', (arr) =&amp;gt; {
&lt;/span&gt;    const output = sort(arr)
    return isOrdered(output)
&lt;span class="gi"&gt;+       ? true
+       : 'sort returned ' + JSON.stringify(output)
&lt;/span&gt;&lt;span class="err"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Failed after 2 tests and 14 shrinks. rngState: 86fd6b284e01a5c793;
Counterexample: [2, 10]; Error: sort returned [10,2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Summary &amp;amp; Try It Yourself
&lt;/h2&gt;

&lt;p&gt;In this first part, we saw the fundamentals of generative testing and getting started with JSVerify. In &lt;a href="https://dev.to/glebec/property-testing-with-jsverify-part-ii-1jcg"&gt;Part II&lt;/a&gt;, we will explore the JSVerify API in greater depth. Before doing so, however, try using JSVerify yourself below:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const jsc = require('jsverify')

// https://en.wikipedia.org/wiki/De_Morgan%27s_laws
const deMorgansLawsHold = (p, q) =&amp;gt; {
    theorem1 = !(p &amp;amp;&amp;amp; q) === (!p || !q)
    theorem2 = !(p || q) === (!p &amp;amp;&amp;amp; !q)
    return theorem1 &amp;amp;&amp;amp; theorem2
}

// A correct property
const result1 = jsc.check(jsc.forall(
    jsc.bool, jsc.bool,
    deMorgansLawsHold
), { quiet: true }) // silences console logs

// An incorrect property
const result2 = jsc.check(jsc.forall(
    jsc.nearray(jsc.bool),
    (nonEmptyArrBools) =&amp;gt; {
        const idxOfFalse = nonEmptyArrBools.indexOf(false)
        return (idxOfFalse &amp;gt;= 0)
            ? true
            : 'indexOf found false at: ' + idxOfFalse
    }
), { quiet: true })

// Predict! Is this property correct or incorrect? Try it and see…
const result3 = jsc.check(jsc.forall(
    '[json]', 'json',
    // jsc.array(jsc.json), jsc.json, // equivalent spec
    (arr, jsVal) =&amp;gt; {
        const newArr = arr.concat(jsVal)
        return newArr.length === arr.length + 1
    }
), { quiet: true })

console.log("de Morgan's laws hold?", result1)
console.log("index of false in a nonempty array is at least 0?", result2)
console.log("concatenating on a random JS value increases length by 1?", result3)

  &lt;/code&gt;
&lt;/div&gt;



</description>
      <category>jsverify</category>
      <category>quickcheck</category>
      <category>testing</category>
      <category>functional</category>
    </item>
    <item>
      <title>Four Ways to Immutability in JavaScript</title>
      <dc:creator>Gabriel Lebec</dc:creator>
      <pubDate>Wed, 13 Feb 2019 00:13:16 +0000</pubDate>
      <link>https://dev.to/glebec/four-ways-to-immutability-in-javascript-3b3l</link>
      <guid>https://dev.to/glebec/four-ways-to-immutability-in-javascript-3b3l</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;This article presents four different techniques to immutably update data structures in JavaScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Natively, using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax" rel="noopener noreferrer"&gt;spread syntax&lt;/a&gt; and other features&lt;/li&gt;
&lt;li&gt;Via Ramda's &lt;a href="https://ramdajs.com/docs/#lens" rel="noopener noreferrer"&gt;&lt;code&gt;lens&lt;/code&gt;&lt;/a&gt; abstraction&lt;/li&gt;
&lt;li&gt;Via Michel Weststrate's &lt;a href="https://github.com/mweststrate/immer" rel="noopener noreferrer"&gt;&lt;code&gt;immer&lt;/code&gt;&lt;/a&gt; library&lt;/li&gt;
&lt;li&gt;Via Facebook's &lt;a href="https://facebook.github.io/immutable-js/" rel="noopener noreferrer"&gt;&lt;code&gt;immutable&lt;/code&gt;&lt;/a&gt; library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many of the code snippets are runnable and editable, and you are encouraged to experiment with them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Functional programming techniques and design patterns are increasingly popular in JavaScript applications. Tools and frameworks such as &lt;a href="https://rxjs-dev.firebaseapp.com/" rel="noopener noreferrer"&gt;RxJS&lt;/a&gt;, &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt;, and &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt; take inspiration from &lt;a href="https://en.wikipedia.org/wiki/Functional_reactive_programming" rel="noopener noreferrer"&gt;functional reactive programming&lt;/a&gt;, for example.&lt;/p&gt;

&lt;p&gt;Among the many varied features of FP, the interrelated facets of &lt;a href="https://en.wikipedia.org/wiki/Pure_function" rel="noopener noreferrer"&gt;purity&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Immutable_object" rel="noopener noreferrer"&gt;immutability&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/Persistent_data_structure" rel="noopener noreferrer"&gt;persistent data structures&lt;/a&gt; yield benefits such as &lt;a href="https://en.wikipedia.org/wiki/Referential_transparency" rel="noopener noreferrer"&gt;referential transparency&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Idempotence" rel="noopener noreferrer"&gt;idempotence&lt;/a&gt;. To put it simply, avoiding mutation and side effects makes code easier to reason about and compose.&lt;/p&gt;

&lt;p&gt;JavaScript is a &lt;a href="https://en.wikipedia.org/wiki/Comparison_of_multi-paradigm_programming_languages#cite_ref-44" rel="noopener noreferrer"&gt;multi-paradigm&lt;/a&gt; programming language. It allows for functional approaches, but without the convenience or guarantees found in some dedicated functional languages. Accordingly, a JS developer must take special care if they intend to update data without mutation. For example, a &lt;a href="https://redux.js.org/basics/reducers" rel="noopener noreferrer"&gt;Redux reducer&lt;/a&gt; "must &lt;strong&gt;never&lt;/strong&gt; mutate its arguments, perform side effects…, [or] call non-pure functions", but Redux itself provides no tools for adhering to those strictures.&lt;/p&gt;

&lt;p&gt;This article will not focus on the benefits of immutability, but rather explore how it can be achieved in JS if desired.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is an Immutable Update
&lt;/h1&gt;

&lt;p&gt;Consider a function which increments the &lt;code&gt;.counter&lt;/code&gt; property of an object:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const obj1 = { bools: [true, false], counter: 7 }
const obj2 = { bools: [false, true], counter: 3 }

function incrementObjCounter (obj) {
  // naive solution
  const newObj = {
    bools: obj.bools, // same reference
    counter: obj.counter + 1 // updated data
  }
  return newObj
}

const newObj1 = incrementObjCounter(obj1)
const newObj2 = incrementObjCounter(obj2)

console.log(obj1, newObj1) // different objects
console.log(obj2, newObj2) // different objects
console.log(obj1.bools === newObj1.bools) // shared reference
console.log(obj2.bools === newObj2.bools) // shared reference

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Rather than modify the original object, we generate a new object with changed data. Note that an even more naive solution might recursively &lt;em&gt;copy&lt;/em&gt; all the data in the original object. This is usually referred to as a &lt;a href="https://lodash.com/docs/4.17.11#cloneDeep" rel="noopener noreferrer"&gt;deep clone&lt;/a&gt;, and doubles the amount of memory in use.&lt;/p&gt;

&lt;p&gt;If we never intend to mutate the data in our base object, however, it can be safely &lt;em&gt;shared&lt;/em&gt; with the new object, as demonstrated with the &lt;code&gt;.bools&lt;/code&gt; property above. This &lt;em&gt;structural sharing&lt;/em&gt; means that an immutable update can often re-use existing memory.&lt;/p&gt;

&lt;p&gt;Unfortunately, the code above is brittle; it uses hard-coded property names even for data not being updated. The function is neither reusable for other object shapes nor easily maintainable.&lt;/p&gt;

&lt;h1&gt;
  
  
  Difficulties with Immutable Updates
&lt;/h1&gt;

&lt;p&gt;Suppose we have some nested data as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dino&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Denver&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dinosaur&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;friends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Wally&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;human&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;pets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Rocky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Casey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;human&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Perhaps we might want to give Wally a new pet rabbit of the form &lt;code&gt;{ name: 'Ears', type: 'rabbit' }&lt;/code&gt;. Give it a try; the &lt;code&gt;dino&lt;/code&gt; value is in scope in the following editable code block. Unlike in most real-world applications, we have &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze" rel="noopener noreferrer"&gt;deeply frozen&lt;/a&gt; &lt;code&gt;dino&lt;/code&gt; so you will know if you accidentally attempt to mutate it – an error will be thrown.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')
const test = (actual) =&amp;gt; registerTests(t =&amp;gt; {
    t.deepEqual(
        actual,
        {
          name: 'Denver',
          type: 'dinosaur',
          friends: [
            {
              name: 'Wally',
              type: 'human',
              pets: [
                {
                  name: 'Rocky',
                  type: 'dog'
                },
                {
                  name: 'Ears',
                  type: 'rabbit'
                }
              ]
            },
            {
              name: 'Casey',
              type: 'human'
            }
          ]
        }
    )
    t.end()
})
function deepFreeze(object) {
  var propNames = Object.getOwnPropertyNames(object);
  for (let name of propNames) {
    let value = object[name];
    object[name] = value;
    if ((typeof value) === 'object') { object[name] = deepFreeze(value) }
  }

return Object.freeze(object);
}
const dino = deepFreeze({
  name: 'Denver',
  type: 'dinosaur',
  friends: [
    {
      name: 'Wally',
      type: 'human',
      pets: [
        {
          name: 'Rocky',
          type: 'dog'
        }
      ]
    },
    {
      name: 'Casey',
      type: 'human'
    }
  ]
})

  &lt;/code&gt;
  &lt;code&gt;
    
await (function runTestInStrictMode () {
'use strict'; // using functional strict mode because of runkit limitations

// dino is in scope

const updatedDino = undefined; // give Wally a new pet rabbit!

return test(updatedDino);
})()

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;Did you manage to correctly generate a new dinosaur, without throwing any mutation-related errors? In an actual codebase, what is your confidence that you would have avoided those errors? Keep in mind that frequently, objects like this are not deeply frozen – they will silently accept mutation.&lt;/p&gt;

&lt;p&gt;For this challenge, we had you add an object. What about updating a deeply-nested object, or deleting one? Feel free to experiment below, then read on for some review.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
function deepFreeze(object) {
  var propNames = Object.getOwnPropertyNames(object);
  for (let name of propNames) {
    let value = object[name];
    object[name] = value;
    if ((typeof value) === 'object') { object[name] = deepFreeze(value) }
  }

return Object.freeze(object);
}
const dino = deepFreeze({
  name: 'Denver',
  type: 'dinosaur',
  friends: [
    {
      name: 'Wally',
      type: 'human',
      pets: [
        {
          name: 'Rocky',
          type: 'dog'
        }
      ]
    },
    {
      name: 'Casey',
      type: 'human'
    }
  ]
})

  &lt;/code&gt;
  &lt;code&gt;
    
(function runTestInStrictMode () {
'use strict'; // using functional strict mode because of runkit limitations

// dino is in scope

const dinoRenamedRocky = undefined // change dino.friends[0].pets[0].name

const dinoRemovedRocky = undefined // remove dino.friends[0].pets[0]

console.log(dino, dinoRenamedRocky, dinoRemovedRocky) // three different values
})()

  &lt;/code&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Review of Vanilla JS Behavior
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Primitives are Immutable (but also Re-assignable)
&lt;/h2&gt;

&lt;p&gt;JavaScript primitives (undefined, null, boolean, number, string, and symbol values) are immutable by default, so you are already prevented from permanently altering primitive values themselves.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const str = 'hello'
str[0] = 'j'        // silently ignores mutation attempt
console.log(str)    // "hello", not "jello"

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Of course, JavaScript does allow &lt;em&gt;re-assignment&lt;/em&gt; of shared &lt;strong&gt;variables&lt;/strong&gt;, which is not the same thing as mutation but which presents many of the same issues.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
let x = 5

badInc = () =&amp;gt; { x = x + 1; return x }
badDbl = () =&amp;gt; { x = x * 2; return x }

console.log(badInc(x) + badDbl(x)) // neither commutative nor idempotent

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Try commuting the terms in the above expression to &lt;code&gt;badDbl(x) + badInc(x)&lt;/code&gt; and re-running the code. Because of the statefulness inherent in re-binding the shared &lt;code&gt;x&lt;/code&gt; variable, we get different results, betraying our expectation of how addition works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Objects are Mutable (but also Freezable)
&lt;/h2&gt;

&lt;p&gt;Anything not of the primitive types listed above is considered an &lt;em&gt;object&lt;/em&gt; in JS – including arrays and functions. A common beginner misunderstanding with JavaScript is that &lt;code&gt;const&lt;/code&gt; declarations will prevent mutation. Not so; &lt;code&gt;const&lt;/code&gt; only prevents &lt;em&gt;re-assignment&lt;/em&gt;.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const obj = {}
const arr = []
const fnc = () =&amp;gt; {}

obj.mutated = true
arr.mutated = true
fnc.mutated = true

console.log(obj.mutated, arr.mutated, fnc.mutated) // true x 3

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;JavaScript does have the static method &lt;code&gt;Object.freeze(obj)&lt;/code&gt; to prevent re-assigning properties. In &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode" rel="noopener noreferrer"&gt;strict mode&lt;/a&gt;, attempting to set a property on a frozen object throws a helpful error. Sadly, in non-strict mode the attempt is merely rejected silently. (Note that &lt;code&gt;freeze&lt;/code&gt; itself mutates the object.)&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const obj = { example: 9000 }
obj.example++ // mutates obj

Object.freeze(obj) // mutates obj by freezing it
obj.example++ // silently ignored in non-strict mode (error in strict mode)

console.log(obj.example) // 9001, not 9002

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Beware, however – &lt;code&gt;freeze&lt;/code&gt; only prevents re-assigning top-level properties, and does not prevent mutating objects referenced in those properties. For that, you need a non-native "&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze" rel="noopener noreferrer"&gt;deep freeze&lt;/a&gt;" algorithm which recursively freezes objects.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const obj = { o: { x: 50 } }

Object.freeze(obj)

obj.o.x++ // still allowed
console.log(obj) // inner reference mutated, oops

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Freezing objects could help reveal and debug errors by failing early (upon mutation attempt) rather than late (when an unanticipated state yields incorrect behavior), at least in strict mode. In practice however, freezing is not very common, perhaps because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an author needs to predict that a given object is worth the extra effort of freezing, belying the &lt;a href="https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it" rel="noopener noreferrer"&gt;YAGNI&lt;/a&gt; principle&lt;/li&gt;
&lt;li&gt;deep freeze algorithms, like deep clone algorithms, have edge cases and pitfalls in JS (e.g. cycles, properly detecting objects)&lt;/li&gt;
&lt;li&gt;recursively freezing deeply-nested objects might be a performance concern (valid or not)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Approach 1: Native Immutable Updates
&lt;/h1&gt;

&lt;p&gt;So, what tools does JS provide when hoping to avoid mutation? As primitives are already immutable, and functions are infrequently used as mutable data containers, in practice the question is how to generate new versions of &lt;code&gt;Object&lt;/code&gt;s and &lt;code&gt;Array&lt;/code&gt;s. For those, we have several built-in methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax" rel="noopener noreferrer"&gt;Spread Syntax&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;As of ES2015, the spread &lt;code&gt;...&lt;/code&gt; operator has allowed for expanding &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols" rel="noopener noreferrer"&gt;iterable&lt;/a&gt; values into explicit arguments. When used inside new array or object literals, this permits copying the properties of existing values into the new value:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const obj1 = { type: 'data' }
const arr1 = [1, 2, 3]

const obj2 = { ...obj1, subtype: 'stuff' } // adds a key-val pair
const arr2 = [ ...arr1, 'cheese' ] // adds an element

// distinct old and new versions
console.log(obj1, obj2)
console.log(arr1, arr2)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;With objects in particular, this allows for easy &lt;em&gt;updating&lt;/em&gt; of a top-level key:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const obj1 = { type: 'data', age: 55 }

const obj2 = { ...obj1, age: obj1.age + 1 } // modified age

console.log(obj1, obj2)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;In some environments, object spread syntax may not be supported, but &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign" rel="noopener noreferrer"&gt;&lt;code&gt;Object.assign&lt;/code&gt;&lt;/a&gt; (also ES2015) may be available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Native Methods
&lt;/h2&gt;

&lt;p&gt;Spread makes it convenient to add new values to an array, add new key-value pairs to an object, or modify a key-value pair on an object. However, deletion of a key-value pair is not as straightforward. There are some tricks using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment" rel="noopener noreferrer"&gt;destructuring&lt;/a&gt; but they are not convenient when working with nested objects.&lt;/p&gt;

&lt;p&gt;When it comes to arrays, removing a specific element can be done via either &lt;code&gt;filter&lt;/code&gt;ing or &lt;code&gt;slice&lt;/code&gt;ing:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const arr = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
const newArrA = [...arr.slice(0, 2), ...arr.slice(3)]
const newArrB = arr.filter(color =&amp;gt; color !== 'yellow')
console.log(arr, newArrA, newArrB)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;While updating an array element can be accomplished with &lt;code&gt;slice&lt;/code&gt; or &lt;code&gt;map&lt;/code&gt;:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const arr = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
const newArrA = [...arr.slice(0, 2), 'sunshine', ...arr.slice(3)]
const newArrB = arr.map(color =&amp;gt; color === 'yellow' ? 'sunshine' : color)
console.log(arr, newArrA, newArrB)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;These methods work but are somewhat cumbersome and error-prone. And we are only dealing with shallow data; things become more difficult with nesting. Let's return to the original example from this article, adding a rabbit to Denver's friend Wally's list of pets. Here is one possible solution using vanilla JS:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const dino = {
  name: 'Denver',
  type: 'dinosaur',
  friends: [
    {
      name: 'Wally',
      type: 'human',
      pets: [
        {
          name: 'Rocky',
          type: 'dog'
        }
      ]
    },
    {
      name: 'Casey',
      type: 'human'
    }
  ]
}

  &lt;/code&gt;
  &lt;code&gt;
    
const updatedDino = {
  ...dino,
  friends: [
    {
      ...dino.friends[0],
      pets: [...dino.friends[0].pets, { name: 'Ears', type: 'rabbit' }]
    },
    ...dino.friends.slice(1)
  ]
}
console.log(dino, updatedDino)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;This works, but it has some notable downsides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is complex and verbose enough to be difficult to read, write, and maintain

&lt;ul&gt;
&lt;li&gt;frequent alternation between array and object spread makes it easy to lose track of what's going on&lt;/li&gt;
&lt;li&gt;the deeper into the object one goes, the higher the likelihood that reference chains grow (e.g. &lt;code&gt;pets: [...dino.friends[0].pets ]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;modifying one specific value in an array requires adding &lt;code&gt;map&lt;/code&gt; or &lt;code&gt;slice&lt;/code&gt; into the mix, increasing noise&lt;/li&gt;
&lt;li&gt;any mistakes in implementation will be silent mutation errors in practice, unless &lt;code&gt;dino&lt;/code&gt; is deeply frozen &lt;strong&gt;and&lt;/strong&gt; you are in strict mode&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;the performance is not ideal

&lt;ul&gt;
&lt;li&gt;spread syntax invokes the iteration protocol&lt;/li&gt;
&lt;li&gt;creating a copy of changed objects / arrays (e.g. the &lt;code&gt;pets&lt;/code&gt; and &lt;code&gt;friends&lt;/code&gt; arrays) is &lt;code&gt;O(n)&lt;/code&gt; time complexity&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Approach 2: &lt;a href="https://ramdajs.com/docs/#lens" rel="noopener noreferrer"&gt;Ramda &lt;code&gt;lens&lt;/code&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ekmett/lens/wiki/History-of-Lenses" rel="noopener noreferrer"&gt;Lenses&lt;/a&gt; are an approach to interacting with nested data that originate in &lt;a href="https://www.haskell.org/" rel="noopener noreferrer"&gt;Haskell&lt;/a&gt;, a lazy (and therefore of necessity pure) functional language with &lt;a href="https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system" rel="noopener noreferrer"&gt;Hindley-Milner&lt;/a&gt; inferred static typing. In that language, they are remarkably flexible and general tools that work across myriad data types seamlessly.&lt;/p&gt;

&lt;p&gt;Lenses and related tools are a deep topic, and in JavaScript we do not have the type restrictions that make lenses especially valuable in Haskell. However, the core idea is simple and useful enough that it makes an appearance in &lt;a href="https://ramdajs.com/" rel="noopener noreferrer"&gt;Ramda&lt;/a&gt;, a popular functional JS utility library.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-Level
&lt;/h2&gt;

&lt;p&gt;Conceptually, a lens is a pair of functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;em&gt;getter&lt;/em&gt; for a "focus" element &lt;code&gt;a&lt;/code&gt; that can be derived from some "source" data &lt;code&gt;s&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;em&gt;setter&lt;/em&gt; which can update &lt;code&gt;a&lt;/code&gt;, immutably generating a new &lt;code&gt;s&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In terms of implementation, a lens is actually a &lt;em&gt;single function&lt;/em&gt; which performs either of the above duties depending on how it is used. A given lens function is not invoked directly on the source; instead, helper functions like &lt;code&gt;view&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, and &lt;code&gt;over&lt;/code&gt; are responsible for correctly wielding the lens.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ramda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;extractedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someLens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sourceData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// NOT someLens(wrappingData)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Because lenses are individual functions, they can be directly &lt;a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-function-composition-20dfb109a1a0" rel="noopener noreferrer"&gt;composed&lt;/a&gt; together to form new lenses (an example of the &lt;a href="https://wiki.haskell.org/Combinator_pattern" rel="noopener noreferrer"&gt;combinator pattern&lt;/a&gt;).&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ramda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deepLens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outerLens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;innerLens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Demonstration
&lt;/h2&gt;

&lt;p&gt;Most commonly with Ramda, one will not write a lens from scratch but use methods like &lt;a href="https://ramdajs.com/docs/#lensIndex" rel="noopener noreferrer"&gt;&lt;code&gt;lensIndex&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://ramdajs.com/docs/#lensProp" rel="noopener noreferrer"&gt;&lt;code&gt;lensProp&lt;/code&gt;&lt;/a&gt; to generate correct lenses.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const dino = {
  name: 'Denver',
  type: 'dinosaur',
  friends: [
    {
      name: 'Wally',
      type: 'human',
      pets: [
        {
          name: 'Rocky',
          type: 'dog'
        }
      ]
    },
    {
      name: 'Casey',
      type: 'human'
    }
  ]
}

  &lt;/code&gt;
  &lt;code&gt;
    
const R = require('ramda')

// dino is in scope

// making a lens for the "friends" property
const friendsLens = R.lensProp('friends')

// viewing data using a lens
const friends = R.view(friendsLens, dino)
console.log(friends)

// immutably setting data using a lens
const lonelyDino = R.set(friendsLens, [], dino) // aww, no more friends
console.log(lonelyDino)

// immutably mapping data using a lens
const addEveryone = arr =&amp;gt; [...arr, 'everyone']
const popularDino = R.over(friendsLens, addEveryone, dino)
console.log(popularDino)

console.log(dino) // unchanged

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;over&lt;/code&gt; methods generate new data with the desired updates, but like Object/Array spread, the new values also share any non-updated references with the old values.&lt;/p&gt;

&lt;p&gt;All of this is well and good, but what about nested data? For that, standard right-to-left function composition can stitch together multiple lenses.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const dino = {
  name: 'Denver',
  type: 'dinosaur',
  friends: [
    {
      name: 'Wally',
      type: 'human',
      pets: [
        {
          name: 'Rocky',
          type: 'dog'
        }
      ]
    },
    {
      name: 'Casey',
      type: 'human'
    }
  ]
}

  &lt;/code&gt;
  &lt;code&gt;
    
const R = require('ramda')

// dino is in scope

// making some lenses
const friendsLens = R.lensProp('friends')
const lens0 = R.lensIndex(0)
const petsLens = R.lensProp('pets')
const nameLens = R.lensProp('name')

// stacking lenses together into a single lens
const frns0pets0name = R.compose(
  friendsLens,  // outermost lens first
  lens0,
  petsLens,
  lens0,
  nameLens      // innermost lens last
)

// viewing data using a lens
console.log(R.view(frns0pets0name, dino))

// immutably setting data using a lens
console.log(R.set(frns0pets0name, 'Spot', dino))

// immutably mapping data using a lens
console.log(R.over(frns0pets0name, (s =&amp;gt; s + '!'), dino))

console.log(dino) // unchanged

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Compared to our Object/Array spread + map technique, the above is far more concise, declarative, easy, and foolproof. But it gets even easier; composing together lenses to focus on a nested property chain is common, so Ramda provides a convenient &lt;a href="https://ramdajs.com/docs/#lensPath" rel="noopener noreferrer"&gt;&lt;code&gt;lensPath&lt;/code&gt;&lt;/a&gt; function.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const dino = {
  name: 'Denver',
  type: 'dinosaur',
  friends: [
    {
      name: 'Wally',
      type: 'human',
      pets: [
        {
          name: 'Rocky',
          type: 'dog'
        }
      ]
    },
    {
      name: 'Casey',
      type: 'human'
    }
  ]
}

  &lt;/code&gt;
  &lt;code&gt;
    
const R = require('ramda')

// dino is in scope
const frns0pets0name = R.lensPath(['friends', 0, 'pets', 0, 'name'])

console.log(R.set(frns0pets0name, 'Spot', dino))

console.log(dino) // unchanged

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;You can use this lens with &lt;code&gt;view&lt;/code&gt; and &lt;code&gt;over&lt;/code&gt; as well, of course – try for yourself. Ultimately, our final solution has been condensed down to two easy-to-read lines – one constructing the lens from a path, another using the lens to immutably set a deeply-nested property in some data.&lt;/p&gt;

&lt;h2&gt;
  
  
  All You Need is Lens?
&lt;/h2&gt;

&lt;p&gt;Lenses, being vanilla composable functions with multiple capabilities (read/update/set), are a highly functional solution with all the attendant tricks that implies: partial application, higher-order usage, first-class portability, dynamic behavior etc. However, while Ramda's lens functions make it easy to view, set, and map nested properties, deleting is a little more indirect; you must map over a parent prop using vanilla JS removal techniques:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const R = require('ramda')
const obj = { items: ['a', 'b'] }
const removeFirst = arr =&amp;gt; arr.slice(1)
const updated = R.over(R.lensProp('items'), removeFirst, obj)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;The basic instantiation and usage of lenses via a library like Ramda may be simple enough, but users should be aware that lenses and other "optics"* have some advanced uses and important gotchas. For example, lens-like functions which violate the &lt;a href="https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/a-little-lens-starter-tutorial#the-lens-laws-" rel="noopener noreferrer"&gt;lens laws&lt;/a&gt; can result in odd edge cases.&lt;/p&gt;

&lt;p&gt;*(&lt;em&gt;A subset of lenses are isomorphisms, which enable you to operate on data structures as if they were other (equivalent) data structures. There are also prisms, which enable interacting with data that may or may not be of a certain shape, and traversals, which can focus on multiple subparts at a time.&lt;/em&gt;)&lt;/p&gt;

&lt;h1&gt;
  
  
  Approach 3: &lt;a href="https://github.com/mweststrate/immer" rel="noopener noreferrer"&gt;Immer&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Some developers may prefer a more idiomatic approach to immutable updates in JS which doesn't involve importing a larger suite of tools or learning a new API. Michael Westrate's library &lt;a href="https://github.com/mweststrate/immer" rel="noopener noreferrer"&gt;Immer&lt;/a&gt; is purpose-built for just that.&lt;/p&gt;

&lt;p&gt;Immer's clever trick is to change what ordinarily-mutating actions &lt;em&gt;mean&lt;/em&gt; – intercepting assignment (&lt;code&gt;=&lt;/code&gt;), unsafe methods (&lt;code&gt;push&lt;/code&gt;), and other cases – in a form of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Meta_programming" rel="noopener noreferrer"&gt;metaprogramming&lt;/a&gt;. Specifically, it uses the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy" rel="noopener noreferrer"&gt;&lt;code&gt;Proxy&lt;/code&gt;&lt;/a&gt; constructor to create a "draft" version of your original object. You can mangle this draft at will, even mutating deeply-nested references directly. Instead of allowing those changes to actually occur, Immer transforms them into an aggregate immutable update on the original object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demonstration
&lt;/h2&gt;

&lt;p&gt;Immer's core function, &lt;code&gt;produce&lt;/code&gt;, has the following signature:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

produce(currentState, producer: (draftState) =&amp;gt; void): nextState


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const { produce } = require('immer')

const original = {
  color: 'blue',
  items: [5, 6],
  thing: { x: true },
  shared: {}
}

const updated = produce(original, (draft =&amp;gt; {
  draft.color = 'red'
  draft.items.push(917)
  delete draft.thing.x
  draft.thing.y = false
}))

console.log(original, updated) // no mutation
console.log(original.shared === updated.shared) // no naive copying

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;As the final &lt;code&gt;console.log&lt;/code&gt; above shows, Immer is using structural sharing just like our manual spread and Ramda lens solutions. The advantages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;new properties are automatically frozen in development mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;produce&lt;/code&gt; has a curried version for partial application&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;immer&lt;/code&gt; is a small single-purpose library&lt;/li&gt;
&lt;li&gt;no need to learn a new API (apart from the one function wrapper)&lt;/li&gt;
&lt;li&gt;no need to take special care in most cases, less cognitive overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  All You Need is Immer?
&lt;/h2&gt;

&lt;p&gt;While Immer is very slick, it is ultimately doing the same &lt;code&gt;Object.assign&lt;/code&gt; / spread / map type operations as our previous solutions. So while Immer benefits from structural sharing, some updates on large data may be slow (&lt;code&gt;O(n)&lt;/code&gt; to copy an array, for example). Also, &lt;a href="https://github.com/mweststrate/immer#supported-object-types" rel="noopener noreferrer"&gt;by default Immer only works on (certain properties of) plain arrays and objects&lt;/a&gt;, not other built-ins such as &lt;code&gt;Map&lt;/code&gt; and &lt;code&gt;Set&lt;/code&gt;. For other pitfalls, &lt;a href="https://github.com/mweststrate/immer#pitfalls" rel="noopener noreferrer"&gt;consult the docs&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Approach 4: &lt;a href="http://facebook.github.io/immutable-js/" rel="noopener noreferrer"&gt;Immutable.js&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;The three approaches we have examined so far all focus on essentially the same data structures – nested &lt;code&gt;Object&lt;/code&gt;s and &lt;code&gt;Array&lt;/code&gt;s. Native methods, lenses, and &lt;code&gt;immer&lt;/code&gt; all "play well with others" in the sense that other libraries and codebases will generally provide and expect such data types.&lt;/p&gt;

&lt;p&gt;One disadvantage of those structures, however, is that they were not purposefully designed with immutable updates in mind. To add an item to an array, you have to create a copy of the array with all other elements – an &lt;code&gt;O(n)&lt;/code&gt; operation. If you fail to take special care, you can call a native method like &lt;code&gt;sort&lt;/code&gt; without realizing it mutates the original data structure.&lt;/p&gt;

&lt;p&gt;An alternative approach is to switch to a &lt;a href="http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf" rel="noopener noreferrer"&gt;purely functional data structure&lt;/a&gt; (PDF link), or at least a data structure with efficient immutable update operations. Such data structures would expose an API of &lt;em&gt;only&lt;/em&gt; pure operations, reducing the chance of error.&lt;/p&gt;

&lt;p&gt;Facebook's library &lt;a href="http://facebook.github.io/immutable-js/" rel="noopener noreferrer"&gt;Immutable&lt;/a&gt; takes advantage of such structures. While they are implemented in vanilla JavaScript, the details are hidden from the user, who now interacts with classes such as &lt;code&gt;List&lt;/code&gt; and &lt;code&gt;Map&lt;/code&gt; (distinct from the ES2015 class of the same name). For large amounts of data, these entities are now much quicker to modify; for example, &lt;code&gt;Map&lt;/code&gt;'s set and get functions have &lt;code&gt;O(log32 n)&lt;/code&gt; time complexity, and &lt;code&gt;List&lt;/code&gt;'s &lt;code&gt;push&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt; methods are &lt;code&gt;O(1)&lt;/code&gt; despite returning a new updated list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demonstration
&lt;/h2&gt;

&lt;p&gt;Immutable is a large library with multiple classes, each of which has many methods. We will demonstrate just a small corner of that library, beginning with converting some typical JS data to a nested series of &lt;code&gt;Map&lt;/code&gt;s and &lt;code&gt;List&lt;/code&gt;s.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const dino = {
  name: 'Denver',
  type: 'dinosaur',
  friends: [
    {
      name: 'Wally',
      type: 'human',
      pets: [
        {
          name: 'Rocky',
          type: 'dog'
        }
      ]
    },
    {
      name: 'Casey',
      type: 'human'
    }
  ]
}

  &lt;/code&gt;
  &lt;code&gt;
    
const Immutable = require('immutable')

// dino is in scope
const immDino = Immutable.fromJS(dino)

// view nested (perhaps missing!) data
const dogName = immDino.getIn(['friends', 0, 'pets', 0, 'name'])
console.log(dogName)

// change nested data (immutably), perhaps at a brand new path
const immDino2 = immDino.setIn(['friends', 0, 'pets', 0, 'name'], 'Spot')
console.log(immDino2)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Some advantages are not directly demonstrated, but worth pointing out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if a property doesn't exist, &lt;code&gt;getIn&lt;/code&gt; will short-circuit and return &lt;code&gt;undefined&lt;/code&gt; rather than throwing a &lt;code&gt;cannot read x of undefined&lt;/code&gt; error&lt;/li&gt;
&lt;li&gt;if a property doesn't exist, &lt;code&gt;setIn&lt;/code&gt; will generate new &lt;code&gt;Map&lt;/code&gt; objects along the way&lt;/li&gt;
&lt;li&gt;there are many more things we can do with Immutable.js &lt;code&gt;Map&lt;/code&gt;s and &lt;code&gt;List&lt;/code&gt;s, such as &lt;code&gt;.map&lt;/code&gt;, &lt;code&gt;.push&lt;/code&gt;, &lt;code&gt;.sort&lt;/code&gt;, etc. – all in a pure, non-destructive way&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end, if some other library or framework requires a plain JS object or array, we can use &lt;code&gt;.toJS()&lt;/code&gt; to convert it back.&lt;/p&gt;

&lt;h2&gt;
  
  
  All You Need is Immutable?
&lt;/h2&gt;

&lt;p&gt;Performance and safety are the primary reasons to favor using &lt;code&gt;immutable&lt;/code&gt;, but as always there are tradeoffs to consider.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immutable requires developers to learn a new, relatively large API&lt;/li&gt;
&lt;li&gt;Debugging &lt;code&gt;immutable&lt;/code&gt; values is less ergonomic than plain objects and arrays&lt;/li&gt;
&lt;li&gt;Projects using Immutable classes may need to convert to and from simpler datatypes, potentially undoing the performance benefit&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  I Want it All
&lt;/h1&gt;

&lt;p&gt;Each of the approaches examined has pros and cons, as is often the case in programming. Thankfully, they are not mutually exclusive. For example, Brian Lonsdorf demonstrates using Ramda lenses to blend native objects/arrays with Immutable.js maps/lists in his article &lt;a href="https://medium.com/@drboolean/lenses-with-immutable-js-9bda85674780" rel="noopener noreferrer"&gt;Lenses with Immutable.js&lt;/a&gt;. Similarly, one might use array spread inside a function passed to Ramda &lt;code&gt;over&lt;/code&gt;, or inside a call to Immer's &lt;code&gt;produce&lt;/code&gt; function. Knowing multiple approaches allows you to reach for the abstraction that fits your use case.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Learning Curve&lt;/th&gt;
&lt;th&gt;Safety&lt;/th&gt;
&lt;th&gt;Performance&lt;/th&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;TL;DR&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax" rel="noopener noreferrer"&gt;Native&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;JS devs expected to know it, but takes time to master&lt;/td&gt;
&lt;td&gt;Poor, common source of errors&lt;/td&gt;
&lt;td&gt;Slow (linear) for large amounts of data&lt;/td&gt;
&lt;td&gt;Manually copy nested properties, &lt;code&gt;map&lt;/code&gt; / &lt;code&gt;filter&lt;/code&gt; / &lt;code&gt;slice&lt;/code&gt; to update or delete&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://ramdajs.com/docs/" rel="noopener noreferrer"&gt;Ramda (lenses)&lt;/a&gt; · &lt;a href="https://bundlephobia.com/result?p=ramda@0.26.1" rel="noopener noreferrer"&gt;(52 kB)&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Small number of concepts, but potentially alien to FP newbies&lt;/td&gt;
&lt;td&gt;Good, but be careful with paths&lt;/td&gt;
&lt;td&gt;Comparable to native&lt;/td&gt;
&lt;td&gt;Create lenses for nested data, use them with &lt;code&gt;view&lt;/code&gt; / &lt;code&gt;set&lt;/code&gt; / &lt;code&gt;over&lt;/code&gt;, manipulate via FP techniques (composition, partial application)&lt;/td&gt;
&lt;td&gt;Versatile patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://github.com/mweststrate/immer" rel="noopener noreferrer"&gt;Immer&lt;/a&gt; · &lt;a href="https://bundlephobia.com/result?p=immer@2.0.0" rel="noopener noreferrer"&gt;(13 kB)&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;One API method&lt;/td&gt;
&lt;td&gt;Good, but has some edge cases&lt;/td&gt;
&lt;td&gt;Comparable to native&lt;/td&gt;
&lt;td&gt;Use normally-mutating native actions on a draft object, actions instead become immutable updates&lt;/td&gt;
&lt;td&gt;Easy API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="http://facebook.github.io/immutable-js/" rel="noopener noreferrer"&gt;Immutable&lt;/a&gt; · &lt;a href="https://bundlephobia.com/result?p=immutable@4.0.0-rc.12" rel="noopener noreferrer"&gt;(63 kB)&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Larger library with many API methods&lt;/td&gt;
&lt;td&gt;Good, but be careful with paths&lt;/td&gt;
&lt;td&gt;Excellent per se, but slowed by conversion&lt;/td&gt;
&lt;td&gt;Use library's data structures and methods instead of native types, convert where necessary&lt;/td&gt;
&lt;td&gt;Faster algos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Addendum: Immutability via Function Encoding
&lt;/h2&gt;

&lt;p&gt;Prof. Dierk König brings up another technique for immutable data: store your data as functions.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1095617645767020544-673" src="https://platform.twitter.com/embed/Tweet.html?id=1095617645767020544"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1095617645767020544-673');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1095617645767020544&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;Vireo&lt;/em&gt; combinator (as it is named in Raymond Smullyan's famous book, &lt;a href="https://en.wikipedia.org/wiki/To_Mock_a_Mockingbird" rel="noopener noreferrer"&gt;To Mock a Mockingbird&lt;/a&gt;) is defined in JavaScript as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vireo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;When &lt;code&gt;vireo&lt;/code&gt; is applied twice (to two separate pieces of data), it returns a final function which has closed over both data points. The result is conceptually a pair of numbers, &lt;em&gt;stored as a function closure&lt;/em&gt;. To access to the stored numbers, a final function argument is provided:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const vireo = a =&amp;gt; b =&amp;gt; f =&amp;gt; f(a)(b)

  &lt;/code&gt;
  &lt;code&gt;
    
const pairOfNums = vireo(5)(8) // f =&amp;gt; f(5)(8)

pairOfNums(a =&amp;gt; b =&amp;gt; console.log(a)) // logs 5
pairOfNums(a =&amp;gt; b =&amp;gt; console.log(b)) // logs 8

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;Note that with this example, there is no way to actually modify the values once the pair is generated – the closure acts as a form of privileged data. How can we "update" such a pair? We make a new function which defers to old function:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const vireo = a =&amp;gt; b =&amp;gt; f =&amp;gt; f(a)(b)

  &lt;/code&gt;
  &lt;code&gt;
    
const pairOfNums = vireo(5)(8) // f =&amp;gt; f(5)(8)

const fst = a =&amp;gt; _ =&amp;gt; a
const snd = _ =&amp;gt; b =&amp;gt; b

const newPairWithSecondNumDoubled = f =&amp;gt; {
    const firstNum = pairOfNums(fst)
    const secondNum = pairOfNums(snd)
    return f(firstNum)(secondNum * 2)
}

console.log(
    newPairWithSecondNumDoubled(fst), // 5
    newPairWithSecondNumDoubled(snd)  // 16
)

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;To make this easier, we could write helper functions for getting, setting, and mapping…&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const vireo = a =&amp;gt; b =&amp;gt; f =&amp;gt; f(a)(b)

  &lt;/code&gt;
  &lt;code&gt;
    
const getL  = p =&amp;gt; p(l =&amp;gt; _ =&amp;gt; l)
const getR  = p =&amp;gt; p(_ =&amp;gt; r =&amp;gt; r)
const getLR = p =&amp;gt; p(l =&amp;gt; r =&amp;gt; [l, r])

const setL  = newL =&amp;gt; p =&amp;gt; vireo(newL)(getR(p))
const setR  = newR =&amp;gt; p =&amp;gt; vireo(getL(p))(newR)

const mapL  = transform =&amp;gt; p =&amp;gt; vireo(transform(getL(p)))(getR(p))
const mapR  = transform =&amp;gt; p =&amp;gt; vireo(getL(p))(transform(getR(p)))

const numPair = vireo(3)(7)

const show = pair =&amp;gt; console.log(getLR(pair))

show(numPair) // [3, 7]
show(setL(0)(numPair)) // [0, 7]
show(mapR(x =&amp;gt; x * 2)(numPair)) // [3, 14]

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Storing data through closures, and creating new functions which defer to old functions, can scale up to more complex data and also be made more idiomatic in JS; this is a large enough topic for its own article, however. If this approach intrigues you, Sandy Maquire's &lt;a href="https://leanpub.com/thinking-with-types" rel="noopener noreferrer"&gt;Thinking with Types&lt;/a&gt; illustrates a clever method (in Haskell) of encoding &lt;a href="https://en.wikipedia.org/wiki/Tic-tac-toe" rel="noopener noreferrer"&gt;Tic-Tac-Toe&lt;/a&gt; boards as functions from coordinates to data. Experiment with a JS version below!&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
const emptyBoard = (x, y) =&amp;gt; null

const setPos = (atX, atY, newVal, oldBoard) =&amp;gt; {
    const oldVal = oldBoard(atX, atY)
    const newBoard = (x, y) =&amp;gt; {
        return (x === atX &amp;amp;&amp;amp; y === atY)
            ? newVal
            : oldBoard(x, y)
    }
    return newBoard
}

const printBoard = (board, limitX, limitY) =&amp;gt; {
    for (let x = 0; x &amp;lt; limitX; x++) {
        for (let y = 0; y &amp;lt; limitY; y++) {
            console.log('pos ' + x + ', ' + y + ' is ' + board(x, y))
        }
    }
}

const b2 = setPos(0, 0, 'x', emptyBoard)
const b3 = setPos(1, 1, 'o', b2)

printBoard(b3, 2, 2)

// NB: if you log a larger board, runkit paginates the results!

  &lt;/code&gt;
&lt;/div&gt;


</description>
      <category>immutable</category>
      <category>immer</category>
      <category>lens</category>
      <category>functional</category>
    </item>
    <item>
      <title>Monadic Parser Combinators: an Interactive JS Tutorial (Pt. 1)</title>
      <dc:creator>Gabriel Lebec</dc:creator>
      <pubDate>Fri, 02 Nov 2018 18:17:53 +0000</pubDate>
      <link>https://dev.to/glebec/monadic-parser-combinators-an-interactive-js-tutorial-pt-1-3jbo</link>
      <guid>https://dev.to/glebec/monadic-parser-combinators-an-interactive-js-tutorial-pt-1-3jbo</guid>
      <description>&lt;p&gt;&lt;em&gt;Parsing&lt;/em&gt; analyzes serial data into a structural result, and is a key step in static code analysis and compilation. Parsers also demonstrate various functional concepts including purity, composition, and monads.&lt;/p&gt;

&lt;p&gt;In this interactive tutorial, we will walk through implementing a simple parser combinator library. Combinators allow programmers to easily build up complex programs through the use of a small number of cooperative utility functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;either&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;either&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zebra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;giraffe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;spaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;many1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tallTale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;spaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`There was a &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The intent is partly to learn about parsing and partly to learn about functional programming. No prior experience in either is assumed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Motivations
&lt;/h2&gt;

&lt;p&gt;Serial data, e.g. from a file or network payload, often must be analyzed into a result before a program can work with it. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started#What_is_HTML" rel="noopener noreferrer"&gt;HTML&lt;/a&gt; is a string format for page contents. Browsers parse HTML into the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction" rel="noopener noreferrer"&gt;DOM&lt;/a&gt;, a tree of in-memory nodes that can be queried and manipulated to affect the rendered web page.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://json.org/" rel="noopener noreferrer"&gt;JSON&lt;/a&gt; is a string format for nested data, often used for configuration files or network payloads. Programs can use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse" rel="noopener noreferrer"&gt;&lt;code&gt;JSON.parse&lt;/code&gt;&lt;/a&gt; to convert a JSON string into a JavaScript Object, which can be easily read and updated during runtime.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://eslint.org/" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt; is a static code analysis tool for detecting errors and style deviations. ESLint uses a JavaScript parser (&lt;a href="https://github.com/eslint/espree" rel="noopener noreferrer"&gt;Espree&lt;/a&gt;) to read the author's program (a text file) and identify potential problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, a class of programs called &lt;em&gt;compilers&lt;/em&gt; go one step further, folding a parse tree back down into a converted string format. Compilers thus act as translators between strings in one formal language to strings in another.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;codeES2018&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;num =&amp;gt; num + 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;codeES5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compileToES5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codeES2018&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codeES5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'function (num) { return num + 1 }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developers.google.com/v8/" rel="noopener noreferrer"&gt;V8&lt;/a&gt; is a JavaScript engine that uses a compiler to translate JavaScript into executable machine code.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt; compiles JavaScript written in modern and/or domain-specific syntax (e.g. ES2018 + JSX) into older syntax (e.g. ES5).&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt; compiles JavaScript with non-standard formatting into JavaScript with consistent formatting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a typical compiler, parsing is referred to as the &lt;em&gt;front end&lt;/em&gt; and code generation is called the &lt;em&gt;back end&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    infix       FE (parser)       +      BE (generator)      postfix
 "2 + 3 * 5"         -&amp;gt;          / \           -&amp;gt;          "2 3 5 * +"
                                2   *
                               / \
                              3   5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;However, it is also possible to generate results &lt;em&gt;during&lt;/em&gt; the parsing step. In that case, no explicit tree is built, though the parser implicitly follows a tree structure while recursing through the input string.&lt;/p&gt;
&lt;h1&gt;
  
  
  Parsers
&lt;/h1&gt;

&lt;p&gt;Generally, a parser extracts structure from the beginning of some serial input. The input can be an ordinary string, though some parsers may expect a &lt;a href="https://en.wikipedia.org/wiki/Stream_(computing)" rel="noopener noreferrer"&gt;&lt;em&gt;stream&lt;/em&gt;&lt;/a&gt; (sequentially consumable source, e.g. generator or observable) of &lt;a href="https://en.wikipedia.org/wiki/Lexical_analysis#Token" rel="noopener noreferrer"&gt;&lt;em&gt;tokens&lt;/em&gt;&lt;/a&gt; (objects recording both linguistic type and lexical content).&lt;/p&gt;

&lt;p&gt;Let's start simple and consider a parser to be a function from string to result.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// parse :: String -&amp;gt; *&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This begs the question of what our parser produces. The answer depends on the problem. Many parsers produce tree nodes, but parsers can be written to build any result desired, including raw strings, numbers, functions, whatever.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dealing With Failure
&lt;/h2&gt;

&lt;p&gt;For now let's just capture the literal string value (or &lt;a href="https://en.wikipedia.org/wiki/Lexical_analysis#Lexeme" rel="noopener noreferrer"&gt;&lt;em&gt;lexeme&lt;/em&gt;&lt;/a&gt;) that our parser matches. Here is an (incomplete) parser intended to match on and result in the lexeme "Triceratops":&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// parseTri :: String -&amp;gt; String&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseTri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Triceratops&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Sadly, this parser is broken. What if our string contains the wrong dinosaur? Parsing "T. Rex" shouldn't result in "Triceratops". We need a way to &lt;strong&gt;signal failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How would you address this issue? Come up with your own approach; your parsing function should be able to take the following strings and either result in "Triceratops" or else indicate (somehow) that it failed to parse.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
// parseTri :: String -&amp;gt; String     // change me
const parseTri = s =&amp;gt; 'Triceratops' // change me

// change parseTri so that it can indicate failure

console.log(parseTri('Triceratops'))       // should succeed
console.log(parseTri('Triceratops rules')) // should succeed
console.log(parseTri('I &amp;lt;3 Triceratops'))  // should fail
console.log(parseTri('Pteranodons'))       // should fail
console.log(parseTri('T. Rex'))            // should fail
console.log(parseTri(''))                  // should fail

  &lt;/code&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Signaling Failure: Maybe?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;An experienced functional programmer would likely reach for a &lt;a href="https://medium.com/fullstack-academy/better-js-cases-with-sum-types-92876e48fd9f" rel="noopener noreferrer"&gt;sum type&lt;/a&gt; such as the &lt;a href="https://jrsinclair.com/articles/2016/marvellously-mysterious-javascript-maybe-monad/" rel="noopener noreferrer"&gt;&lt;code&gt;Maybe&lt;/code&gt; monad&lt;/a&gt;. However, to properly address that concept now would derail this article substantially, so we will circle back to &lt;code&gt;Maybe&lt;/code&gt; later on.&lt;/p&gt;
&lt;h3&gt;
  
  
  Signaling Failure: Array?
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Functional parsers commonly represent their results as lists. Failure can thus be represented by the empty list &lt;code&gt;[]&lt;/code&gt;, and multiple successes (from an ambiguous grammar) can be captured if necessary. Ambiguous grammars lie outside the scope of this article, so we don't strictly need lists.&lt;/p&gt;
&lt;h3&gt;
  
  
  Signaling Failure: Null
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Both &lt;code&gt;Maybe&lt;/code&gt; and lists are good ways of dealing with failure, but for now we will stick with a method JS developers are familiar with: &lt;code&gt;null&lt;/code&gt;. The &lt;code&gt;null&lt;/code&gt; value, whose inventor &lt;a href="https://en.wikipedia.org/wiki/Tony_Hoare" rel="noopener noreferrer"&gt;Tony Hoare&lt;/a&gt; once called his &lt;a href="https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions" rel="noopener noreferrer"&gt;"billion dollar mistake"&lt;/a&gt;, has serious pitfalls. However, it is idiomatic, approachable, and will suffice for the moment.&lt;/p&gt;

&lt;p&gt;Here is our new parser. Try it on some strings and see what happens:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
// parseTri :: String -&amp;gt; String | Null
const parseTri = s =&amp;gt; s.startsWith('Triceratops')
    ? 'Triceratops'
    : null

console.log(parseTri('...try strings here...'))

  &lt;/code&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Dealing with Leftovers
&lt;/h2&gt;

&lt;p&gt;When we parse a result from a string, in most cases we will only consume part of the input. The remainder will have other values we can parse, which means we need to keep track of where to resume. In a mutable setting like JavaScript, one might be tempted to create a shared &lt;code&gt;index&lt;/code&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseTri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;remainder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remainder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Triceratops&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Triceratops&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Triceratops&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This works fine for parsing a single string:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
let index = 0
const parseTri = s =&amp;gt; {
    const remainder = s.slice(index)
    if (remainder.startsWith('Triceratops')) {
        index += 'Triceratops'.length
        return 'Triceratops'
    }
    return null
}

  &lt;/code&gt;
  &lt;code&gt;
    
// (index &amp;amp; parseTri are in scope but hidden)
const string = 'TriceratopsTriceratops'
const res1 = parseTri(string) // 'Triceratops'
const res2 = parseTri(string) // 'Triceratops'
const res3 = parseTri(string) // null
console.log(res1, res2, res3)

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;However, shared mutable state can quickly cause problems. What if we want to subsequently parse a different string?&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
let index = 0
const parseTri = s =&amp;gt; {
    const remainder = s.slice(index)
    if (remainder.startsWith('Triceratops')) {
        index += 'Triceratops'.length
        return 'Triceratops'
    }
    return null
}
const string = 'TriceratopsTriceratops'
const res1 = parseTri(string) // 'Triceratops'
const res2 = parseTri(string) // 'Triceratops'
const res3 = parseTri(string) // null

  &lt;/code&gt;
  &lt;code&gt;
    
// (index, parseTri, and res1–res3 are in scope but hidden)
const string2 = 'Triceratops rules'
const res4 = parseTri(string2)
console.log(res4) // null // oops!

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;There are solutions, of course. We could create a &lt;code&gt;Parser&lt;/code&gt; class whose instances manage internal state, or a higher-order &lt;code&gt;makeParser&lt;/code&gt; function which closes over state. Both of those solutions bury state without actually eliminating it; debugging such hidden state is sometimes even more challenging.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pure Token Consumption
&lt;/h3&gt;

&lt;p&gt;It turns out that for this problem, we don't actually need mutable state. In functional programming, we prefer &lt;em&gt;pure&lt;/em&gt; solutions.&lt;/p&gt;

&lt;p&gt;Pure functions are stateless deterministic mappings from input to output, with no side effects. In other words, pure functions have output, but neither depend on nor change the external universe. If you can define your function as a (potentially infinite) table of inputs and outputs, it's pure. Try to induce how &lt;code&gt;f1&lt;/code&gt;, &lt;code&gt;f2&lt;/code&gt;, and &lt;code&gt;f3&lt;/code&gt; below are defined:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;f1 in&lt;/th&gt;
&lt;th&gt;f1 out&lt;/th&gt;
&lt;th&gt;f2 in&lt;/th&gt;
&lt;th&gt;f2 out&lt;/th&gt;
&lt;th&gt;f3 in&lt;/th&gt;
&lt;th&gt;f3 out&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'hi'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[a, b]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'what'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0, 9, 1]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;9&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'pow'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[0]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'forest'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;7&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'a'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[1, 2, 3]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;14&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;''&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[z, y]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;23&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If a parser needs to indicate where the next parse should commence, that implies that the leftover input should itself be a return value. So, our parsers will return &lt;em&gt;two&lt;/em&gt; things: a parsed result, and remaining input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;How can you write a function that returns two things? There is more than one viable way; come up with your own approach below, then read on for our take.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
// parseTri :: String -&amp;gt; String &amp;amp; String
const parseTri = s =&amp;gt; s.startsWith('Triceratops')
    ? 'Triceratops' // fix me to also return leftover input
    : null

// should succeed with "" as a remainder
console.log(parseTri('Triceratops'))

// should succeed with " rules" as a remainder
console.log(parseTri('Triceratops rules'))

// should fail
console.log(parseTri('T. Rex'))

  &lt;/code&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Tuples and Friends
&lt;/h3&gt;

&lt;p&gt;Because functional programming involves a lot of data flowing in and out of functions, functional languages often feature a lightweight data structure for packaging values together: the tuple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Haskell&lt;/span&gt;
&lt;span class="n"&gt;myTuple&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;-- a 2-tuple&lt;/span&gt;
&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fst&lt;/span&gt; &lt;span class="n"&gt;myTuple&lt;/span&gt; &lt;span class="c1"&gt;-- "hello"&lt;/span&gt;
&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;snd&lt;/span&gt; &lt;span class="n"&gt;myTuple&lt;/span&gt; &lt;span class="c1"&gt;-- 99&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;JavaScript doesn't have tuples, but it does have Objects and Arrays (which are actually a type of Object). We can emulate tuples easily enough:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myTuple&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myTuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// 'hello'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myTuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myTuple&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myTuple&lt;/span&gt; &lt;span class="c1"&gt;// 'hello'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;myTuple&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Arrays are more concise, but Objects are more expressive. You probably used one of these in your solution above; we'll use Objects.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
  &lt;/code&gt;
  &lt;code&gt;
    
// parseTri :: String -&amp;gt; { result: String, remainder: String } | Null
const parseTri = s =&amp;gt; s.startsWith('Triceratops')
    ? { result: 'Triceratops', remainder: s.slice(11) }
    : null

console.log(parseTri('Triceratops'))
console.log(parseTri('Triceratops is cool'))
console.log(parseTri('T. Rex'))

  &lt;/code&gt;
&lt;/div&gt;



&lt;h4&gt;
  
  
  Side Note: Isomorphisms
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;n&lt;/em&gt;-Tuples and &lt;em&gt;n&lt;/em&gt;-element JS Arrays (when used solely to store data) are actually &lt;a href="https://kseo.github.io/posts/2016-12-25-type-isomorphism.html" rel="noopener noreferrer"&gt;&lt;em&gt;isomorphic&lt;/em&gt;&lt;/a&gt;. Sets &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; are isomorphic if you can define a pair of functions &lt;code&gt;a2b&lt;/code&gt; and &lt;code&gt;b2a&lt;/code&gt;, such that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a2b&lt;/code&gt; maps all values in &lt;code&gt;A&lt;/code&gt; to values in &lt;code&gt;B&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b2a&lt;/code&gt; maps all values in &lt;code&gt;B&lt;/code&gt; to values in &lt;code&gt;A&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;b2a(a2b(a)) = a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a2b(b2a(b)) = b&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Isomorphisms are a &lt;a href="https://stackoverflow.com/questions/11245183/importance-of-isomorphic-functions" rel="noopener noreferrer"&gt;rich topic&lt;/a&gt; with some delightful results, but the upshot is that it is nice to know when two data types are equivalent for a given use case.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thought puzzle: why might two-valued objects &lt;strong&gt;not&lt;/strong&gt; be isomorphic to 2-el arrays? What information would be lost in translation?&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Threading Parsers
&lt;/h3&gt;

&lt;p&gt;Our parser can now report which part of the input was not consumed, but how do we actually use that information? The leftover string from one parse becomes the input to the next parse. Complete the code below.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const assert = require('assert')

const parseTri = s =&amp;gt; s.startsWith('Triceratops')
    ? { result: 'Triceratops', remainder: s.slice(11) }
    : null

const solution = [
    "const firstParse = parseTri(string)",
    "const secondParse = parseTri(firstParse.remainder)",
    "const thirdParse = parseTri(secondParse.remainder)"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// parseTri :: String -&amp;gt; { result: String, remainder: String } | Null

// parseTri is in scope in this snippet. You can refer back
// to its definition, but you won't need to edit it.

const string = 'TriceratopsTriceratops'

// use parseTri to obtain the three values below:

const firstParse = undefined
const secondParse = undefined
const thirdParse = undefined

// console.log(solution)
assert.deepStrictEqual(firstParse, {
    result: 'Triceratops',
    remainder: 'Triceratops'
}, 'first parse works')
assert.deepStrictEqual(secondParse, {
    result: 'Triceratops',
    remainder: ''
}, 'second parse works')
assert.equal(thirdParse, null, 'third parse works')

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;To see our solution, you can log the hidden variable &lt;code&gt;solution&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generalizing
&lt;/h2&gt;

&lt;p&gt;We have a single parser which can parse "Triceratops" – not very interesting. Write a few parsers for other dinosaurs.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')

const testParsers = () =&amp;gt; registerTests(t =&amp;gt; {
    t.deepEqual(
        parseRex('T. Rex'),
        { result: 'T. Rex', remainder: '' },
        'parseRex parses "T. Rex"'
    )
    t.deepEqual(
        parseRex('T. Rex is scary'),
        { result: 'T. Rex', remainder: ' is scary' },
        'parseRex parses "T. Rex is scary"'
    )
    t.equal(
        parseRex('Triceratops'),
        null,
        'parseRex fails to parse "Triceratops"'
    )
    t.deepEqual(
        parseRaptor('Velociraptor'),
        { result: 'Velociraptor', remainder: '' },
        'parseRaptor parses "Velociraptor"'
    )
    t.deepEqual(
        parseRaptor('Velociraptor is scary'),
        { result: 'Velociraptor', remainder: ' is scary' },
        'parseRaptor parses "Velociraptor is scary"'
    )
    t.equal(
        parseRaptor('Triceratops'),
        null,
        'parseRaptor fails to parse "Triceratops"'
    )
    t.end()
})

const solution = [
    "const parseRex = s =&amp;gt; s.startsWith('T. Rex')",
    "    ? { result: 'T. Rex', remainder: s.slice(6) }",
    "    : null",
    "",
    "const parseRaptor = s =&amp;gt; s.startsWith('Velociraptor')",
    "    ? { result: 'Velociraptor', remainder: s.slice(12) }",
    "    : null"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// parseRex :: String -&amp;gt; { result: String, remainder: String } | Null
const parseRex = undefined // matches "T. Rex"

// parseRaptor :: String -&amp;gt; { result: String, remainder: String } | Null
const parseRaptor = undefined // matches "Velociraptor"

// console.log(solution)
await testParsers()

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;This is pretty repetitive. Let's generalize and make a &lt;code&gt;parseLiteral&lt;/code&gt; function.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')

const testParsers = () =&amp;gt; registerTests(t =&amp;gt; {
    t.deepEqual(
        parseRex('T. Rex'),
        { result: 'T. Rex', remainder: '' },
        'parseRex parses "T. Rex"'
    )
    t.deepEqual(
        parseRex('T. Rex is scary'),
        { result: 'T. Rex', remainder: ' is scary' },
        'parseRex parses "T. Rex is scary"'
    )
    t.equal(
        parseRex('Triceratops'),
        null,
        'parseRex fails to parse "Triceratops"'
    )
    t.deepEqual(
        parseRaptor('Velociraptor'),
        { result: 'Velociraptor', remainder: '' },
        'parseRaptor parses "Velociraptor"'
    )
    t.deepEqual(
        parseRaptor('Velociraptor is scary'),
        { result: 'Velociraptor', remainder: ' is scary' },
        'parseRaptor parses "Velociraptor is scary"'
    )
    t.equal(
        parseRaptor('Triceratops'),
        null,
        'parseRaptor fails to parse "Triceratops"'
    )
    t.end()
})

const solution = [
    "const parseLiteral = literal =&amp;gt; s =&amp;gt; s.startsWith(literal)",
    "    ? { result: literal, remainder: s.slice(literal.length) }",
    "    : null",
    "",
    "const parseRex = parseLiteral('T. Rex')",
    "",
    "const parseRaptor = parseLiteral('Velociraptor')"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// parseLiteral :: String -&amp;gt;
//     (String -&amp;gt; { result: String, remainder: String } | Null)
const parseLiteral = literal =&amp;gt; undefined

// parseRex :: String -&amp;gt; { result: String, remainder: String } | Null
const parseRex = undefined // use parseLiteral

// parseRaptor :: String -&amp;gt; { result: String, remainder: String } | Null
const parseRaptor = undefined // use parseLiteral

// console.log(solution)
await testParsers()

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Solving the above demonstrates a common functional technique. &lt;em&gt;Higher-order&lt;/em&gt; functions take and/or return functions themselves; &lt;code&gt;parseLiteral&lt;/code&gt; does the latter. Instead of hard-coding individual parsers for every string, &lt;code&gt;parseLiteral&lt;/code&gt; generalizes, mapping from strings to parsers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;string&lt;/th&gt;
&lt;th&gt;&lt;code&gt;parseLiteral(string)&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'hi'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;parser for &lt;code&gt;'hi'&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'yo'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;parser for &lt;code&gt;'yo'&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;'wow'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;parser for &lt;code&gt;'wow'&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Different Result Types
&lt;/h3&gt;

&lt;p&gt;Parsers &lt;em&gt;match&lt;/em&gt; on strings, but they don't have to &lt;em&gt;result&lt;/em&gt; in them. Write parsers for digit strings which result in numbers.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')

const testParsers = () =&amp;gt; registerTests(t =&amp;gt; {
    t.deepEqual(
        parseNum0('0'),
        { result: 0, remainder: '' },
        'parseNum0 parses "0"'
    )
    t.deepEqual(
        parseNum0('0 is cool'),
        { result: 0, remainder: ' is cool' },
        'parseNum0 parses "0 is cool"'
    )
    t.equal(
        parseNum0('1'),
        null,
        'parseNum0 fails to parse "1"'
    )
    t.deepEqual(
        parseNum1('1'),
        { result: 1, remainder: '' },
        'parseNum1 parses "1"'
    )
    t.deepEqual(
        parseNum1('1 is cool'),
        { result: 1, remainder: ' is cool' },
        'parseNum1 parses "1 is cool"'
    )
    t.equal(
        parseNum1('0'),
        null,
        'parseNum1 fails to parse "0"'
    )
    t.end()
})

const solution = [
    "const parseNum0 = s =&amp;gt; s.startsWith('0')",
    "    ? { result: 0, remainder: s.slice(1) }",
    "    : null",
    "",
    "const parseNum1 = s =&amp;gt; s.startsWith('1')",
    "    ? { result: 1, remainder: s.slice(1) }",
    "    : null"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// parseNum0 :: String -&amp;gt; { result: Number, remainder: String } | Null
const parseNum0 = undefined // result should be 0, not '0'

// parseNum1 :: String -&amp;gt; { result: Number, remainder: String } | Null
const parseNum1 = undefined // result should be 1, not '1'

// console.log(solution)
await testParsers()

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Once we start using our parsers for practical purposes, it will be convenient to transform raw lexemes into processed results specific to our use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types, Signatures, &amp;amp; Aliases
&lt;/h3&gt;

&lt;p&gt;We now have seen two different kinds of parsers: ones that result in strings, and ones that result in numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;parseRex&lt;/span&gt;  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Null&lt;/span&gt;
&lt;span class="n"&gt;parseNum1&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We haven't drawn special attention to these comments yet, preferring to teach by example, but these are examples of &lt;em&gt;type signatures&lt;/em&gt;. A type signature documents what &lt;strong&gt;set&lt;/strong&gt; a value belongs to. For example, the &lt;code&gt;Bool&lt;/code&gt; type is a set of two values: &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt;. You can read the notation &lt;code&gt;::&lt;/code&gt; as "has type" or "is in the set":&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;true&lt;/span&gt;  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="c1"&gt;-- `true`  is in the set `Bool`&lt;/span&gt;
&lt;span class="n"&gt;false&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt; &lt;span class="c1"&gt;-- `false` is in the set `Bool`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Functions also belong to types. The &lt;code&gt;!&lt;/code&gt; (or "not") function happens to be in the &lt;em&gt;set of functions which map values in &lt;code&gt;Bool&lt;/code&gt; to values in &lt;code&gt;Bool&lt;/code&gt;&lt;/em&gt;. We signify this as &lt;code&gt;(!) :: Bool -&amp;gt; Bool&lt;/code&gt;. Here is the &lt;code&gt;!&lt;/code&gt; function defined:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bool input&lt;/th&gt;
&lt;th&gt;Bool output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Thought puzzle: there are precisely &lt;strong&gt;three&lt;/strong&gt; other functions of type &lt;code&gt;Bool -&amp;gt; Bool&lt;/code&gt;. Can you define all of them? Remember, each function will be a table of two rows.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;Functions are mappings from one &lt;strong&gt;type&lt;/strong&gt; to another &lt;strong&gt;type&lt;/strong&gt; (e.g. &lt;code&gt;Int -&amp;gt; Bool&lt;/code&gt;, &lt;code&gt;String -&amp;gt; String&lt;/code&gt;, or &lt;code&gt;Object -&amp;gt; String&lt;/code&gt;). Accordingly, functional languages often emphasize their type system. ML and related languages like OCaml, F#, ReasonML, Miranda, Haskell, PureScript, Idris, and Elm are examples of languages with sophisticated typing, including &lt;a href="https://codewords.recurse.com/issues/three/algebra-and-calculus-of-algebraic-data-types" rel="noopener noreferrer"&gt;&lt;em&gt;algebraic data types&lt;/em&gt;&lt;/a&gt; and complete &lt;a href="https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system" rel="noopener noreferrer"&gt;&lt;em&gt;type inference&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;JavaScript has a (sometimes infamous) dynamic type system, and lacks an official type notation. The syntax here is borrowed from Haskell and is similar to the system used by &lt;a href="http://ramdajs.com/" rel="noopener noreferrer"&gt;Ramda&lt;/a&gt;, a JS utility library. It is explained well by both the &lt;a href="https://github.com/ramda/ramda/wiki/Type-Signatures" rel="noopener noreferrer"&gt;Ramda wiki&lt;/a&gt; and &lt;a href="https://github.com/fantasyland/fantasy-land#type-signature-notation" rel="noopener noreferrer"&gt;Fantasy Land docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We bring this up now because it is beginning to get cumbersome to write out the entire type of our parsers. The &lt;code&gt;parseRex&lt;/code&gt; and &lt;code&gt;parseNum1&lt;/code&gt; type signatures differ at only one location, &lt;code&gt;result&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;parseRex&lt;/span&gt;  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Null&lt;/span&gt;
&lt;span class="n"&gt;parseNum1&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Accordingly, from now on we will use &lt;code&gt;Parser a&lt;/code&gt; to mean "a parsing function whose &lt;code&gt;result&lt;/code&gt; is of type &lt;code&gt;a&lt;/code&gt;":&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remainder&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;Null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This &lt;em&gt;type alias&lt;/em&gt; is just a shorthand we will use for documentation purposes. It will clean up our comments considerably and make it easier to talk about parsers. For example, now we can categorize &lt;code&gt;parseRex&lt;/code&gt; and &lt;code&gt;parseNum1&lt;/code&gt; more concisely:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;parseRex&lt;/span&gt;  &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="n"&gt;parseNum1&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="kt"&gt;Number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Try it yourself. Simplify our &lt;code&gt;parseLiteral&lt;/code&gt; signature using the shorthand:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const solution = [
    "parseLiteral :: String -&amp;gt; Parser String"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// long version:

// parseLiteral :: String -&amp;gt;
//     (String -&amp;gt; { result: String, remainder: String } | Null)

// short version (fill in):

// parseLiteral :: ???

console.log(solution)

  &lt;/code&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Combinators at Last
&lt;/h2&gt;

&lt;p&gt;What if we want to match on more than one possibility? Implement the following parsers. Existing parsers are in scope, use them in your definition:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')

const parseLiteral = literal =&amp;gt; s =&amp;gt; s.startsWith(literal)
    ? { result: literal, remainder: s.slice(literal.length) }
    : null

const parseTri = parseLiteral('Triceratops')
const parseRex = parseLiteral('T. Rex')
const parseRaptor = parseLiteral('Velociraptor')

const testParsers = () =&amp;gt; registerTests(t =&amp;gt; {
    t.deepEqual(
        parseCarnivore('T. Rex is scary'),
        { result: 'T. Rex', remainder: ' is scary' },
        'parseCarnivore parses "T. Rex is scary"'
    )
    t.deepEqual(
        parseCarnivore('Velociraptor is fast'),
        { result: 'Velociraptor', remainder: ' is fast' },
        'parseCarnivore parses "Velociraptor is fast"'
    )
    t.equal(
        parseCarnivore('Triceratops eats grass'),
        null,
        'parseCarnivore fails to parse "Triceratops eats grass"'
    )
    t.deepEqual(
        parseBigDino('T. Rex has small arms'),
        { result: 'T. Rex', remainder: ' has small arms' },
        'parseBigDino parses "T. Rex has small arms"'
    )
    t.deepEqual(
        parseBigDino('Triceratops has three horns'),
        { result: 'Triceratops', remainder: ' has three horns' },
        'parseBigDino parses "Triceratops has three horns"'
    )
    t.equal(
        parseBigDino('Velociraptor hunts in packs'),
        null,
        'parseBigDino fails to parse "Velociraptor hunts in packs"'
    )
    t.end()
})

const solution = [
    "// parseCarnivore, parseBigDino :: Parser String",
    "const parseCarnivore = s =&amp;gt; parseRex(s) || parseRaptor(s)",
    "const parseBigDino   = s =&amp;gt; parseRex(s) || parseTri(s)"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// parseTri    :: Parser String
// parseRex    :: Parser String
// parseRaptor :: Parser String

// parseCarnivore :: Parser String
const parseCarnivore = undefined // match "T. Rex" OR "Velociraptor"

// parseBigDino :: Parser String
const parseBigDino = undefined // match "T. Rex" OR "Triceratops"

// console.log(solution)
await testParsers()

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Again, this is getting repetitive. What does the functional programmer do when faced with repetition? Generalize! Write a function &lt;code&gt;either&lt;/code&gt; which takes two parsers and returns a new parser that matches either of them.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')

const parseLiteral = literal =&amp;gt; s =&amp;gt; s.startsWith(literal)
    ? { result: literal, remainder: s.slice(literal.length) }
    : null

const parseTri = parseLiteral('Triceratops')
const parseRex = parseLiteral('T. Rex')
const parseRaptor = parseLiteral('Velociraptor')

const testParsers = () =&amp;gt; registerTests(t =&amp;gt; {
    t.deepEqual(
        parseCarnivore('T. Rex is scary'),
        { result: 'T. Rex', remainder: ' is scary' },
        'parseCarnivore parses "T. Rex is scary"'
    )
    t.deepEqual(
        parseCarnivore('Velociraptor is fast'),
        { result: 'Velociraptor', remainder: ' is fast' },
        'parseCarnivore parses "Velociraptor is fast"'
    )
    t.equal(
        parseCarnivore('Triceratops eats grass'),
        null,
        'parseCarnivore fails to parse "Triceratops eats grass"'
    )
    t.deepEqual(
        parseBigDino('T. Rex has small arms'),
        { result: 'T. Rex', remainder: ' has small arms' },
        'parseBigDino parses "T. Rex has small arms"'
    )
    t.deepEqual(
        parseBigDino('Triceratops has three horns'),
        { result: 'Triceratops', remainder: ' has three horns' },
        'parseBigDino parses "Triceratops has three horns"'
    )
    t.equal(
        parseBigDino('Velociraptor hunts in packs'),
        null,
        'parseBigDino fails to parse "Velociraptor hunts in packs"'
    )
    t.end()
})

const solution = [
    "// either :: (Parser a, Parser b) -&amp;gt; Parser (a | b)",
    "const either = (p1, p2) =&amp;gt; s =&amp;gt; p1(s) || p2(s)"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// parseLiteral :: String -&amp;gt; Parser String
// parseTri     :: Parser String
// parseRex     :: Parser String
// parseRaptor  :: Parser String

// either :: (Parser a, Parser b) -&amp;gt; Parser (a | b)
const either = (p1, p2) =&amp;gt; undefined

// parseCarnivore, parseBigDino :: Parser String
const parseCarnivore = either(parseRex, parseRaptor)
const parseBigDino   = either(parseRex, parseTri)

// console.log(solution)
await testParsers()

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;Congratulations, you've written a &lt;em&gt;combinator&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combi-who?
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Combinator&lt;/em&gt;, like many programming terms, is overloaded – it means different things in different contexts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Combinatory_logic" rel="noopener noreferrer"&gt;Combinatory logic&lt;/a&gt; is the study of functions which act on functions. For example, the &lt;code&gt;I&lt;/code&gt; combinator (&lt;code&gt;x =&amp;gt; x&lt;/code&gt;) takes in a function and returns the same function. In this field, "combinator" formally means a function with no &lt;em&gt;free&lt;/em&gt; (unbound) &lt;em&gt;variables&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wiki.haskell.org/Combinator_pattern" rel="noopener noreferrer"&gt;The combinator pattern&lt;/a&gt; is a strategy for building flexible libraries, in which a small number of cooperative utility functions build up rich results (which in turn can be new inputs to those same functions).

&lt;ul&gt;
&lt;li&gt;For example, CSS "combinators" take in CSS selectors and yield new, more complex selectors. &lt;code&gt;div&lt;/code&gt; and &lt;code&gt;h1&lt;/code&gt; are both primitive selectors; using the &lt;em&gt;direct child&lt;/em&gt; (&lt;code&gt;&amp;gt;&lt;/code&gt;) combinator, you can create the new &lt;code&gt;div &amp;gt; h1&lt;/code&gt; selector.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We will define a &lt;em&gt;parser combinator&lt;/em&gt; as a function which takes in one or more parsers, and returns a new parser. Some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;either&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;both&lt;/span&gt;   &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;any&lt;/span&gt;    &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="n"&gt;many&lt;/span&gt;   &lt;span class="o"&gt;::&lt;/span&gt;  &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Parser&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You've already defined &lt;code&gt;either&lt;/code&gt;; take a crack at &lt;code&gt;both&lt;/code&gt; and &lt;code&gt;any&lt;/code&gt; next. For manual testing, &lt;code&gt;parseLiteral&lt;/code&gt; and all of our dino parsers are in scope:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')

const parseLiteral = literal =&amp;gt; s =&amp;gt; s.startsWith(literal)
    ? { result: literal, remainder: s.slice(literal.length) }
    : null

const parseTri = parseLiteral('Triceratops')
const parseRex = parseLiteral('T. Rex')
const parseRaptor = parseLiteral('Velociraptor')

const testTriRexViaBoth = () =&amp;gt; registerTests(t =&amp;gt; {
    const parseTriRex2 = both(parseTri, parseRex)
    t.deepEqual(
        parseTriRex2('TriceratopsT. Rex'),
        { result: ['Triceratops', 'T. Rex'], remainder: '' },
        'parseTriRex parses "TriceratopsT. Rex"'
    )
    t.deepEqual(
        parseTriRex2('TriceratopsT. Rex!!!'),
        { result: ['Triceratops', 'T. Rex'], remainder: '!!!' },
        'parseTriRex parses "TriceratopsT. Rex!!!"'
    )
    t.equal(
        parseTriRex2('TriceratopsT. Bone'),
        null,
        'parseTriRex fails to parse "TriceratopsT. Bone"'
    )
    t.equal(
        parseTriRex2('Triangles'),
        null,
        'parseTriRex fails to parse "Triangles"'
    )
    t.end()
})

const solution = [
    "const both = (p1, p2) =&amp;gt; s =&amp;gt; {",
    "    const r1 = p1(s)",
    "    if (!r1) return null",
    "    const r2 = p2(r1.remainder)",
    "    if (!r2) return null",
    "    return {",
    "        result: [r1.result, r2.result],",
    "        remainder: r2.remainder",
    "    }",
    "}"
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// both takes in a two parsers, and makes a parser that matches
// the first one and then the second (or fails if EITHER of them
// fails). It packages the two successes into an array.

// both :: (Parser a, Parser b) -&amp;gt; Parser [a, b]
const both = undefined

// parseTriRex :: Parser String
const parseTriRex = both(parseTri, parseRex)
console.log(parseTriRex('TriceratopsT. Rex!')) // succeeds
console.log(parseTriRex('Triceratops &amp;amp; T. Rex')) // fails

// console.log(solution)
await testTriRexViaBoth()

  &lt;/code&gt;
&lt;/div&gt;



&lt;p&gt;Also, &lt;code&gt;either&lt;/code&gt; is in scope if you want it:&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const registerTests = require('@runkit/glebec/tape-dispenser/releases/1.0.0')

const parseLiteral = literal =&amp;gt; s =&amp;gt; s.startsWith(literal)
    ? { result: literal, remainder: s.slice(literal.length) }
    : null

const either = (p1, p2) =&amp;gt; s =&amp;gt; p1(s) || p2(s)

const parseTri = parseLiteral('Triceratops')
const parseRex = parseLiteral('T. Rex')
const parseRaptor = parseLiteral('Velociraptor')

const testDinoViaAny = () =&amp;gt; registerTests(t =&amp;gt; {
    const parseDino2 = any(parseTri, parseRex, parseRaptor)
    t.deepEqual(
        parseDino2('Velociraptor on the loose'),
        { result: 'Velociraptor', remainder: ' on the loose' },
        'parseDino parses "Velociraptor on the loose"'
    )
    t.deepEqual(
        parseDino2('Triceratops for the win'),
        { result: 'Triceratops', remainder: ' for the win' },
        'parseDino parses "Triceratops for the win"'
    )
    t.deepEqual(
        parseDino2('T. Rex is a king'),
        { result: 'T. Rex', remainder: ' is a king' },
        'parseDino parses "T. Rex is a king"'
    )
    t.equal(
        parseDino2('Wooly mammoths migrate west'),
        null,
        'parseDino fails to parse "Wooly mammoths migrate west"'
    )
    t.end()
})

const solution = [
    "// any :: (...Parser *) -&amp;gt; Parser *",
    "const any = (...parsers) =&amp;gt; parsers.reduce(either)",
].join('\n')

  &lt;/code&gt;
  &lt;code&gt;
    
// either :: (Parser a, Parser b) -&amp;gt; Parser (a | b)

// any takes in a variable number of parsers, and makes a parser
// that matches the first one to match (or fails if they ALL fail).

// any :: (...Parser *) -&amp;gt; Parser *
const any = undefined

// parseDino :: Parser String
const parseDino = any(parseTri, parseRex, parseRaptor)

// console.log(solution)
await testDinoViaAny()

  &lt;/code&gt;
&lt;/div&gt;


&lt;p&gt;This is a powerful concept. Instead of hand-coding ad-hoc parser functions for every conceivable purpose, we can define a few abstract combinators. Feed simple parsers in, get more powerful parsers out; those new powerful parsers can become, in turn, inputs to the same combinators. We can therefore build up rich behavior from a few easy-to-use tools. This is the essence of &lt;strong&gt;composition&lt;/strong&gt; – construction via combination.&lt;/p&gt;


&lt;div class="runkit-element"&gt;
  &lt;code&gt;
    
const parseLiteral = literal =&amp;gt; s =&amp;gt; s.startsWith(literal)
    ? { result: literal, remainder: s.slice(literal.length) }
    : null

const parseTri = parseLiteral('Triceratops')
const parseRex = parseLiteral('T. Rex')
const parseRaptor = parseLiteral('Velociraptor')

const either = (p1, p2) =&amp;gt; s =&amp;gt; p1(s) || p2(s)

const both = (p1, p2) =&amp;gt; s =&amp;gt; {
    const r1 = p1(s)
    if (!r1) return null
    const r2 = p2(r1.remainder)
    if (!r2) return null
    return {
        result: [r1.result, r2.result],
        remainder: r2.remainder
    }
}

const any = (...parsers) =&amp;gt; parsers.reduce(either)

  &lt;/code&gt;
  &lt;code&gt;
    
const parseDino = any(parseTri, parseRex, parseRaptor)
const parseTwoDinos = both(parseDino, parseDino)
console.log(parseTwoDinos('VelociraptorTriceratopsEtc.')) // succeeds
console.log(parseTwoDinos('T. RexVelociraptor…')) // succeeds
console.log(parseTwoDinos('TriceratopsNope')) // fails

  &lt;/code&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Conclusion to Part 1
&lt;/h2&gt;

&lt;p&gt;Below is the current state of our parser combinator library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// type Parser a = String -&amp;gt; { result: a, remainder: String } | Null&lt;/span&gt;

&lt;span class="c1"&gt;// parseLiteral :: String -&amp;gt; Parser String&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parseLiteral&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;literal&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;remainder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;

&lt;span class="c1"&gt;// either :: (Parser a, Parser b) -&amp;gt; Parser (a | b)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// both :: (Parser a, Parser b) -&amp;gt; Parser [a, b]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;both&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remainder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;remainder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remainder&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// any :: (...Parser *) -&amp;gt; Parser *&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;parsers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;parsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;either&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this first installment, we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what parsing is&lt;/li&gt;
&lt;li&gt;some use cases for parsers&lt;/li&gt;
&lt;li&gt;one (non-functional) way to deal with failure&lt;/li&gt;
&lt;li&gt;one (functional) way to eliminate state&lt;/li&gt;
&lt;li&gt;function purity&lt;/li&gt;
&lt;li&gt;using tuples (or arrays/objects) as return values&lt;/li&gt;
&lt;li&gt;threading parser results sequentially&lt;/li&gt;
&lt;li&gt;types, signatures, and aliases&lt;/li&gt;
&lt;li&gt;basic parser combinators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In an upcoming sequel to this article, we will cover some more challenging issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dealing with longer sequences&lt;/li&gt;
&lt;li&gt;dealing with choice&lt;/li&gt;
&lt;li&gt;functors and monads&lt;/li&gt;
&lt;li&gt;simulating infix function notation&lt;/li&gt;
&lt;li&gt;formal grammars &amp;amp; parsing theory&lt;/li&gt;
&lt;li&gt;recursive descent&lt;/li&gt;
&lt;li&gt;laziness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Part 2 will be linked here once published.&lt;/p&gt;




&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Gabriel Lebec is an instructor for Fullstack Academy of Code, an intensive web applications development program. He has a B.A. in Mathematics and Studio Art, and too many hobbies, including the art-historical study of antique Japanese swords. You can see more by Gabriel at &lt;a href="https://medium.com/@glebec" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;, &lt;a href="https://www.youtube.com/channel/UCVqIaPVG27Nh64ZGWdFzSWQ/playlists" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;, &lt;a href="https://github.com/glebec" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, and &lt;a href="https://twitter.com/g_lebec" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>parsers</category>
      <category>monads</category>
      <category>functional</category>
      <category>combinators</category>
    </item>
  </channel>
</rss>
