ploeh blog https://blog.ploeh.dk danish software design en-us Mark Seemann Wed, 28 Jul 2021 12:58:37 UTC Wed, 28 Jul 2021 12:58:37 UTC Referential transparency fits in your head https://blog.ploeh.dk/2021/07/28/referential-transparency-fits-in-your-head/ Wed, 28 Jul 2021 12:13:00 UTC <div id="post"> <p> <em>Why functional programming matters.</em> </p> <p> This article is mostly excerpts from my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. The overall message is too important to exclusively hide away in a book, though, which is the reason I also publish it here. </p> <p> The illustrations are preliminary. While writing the manuscript, I experimented with hand-drawn figures, but Addison-Wesley prefers 'professional' illustrations. In the published book, the illustrations shown here will be replaced by cleaner, more readable, but also more boring figures. </p> <blockquote> <h3 id="7a0e7dacbe4048cc8d22583258e39267"> Nested composition <a href="#7a0e7dacbe4048cc8d22583258e39267" title="permalink">#</a> </h3> <p> Ultimately, software interacts with the real world. It paints pixels on the screen, saves data in databases, sends emails, posts on social media, controls industrial robots, etcetera. All of these are what we in the context of <a href="https://en.wikipedia.org/wiki/Command-query_separation">Command Query Separation</a> call <em>side effects</em>. </p> <p> Since side effects are software's raison d'être, it seems only natural to model composition around them. This is how most people tend to approach object-oriented design. You model <em>actions</em>. </p> <p> Object-oriented composition tends to focus on composing side effects together. The <a href="https://en.wikipedia.org/wiki/Composite_pattern">Composite</a> design pattern may be the paragon of this style of composition, but most of the patterns in <a href="http://amzn.to/XBYukB">Design Patterns</a> rely heavily on composition of side effects. </p> <p> As illustrated in [the following figure] this style of composition relies on nesting objects in other objects, or side effects in other side effects. Since your goal should be code that fits in your head, this is a problem. </p> <p> <img src="/content/binary/nested-composition.jpg" alt="Objects nested within other objects."> </p> <p> [Figure caption:] The typical composition of objects (or, rather, methods on objects) is nesting. The more you compose, the less the composition fits in your brain. In this figure, each star indicates a side effect that you care about. Object <em>A</em> encapsulates one side effect, and object <em>B</em> two. Object <em>C</em> composes <em>A</em> and <em>B</em>, but also adds a fourth side effect. That's already four side effects that you need to keep in mind when trying to understand the code. This easily gets out of hand: object <em>E</em> composes a total of eight side effects, and <em>F</em> nine. Those don't fit well in your brain. </p> </blockquote> <p> I should add here that one of the book's central tenets is that <a href="https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two">the human short-term memory can only hold a limited amount of information</a>. Code that fits in your head is code that respects that limitation. This is a topic I've already addressed in <a href="https://cleancoders.com/episode/humane-code-real-episode-1">my Humane Code video</a>. </p> <p> In the book, I use the number <em>seven</em> as a symbol of the this cognitive limit. Nothing I argue, however, relies on this exact number. The point is only that short-term memory is quite limited. <em>Seven</em> is only a shorthand for that. </p> <p> The book proceeds to provide a code example that illustrates how fast nested composition accumulates complexity that exceeds the capacity of your short-term memory. You can see the code example in the book, or in the article <a href="/2020/11/23/good-names-are-skin-deep">Good names are skin-deep</a>, which makes a slightly different criticism than the one argued in the book. </p> <p> The section on nested composition goes on: </p> <blockquote> <blockquote> <p> "Abstraction is the elimination of the irrelevant and the amplification of the essential" </p> <footer><cite>Robert C. Martin, <a href="http://amzn.to/19W4JHk">APPP</a></cite></footer> </blockquote> <p> By hiding a side effect in a Query, I've <em>eliminated</em> something essential. In other words, more is going on in [the book's code listing] than meets the eye. The <a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a> may be as low as <em>4</em>, but there's a hidden fifth action that you ought to be aware of. </p> <p> Granted, five chunks still fit in your brain, but that single hidden interaction is an extra 14% towards the budget of seven. It doesn't take many hidden side effects before the code no longer fits in your head </p> <h3 id="3e2c16e5e5d34e9790fbfe13f3e1f974"> Sequential composition <a href="#3e2c16e5e5d34e9790fbfe13f3e1f974" title="permalink">#</a> </h3> <p> While nested composition is problematic, it isn't the only way to compose things. You can also compose behaviour by chaining it together, as illustrated in [the following figure]. </p> <p> <img src="/content/binary/sequential-composition.jpg" alt="Two composed arrows - one is pointing to the other, thereby creating one arrow composed from two."> </p> <p> [Figure caption:] Sequential composition of two functions. The output from <code>Where</code> becomes the input to <code>Allocate</code>. </p> <p> In the terminology of Command Query Separation, Commands cause trouble. Queries, on the other hand, tend to cause little trouble. They return data which you can use as input for other Queries. </p> </blockquote> <p> Again, the book proceeds to show code examples. You can, of course, see the code in the book, but the methods discussed are the <code>WillAccept</code> function <a href="/2020/11/30/name-by-role">shown here</a>, the <code>Overlaps</code> function <a href="/2021/03/01/pendulum-swing-internal-by-default">shown here</a>, as well as a few other functions that I don't think that I've shown on the blog. </p> <blockquote> <p> The entire restaurant example code base is written with that principle in mind. Consider the <code>WillAccept</code> method [...]. After all the Guard Clauses it first creates a new instance of the <code>Seating</code> class. You can think of a constructor as a Query under the condition that it has no side effects. </p> <p> The next line of code filters the <code>existingReservations</code> using the <code>Overlaps</code> method [...] as a predicate. The built-in <code>Where</code> method is a Query. </p> <p> Finally, the <code>WillAccept</code> method returns whether there's <code>Any</code> table among the <code>availableTables</code> that <code>Fits</code> the <code>candidate.Quantity</code>. The <code>Any</code> method is another built-in Query, and <code>Fits</code> is a predicate. </p> <p> Compared to [the sequential composition figure], you can say that the <code>Seating</code> constructor, <code>seating.Overlaps</code>, <code>Allocate</code>, and <code>Fits</code> are sequentially composed. </p> <p> None of these methods have side effects, which means that once <code>WillAccept</code> returns its Boolean value, you can forget about how it reached that result. It truly eliminates the irrelevant and amplifies the essential </p> <h3 id="e15e5142ede7460bbf52bebf9102783f"> Referential transparency <a href="#e15e5142ede7460bbf52bebf9102783f" title="permalink">#</a> </h3> <p> There's a remaining issue that Command Query Separation fails to address: predictability. While a Query has no side effects that your brain has to keep track of, it could still surprise you if you get a new return value every time you call it - even with the same input. </p> <p> This may not be quite as bad as side effects, but it'll still tax your brain. What happens if we institute an extra rule on top of Command Query Separation: that Queries must be deterministic? </p> <p> This would mean that a Query can't rely on random number generators, GUID creation, the time of day, day of the month, or any other data from the environment. That would include the contents of files and databases. That sounds restrictive, so what's the benefit? </p> <p> A <em>deterministic</em> method without side effects is <em>referentially transparent</em>. It's also known as a <em>pure function</em>. Such functions have some very desirable qualities. </p> <p> One of these qualities is that pure functions readily compose. If the output of one function fits as the input for another, you can sequentially compose them. Always. There are <a href="https://bartoszmilewski.com/2014/11/04/category-the-essence-of-composition">deep mathematical reasons</a> for that, but suffice it to say that composition is ingrained into the fabric that pure functions are made of. </p> <p> Another quality is that you can replace a pure function call with its result. The function call is <em>equal</em> to the output. The only difference between the result and the function call is the time it takes to get it. </p> <p> Think about that in terms of Robert C. Martin's definition of abstraction. Once a pure function returns, the result is all you have to care about. How the function arrived at the result is an implementation detail. Referentially transparent functions eliminate the irrelevant and amplify the essential. As [the following figure] illustrates, they collapse arbitrary complexity to a single result; a single chunk that fits in your brain. </p> <p> <img src="/content/binary/pure-function-collapsing-to-its-result.jpg" alt="A pure function illustrated as circle with internal cogs, with arrows pointing to a single point to its right."> </p> <p> [Figure caption:] Pure function (left) collapsing to its result (right). Regardless of complexity, a referentially transparent function call can be replaced by its output. Thus, once you know what the output is, that's the only thing you need to keep track of as you read and interpret the calling code. </p> <p> On the other hand, if you want to know how the function works, you zoom in on its implementation, in the spirit of fractal architecture. That might be the <code>WillAccept</code> method [...]. This method is, in fact, not just Query, it's a pure function. When you look at the source code of that function, you've zoomed in on it, and the surrounding context is irrelevant. It operates exclusively on its input arguments and immutable class fields. </p> <p> When you zoom out again, the entire function collapses into its result. It's the only thing your brain needs to keep track of. </p> </blockquote> <p> Regardless of complexity, a referentially transparent function reduces to a single chunk: the result that it produces. Thus, referentially transparent code is code that fits in your head. </p> <h3 id="271a289f1907493ead7064542e22b490"> Conclusion <a href="#271a289f1907493ead7064542e22b490" title="permalink">#</a> </h3> <p> <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> isn't a book about functional programming, but it does advocate for the <em>functional core, imperative shell</em> (also known as an <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a>) architecture, among many other techniques, practices, and heuristics that it presents. </p> <p> I hope that you found the excerpt so inspiring that you consider buying the book. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/07/28/referential-transparency-fits-in-your-head The State functor https://blog.ploeh.dk/2021/07/19/the-state-functor/ Mon, 19 Jul 2021 15:00:00 UTC <div id="post"> <p> <em>Stateful computations as a functor. An example for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2018/03/22/functors">an article series about functors</a>. In a <a href="/2018/03/26/the-maybe-functor">previous article</a>, you saw how to implement the Maybe functor in C#. In this article, you'll see another functor example: <em>State</em>. </p> <p> In functional programming, sooner or later a particular question comes up: How do you implement a stateful computation without mutating state? </p> <p> You use a polymorphic function that takes the current state as input and returns the new state and a result as output. In a C-based language like C#, you can model it as an interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IState</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;Tuple&lt;T,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Run</span>(S&nbsp;<span style="color:#1f377f;">state</span>); }</pre> </p> <p> The interface is generic in both the type of state and the type of return value. Notice that the type declaration lists the state type <code>S</code> before the type of the value <code>T</code>, whereas the returned tuple lists <code>T</code> before <code>S</code>. This is quite confusing, but is how <a href="https://www.haskell.org">Haskell</a> does it. Not ideal, but I've chosen to keep that convention for the benefit of readers who'd like to compare the various implementations. </p> <p> This article introduces the implementation and machinery of the type. In a later article I'll show an example. </p> <h3 id="9fb14b122a344d1c92760bea12097a70"> A nonsense example <a href="#9fb14b122a344d1c92760bea12097a70" title="permalink">#</a> </h3> <p> You can implement the interface by doing something useful, or, as in the following example, something fatuous like expanding (or contracting) all vowels in a word according to an integer state: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">VowelExpander</span>&nbsp;:&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">string</span>&nbsp;text; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">VowelExpander</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">text</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.text&nbsp;=&nbsp;text; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#74531f;">Run</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">const</span>&nbsp;<span style="color:blue;">string</span>&nbsp;vowels&nbsp;=&nbsp;<span style="color:#a31515;">&quot;aeiouy&quot;</span>; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expanded</span>&nbsp;=&nbsp;text.SelectMany(<span style="color:#1f377f;">c</span>&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vowels.Contains(c)&nbsp;? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enumerable.Repeat(c,&nbsp;state)&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;c&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">newState</span>&nbsp;=&nbsp;state&nbsp;+&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">string</span>(expanded.ToArray()),&nbsp;newState); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This class repeats each vowel in a string by the number indicated by the current state. It also increments the state. Here's a parametrised test that shows how various input produces different outputs: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;0,&nbsp;<span style="color:#a31515;">&quot;f&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;2,&nbsp;<span style="color:#a31515;">&quot;foooo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;0,&nbsp;<span style="color:#a31515;">&quot;br&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;2,&nbsp;<span style="color:#a31515;">&quot;baar&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BasicUsageExample</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">txt</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">count</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(txt); &nbsp;&nbsp;&nbsp;&nbsp;Tuple&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;s.Run(count); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Tuple.Create(expected,&nbsp;count&nbsp;+&nbsp;1),&nbsp;t); }</pre> </p> <p> That's just one, simple stateful computation. It's a silly example, but it's <a href="https://en.wikipedia.org/wiki/Referential_transparency">referentially transparent</a>. </p> <h3 id="c8f53e5b19e64458a4f7b42de60991d0"> Functor <a href="#c8f53e5b19e64458a4f7b42de60991d0" title="permalink">#</a> </h3> <p> You can turn the <code>IState</code> interface into a functor by adding an appropriate <code>Select</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IState&lt;S,&nbsp;T1&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;SelectState&lt;S,&nbsp;T,&nbsp;T1&gt;(source,&nbsp;selector); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">SelectState</span>&lt;<span style="color:#2b91af;">S</span>,&nbsp;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;&nbsp;:&nbsp;IState&lt;S,&nbsp;T1&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;IState&lt;S,&nbsp;T&gt;&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;Func&lt;T,&nbsp;T1&gt;&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">SelectState</span>(IState&lt;S,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">source</span>,&nbsp;Func&lt;T,&nbsp;T1&gt;&nbsp;<span style="color:#1f377f;">selector</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.source&nbsp;=&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.selector&nbsp;=&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;T1,&nbsp;S&gt;&nbsp;<span style="color:#74531f;">Run</span>(S&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tuple&lt;T,&nbsp;S&gt;&nbsp;<span style="color:#1f377f;">tuple</span>&nbsp;=&nbsp;source.Run(state); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T1&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;selector(tuple.Item1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(projection,&nbsp;tuple.Item2); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> A functor maps from one contained type to another, in this case from <code>T</code> to <code>T1</code>, while the state type <code>S</code> remains the same. Notice that it's possible to change the value of the state, but not the type. Even though the State functor has two generic type arguments, it's <em>not</em> a <a href="/2018/12/24/bifunctors">bifunctor</a>. You can pick any type you'd like for <code>S</code>, such as <code>int</code> in the above <code>VowelExpander</code>, but once you've picked a type for the state, you can't project it. It's possible to prove that you can't implement a lawful mapping for the <code>S</code> dimension of State, but if you'd like to understand it intuitively, it's a great exercise to try to implement a function from <code>IState&lt;S, T&gt;</code> to <code>IState&lt;S1, T&gt;</code>. Try it, and you'll soon learn why this is impossible. </p> <p> Here's an example of using the <code>Select</code> method to project an <code>IState&lt;int, string&gt;</code> to <code>IState&lt;int, int&gt;</code>: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BasicSelectExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(<span style="color:#a31515;">&quot;bar&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;s.Select(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x.Length); &nbsp;&nbsp;&nbsp;&nbsp;Tuple&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;projection.Run(2); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Tuple.Create(4,&nbsp;3),&nbsp;t); }</pre> </p> <p> As usual, you can also use query syntax: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">QuerySyntaxExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(<span style="color:#a31515;">&quot;baz&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;<span style="color:blue;">int</span>,&nbsp;DayOfWeek&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;txt&nbsp;<span style="color:blue;">in</span>&nbsp;s &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;txt.Length&nbsp;%&nbsp;2&nbsp;==&nbsp;0&nbsp;?&nbsp;DayOfWeek.Friday&nbsp;:&nbsp;DayOfWeek.Sunday; &nbsp;&nbsp;&nbsp;&nbsp;Tuple&lt;DayOfWeek,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&nbsp;projection.Run(3); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Tuple.Create(DayOfWeek.Sunday,&nbsp;4),&nbsp;t); }</pre> </p> <p> This is, once again, a nonsensical function that only exists to show that arbitrary projections are possible. </p> <h3 id="c39f632f07d345c98940a7c65ffeead1"> First functor law <a href="#c39f632f07d345c98940a7c65ffeead1" title="permalink">#</a> </h3> <p> The <code>Select</code> method obeys the first functor law. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the first functor law for the <code>IState&lt;S, T&gt;</code> interface. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the first functor law: </p> <p> <pre>[Theory] [InlineData(DayOfWeek.Monday)] [InlineData(DayOfWeek.Tuesday)] [InlineData(DayOfWeek.Wednesday)] [InlineData(DayOfWeek.Thursday)] [InlineData(DayOfWeek.Friday)] [InlineData(DayOfWeek.Saturday)] [InlineData(DayOfWeek.Sunday)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FirstFunctorLaw</span>(DayOfWeek&nbsp;<span style="color:#1f377f;">day</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;Guid,&nbsp;Guid&gt;&nbsp;<span style="color:#1f377f;">id</span>&nbsp;=&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&gt;&nbsp;g; &nbsp;&nbsp;&nbsp;&nbsp;IState&lt;DayOfWeek,&nbsp;Guid&gt;&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;DayIdentifier(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(s.Run(day),&nbsp;s.Select(id).Run(day)); }</pre> </p> <p> This test uses another frivolous <code>IState</code> implementation: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">DayIdentifier</span>&nbsp;:&nbsp;IState&lt;DayOfWeek,&nbsp;Guid&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Guid&nbsp;Monday&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Guid(<span style="color:#a31515;">&quot;5AB18569-29C7-4041-9719-5255266B808D&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Guid&nbsp;OtherDays&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Guid(<span style="color:#a31515;">&quot;00553FC8-82C9-40B2-9FAA-F9ADFFD4EE66&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Tuple&lt;Guid,&nbsp;DayOfWeek&gt;&nbsp;<span style="color:#74531f;">Run</span>(DayOfWeek&nbsp;<span style="color:#1f377f;">state</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(state&nbsp;==&nbsp;DayOfWeek.Monday) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(Monday,&nbsp;DayOfWeek.Tuesday); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Tuple.Create(OtherDays,&nbsp;DayOfWeek.Monday); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> I only chose to write another implementation of <code>IState</code> to show a bit of variation, and to demonstrate that both <code>S</code> and <code>T</code> can be whichever type you need them to be. </p> <p> The above test cases pass. </p> <h3 id="9126274332ae4a319d8db277fef66a68"> Second functor law <a href="#9126274332ae4a319d8db277fef66a68" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>IState</code> obeys the second functor law: </p> <p> <pre>[Theory] [InlineData(&nbsp;<span style="color:#a31515;">&quot;foo&quot;</span>,&nbsp;0)] [InlineData(&nbsp;<span style="color:#a31515;">&quot;bar&quot;</span>,&nbsp;1)] [InlineData(&nbsp;<span style="color:#a31515;">&quot;baz&quot;</span>,&nbsp;2)] [InlineData(<span style="color:#a31515;">&quot;quux&quot;</span>,&nbsp;3)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">SecondFunctorLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">txt</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x.Length; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x&nbsp;%&nbsp;2&nbsp;==&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;VowelExpander(txt); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.Select(g).Select(f).Run(i), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.Select(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;f(g(x))).Run(i)); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Instead of explicitly declaring the functions as <code>Func</code> variables, this test uses a (relatively) new C# feature called <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions">local functions</a>. </p> <p> You can't easily compare two different functions for equality, so this test defines equality as the functions producing the same result when you <code>Run</code> them. </p> <p> Again, while the test doesn't prove anything, it demonstrates that for the five test cases, it doesn't matter if you project the state <code>s</code> in one or two steps. </p> <h3 id="584dea4732f54b749bd60d36c0b2dec0"> Haskell <a href="#584dea4732f54b749bd60d36c0b2dec0" title="permalink">#</a> </h3> <p> In Haskell, State is <a href="https://hackage.haskell.org/package/mtl/docs/Control-Monad-State.html">available in the mtl package</a>. You can implement the behaviour from <code>VowelExpander</code> like this: </p> <p> <pre><span style="color:#2b91af;">expandVowels</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">Int</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;(<span style="color:#2b91af;">String</span>,&nbsp;<span style="color:#2b91af;">Int</span>) expandVowels&nbsp;text&nbsp;s&nbsp;= &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;vowels&nbsp;=&nbsp;<span style="color:#a31515;">&quot;aeiouy&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expanded&nbsp;=&nbsp;text&nbsp;&gt;&gt;=&nbsp;(\c&nbsp;-&gt;&nbsp;<span style="color:blue;">if</span>&nbsp;c&nbsp;`elem`&nbsp;vowels&nbsp;<span style="color:blue;">then</span>&nbsp;<span style="color:blue;">replicate</span>&nbsp;s&nbsp;c&nbsp;<span style="color:blue;">else</span>&nbsp;[c]) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newState&nbsp;=&nbsp;s&nbsp;+&nbsp;1 &nbsp;&nbsp;<span style="color:blue;">in</span>&nbsp;(expanded,&nbsp;newState)</pre> </p> <p> Instead of defining an interface, you can use any function <code>s -&gt; (a, s)</code>, which you can elevate to the State functor using a function called <code>state</code>. You can then use <code>fmap</code> or <code>&lt;$&gt;</code> to map the value: </p> <p> <pre>&gt; runState (length &lt;$&gt; state (expandVowels "bar")) 2 (4,3)</pre> </p> <p> You can see a more useful example of the Haskell State functor in use in the article <a href="/2019/03/11/an-example-of-state-based-testing-in-haskell">An example of state-based testing in Haskell</a>. </p> <h3 id="eea12540db2a4c1cb33c5f005134cde4"> Conclusion <a href="#eea12540db2a4c1cb33c5f005134cde4" title="permalink">#</a> </h3> <p> A function that takes a state value as input and returns a value and a (potentially new) state value as output is a functor known as <em>State</em>. It can be used as a convenient way to express stateful computations as pure functions. </p> <p> <strong>Next:</strong> <a href="/2020/06/22/the-io-functor">The IO functor</a>. </p> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/07/19/the-state-functor A reading of Extensibility for the Masses https://blog.ploeh.dk/2021/07/12/a-reading-of-extensibility-for-the-masses/ Mon, 12 Jul 2021 05:36:00 UTC <div id="post"> <p> <em>A paper read and translated to C#.</em> </p> <p> When I have the time (and I do make this a priority) I set aside an hour every day to study. Lately I've been using these time slots to read and reproduce the code in the 2012 paper <em>"Extensibility for the Masses. Practical Extensibility with Object Algebras"</em> by Bruno C. d. S. Oliveira and William R. Cook. As is often common with academic papers, they don't have a single, authoritative address on the internet. You can find the paper in various places. I've used <a href="https://www.cs.utexas.edu/~wcook/Drafts/2012/ecoop2012.pdf">a copy hosted by University of Texas</a>, which is the institution with which William R. Cook is associated. </p> <p> While the example code in the paper is in Java, the authors claim that it translates easily to C#. I decided to give this a try, and found it to be true. </p> <h3 id="673345bb9c48466790a40e4c5e239240"> Git repository <a href="#673345bb9c48466790a40e4c5e239240" title="permalink">#</a> </h3> <p> From the beginning I created <a href="https://github.com/ploeh/ExtensibilityForMasses">a Git repository</a> with an eye to publishing it in case anyone was interested in looking over my shoulder. Not only can you see the 'final' translation, but you can also follow along with each commit. </p> <p> I committed each time I had something that seemed to work. When I struggled to understand how to interpret some of the code, I left detailed commit messages describing my doubts, and explaining why I had chosen to interpret things in a particular way. </p> <p> Along the way I also added automated tests, because I found that the paper lacked examples. Those tests represent my own interpretation of the code in the paper, and how one is supposed to use it. In total, I wrote 75 test cases. </p> <h3 id="05a8b46089be4fed9ead17648df68bef"> Help from one of the authors <a href="#05a8b46089be4fed9ead17648df68bef" title="permalink">#</a> </h3> <p> At one time I hit a snag that I couldn't readily resolve. After searching the web in vain, I posted <a href="https://stackoverflow.com/q/67818254/126014">a question on Stack Overflow</a>. After a few days, I got an answer from Bruno C. d. S. Oliveira, one of the authors of the paper! </p> <p> It turns out that some of my confusion stemmed from an otherwise inconsequential error in the paper. We shouldn't be shocked that an academic paper contains errors. One of many things I learned from reading Charles Petzold's excellent book <a href="http://amzn.to/2n9MFGh">The Annotated Turing</a> was that later researchers found several errors in Turing's 1936 paper, but none that changed the overall conclusion. So it seems to be here as well. There's at least one confirmed error (and another one that I only suspect), but it's inconsequential and easily corrected. </p> <p> It does, however, raise a point about scientific papers in general: Even if they're peer-reviewed they may contain errors. I'm <a href="/2020/05/25/wheres-the-science">much in favour of scientific knowledge, but also sceptical about some claims about computer science and software engineering</a>. </p> <h3 id="1cd1086ddbe84c83910dddad451efdbc"> Readability <a href="#1cd1086ddbe84c83910dddad451efdbc" title="permalink">#</a> </h3> <p> The paper's title claims to give extensibility to the masses, but will 'the masses' be able to read the paper? As papers go, I found this one quite readable. While other papers present their examples in <a href="https://www.haskell.org">Haskell</a>, this one uses Java. If you're comfortable with Java (or C#), you should be able to follow the code examples (or my C# translation). </p> <p> You won't entirely escape Greek letters or other <a href="/2021/06/07/abstruse-nomenclature">abstruse nomenclature</a>. This is, after all, an academic paper, so it can't be lucid all the way through. There's a section called <em>Algebraic Signatures, F-Algebras, and Church Encodings</em> that is definitely not for 'the masses'. I understand enough about <a href="https://bartoszmilewski.com/2017/02/28/f-algebras/">F-algebras</a> and <a href="/2018/05/22/church-encoding">Church encodings</a> to follow the outline of this section, but I didn't find it helpful. </p> <p> If you're interested in the overall article, but don't know what these words mean, I suggest you skim those parts and pay as much attention to the details as when <a href="https://en.wikipedia.org/wiki/Geordi_La_Forge">Geordi La Forge</a> spews <a href="https://en.wikipedia.org/wiki/Technobabble">technobabble</a>. In other words, I think you can follow the rest of the article just was well, even if <em>Church<sub>Σ</sub> = ∀A.(T<sub>1</sub> → A) × ... × (T<sub>n</sub> → A) → A</em> makes no sense to you. </p> <h3 id="c42c389e557a47848d4c66af477297ca"> Conclusion <a href="#c42c389e557a47848d4c66af477297ca" title="permalink">#</a> </h3> <p> Does the paper deliver on its promise? Yes and no. Formally, I think that it does. In the beginning, it establishes some criteria for a successful solution, and as far as I can tell, it can check off all of them. </p> <p> It's also true that the proposed solution requires only intermediary language features. Generics and inheritance, as they're available in C# and Java, is all that's required. </p> <p> On the other hand, I don't find the paper's examples compelling. Few 'mass developers' are tasked with implementing a simple expression-based language. I can't shake the feeling that most of what the paper accomplishes could be handled with tasty application of composition and the <a href="https://en.wikipedia.org/wiki/Adapter_pattern">Adapter pattern</a>. </p> <p> Still, I'll keep this paper in mind if I ever have to publish a reusable and extensible, type-safe software library. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="eddd9051446447b8ae4831a703c1ccbf"> <div class="comment-author"><a href="https://github.com/Joker-vD">Joker_vD</a></div> <div class="comment-content"> <p> I was intrigued by the paper's abstract, but then it turned out it's just about implementing Oleg Kiselyov's final (typed, tagless) encoding in plain boring Java/C# &mdash; the most surprising thing is that it doesn't really mention Kiselyov's work which predates this paper by 3-4 years. And Kiselyov in his writings moslty used really basic Haskell features so translating it to Java/C# is pretty straightforward, I actually did with it the last Autumn, toying with the idea, so I feel this paper could very well have been a (small) blog post, really. Anyway, let's talk about the proposed solution itself. </p> <p> And the solution is actually pretty ingenious! The conventional approach to representing AST and writing interpreters (in broad sense) for it is to represent AST as a tree of objects, and interpret it by walking this tree over, doing the work in the process. The problem is that to add a new kind of node to AST you need to patch all existing intepreters, and writing an interpreter involves either manual dynamic dispatch on the node types in the interpreter's code, or trying to shift it onto the nodes itself somehow (cf. Visitor pattern). </p> <p> The proposed solution neatly side steps the whole problem of representing an AST by simply not representing it as a piece of data <b>at all</b>, it instead interprets a (would-be) AST right at the moment of the construction. And so the interpreters &mdash; instead of being written as vistors &mdash; are written as builders that build the resulting value. </p> <p> As I said, it's very ingenious but it is also, sadly, largely pointless. You see, it all largely started with the Haskell programmers trying to make ASTs more statically typed to get rid of as many runtime checks and "this case is impossible" in switches in the interpreters: you have to check that e.g. the <code>if</code>'s condition (which is usually just a plain <code>Expr</code>) must evaluate to boolean, but if you make its type some sort of <code>Expr&lt;BoolType&rt;</code>, the Haskell's typechecker won't allow you to build a malformed AST in the first place! It led to introduction of GADTs, then to extending GADTs even further, and I guess at some point some people started feeling kinda uneasy about going this close to the full-blown dependent types, and so the tagless final encoding was born: as I said in the beginning, it uses very boring and straightforward Haskell features &mdash; parametric polymorphism and typeclasses &mdash; or, as they're more widely known, generics and interfaces. But then again, as it evolved, it too started require language extensions although not as radical as in previous cases, and at some point waded into the esoteric type-level meta-programming territory. </p> <p> So here's the pointless part: the initial goal was to push type-checking of the (mini-)language being implemented onto the Haskell's typechecker, and it makes implementing small, typed mini-languages that are essentially Haskell's subset <i>very</i> easy, but... if you program in Haskell, what do you need this toy of a language for? And do its types/semantics really align that well with Haskell's? If they don't, this whole ordeal becomes very difficult: imagine a language with three variables (<code>A</code>, <code>B</code>, and <code>C</code>) that can hold either integers or booleans, constants, assignments, basic arithmetic and comparison operators, <code>if-then-else</code> statement and <code>while</code> loop. Trying to encode it in Haskell type-safely (so that variables would have consistent types after all branches/loops' ends) is pretty non-trivial, whether you use GADTs or the approach from the paper. I've seen a blogpost where this exact excercise was done, and it was done in Coq, with essential use of dependent typing. </p> <p> And trying to pull this off in a language like Java/C# with much more limited type-system is, I would argue, fundamentally misguided. Eric Lippert has summed it quite well in his "Wizards and warriors, part five": </p> <quote> We have no reason to believe that the C# type system was designed to have sufficient generality to encode the rules of Dungeons &amp; Dragons, so why are we even trying? </quote> <p> Then, of course, there is a problem that in this approach, AST does not actually exist as an object: it's represented as a function/method. If the interpreter you write needs multiple passes over AST, I am afraid you'll have to materialize your AST and AFAIK you can't really fine-tune or optimize the representation of closures in Java/C#. Of course, if you <i>don't</i> need multiple passes, then this approach is perfectly fine, and in fact, that's actually how one-pass compilers are usually structured: the parser straight up calls the code-generating hooks, and when it's done, the code-gen is done. </p> <p> And when it comes down to actual extensibility, that is, the case when a new node type is added to AST, this approach really doesn't win much compared to conventional visitors: ideally, since interfaces should be immutable, such addition means that a new visitor interface is declared (an extension of the old one) which can be implemented by inheriting from the old interpreter, or by Adapting it &mdash; just the same that would be done in the proposed approach. </p> <p> So, my conclusion: this paper tries to solve the problem of AST representation/interpretation by telling us to essentially write one-pass compilers, in the name of not writing semantic checking code for AST ourselves but instead of shifting it onto the shoulders of Java/C# type checker. No, sorry, but that's not a solution to the actual problem. </p> </div> <div class="comment-date">2021-07-14 01:21 UTC</div> </div> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/07/12/a-reading-of-extensibility-for-the-masses Fractal hex flowers https://blog.ploeh.dk/2021/07/05/fractal-hex-flowers/ Mon, 05 Jul 2021 08:51:00 UTC <div id="post"> <p> <em>The code behind the cover of Code That Fits in Your Head</em> </p> <p> A book needs a cover, but how do you choose a cover illustration for a programming book? Software development tends to be abstract, so how to pick a compelling picture? </p> <p> Occasionally, a book manages to do everything right, such as the wonderful <a href="https://amzn.to/3fEB938">Mazes for Programmers</a>, which also happens to have a cover appropriate for its contents. Most publishers, however, resort to pictures of bridges, outer space, animals, or folk costumes. </p> <p> For <a href="/code-that-fits-in-your-head">my new book</a>, I wanted a cover that, like <em>Mazes for Programmers</em>, relates to its contents. Fortunately, the book contains a few concepts that easily visualise, including a concept I call <em>fractal architecture</em>. You can create some compelling drawings based on <em>hex flowers</em> nested within the petals of other hex flowers. I chose to render some of those for the book cover: </p> <p> <img src="/content/binary/ctfiyh.jpg" alt="Book cover."> </p> <p> I used <a href="https://observablehq.com">Observable</a> to host the code that renders the fractal hex flowers. This enabled me to experiment with various colour schemes and effects. Here's one example: </p> <p> <img src="/content/binary/decayed-purple-lace.png" alt="Fractal hex flower rendering example."> </p> <p> Not only did I write the program to render the figures on Observable, I turned the notebook into <a href="https://observablehq.com/@ploeh/fractal-hex-flowers">a comprehensive article</a> explaining not only how to draw the figures, but also the geometry behind it. </p> <p> The present blog post is really only meant as a placeholder. The real article is over at Observable. <a href="https://observablehq.com/@ploeh/fractal-hex-flowers">Go there to read it</a>. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/07/05/fractal-hex-flowers Property-based testing is not the same as partition testing https://blog.ploeh.dk/2021/06/28/property-based-testing-is-not-the-same-as-partition-testing/ Mon, 28 Jun 2021 06:45:00 UTC <div id="post"> <p> <em>Including an example of property-based testing without much partitioning.</em> </p> <p> A <a href="https://twitter.com/marick/status/1375601495916285952">tweet from Brian Marick</a> induced me to read a paper by Dick Hamlet and Ross Taylor called <em>Partition Testing Does Not Inspire Confidence</em>. In general, I find the conclusion fairly intuitive, but on the other hand hardly an argument against <a href="/property-based-testing-intro">property-based testing</a>. </p> <p> I'll later return to why I find the conclusion intuitive, but first, I'd like to address the implied connection between <a href="https://en.wikipedia.org/wiki/Equivalence_partitioning">partition testing</a> and property-based testing. I'll also show a detailed example. </p> <p> The source code used in this article is <a href="https://github.com/ploeh/FizzBuzzHaskellPropertyBased">available on GitHub</a>. </p> <h3 id="3cb59648be0044c88e5525583013c822"> Not the same <a href="#3cb59648be0044c88e5525583013c822" title="permalink">#</a> </h3> <p> The Hamlet & Taylor paper is exclusively concerned with partition testing, which makes sense, since it's from 1990. As far as I'm aware, property-based testing wasn't invented until later. </p> <p> Brian Marick extends its conclusions to property-based testing: <blockquote> <p> "I've been a grump about property-based testing because I bought into the conclusion of Hamlet&Taylor's 1990 "Partition testing does not inspire confidence"" </p> <footer><cite><a href="https://twitter.com/marick/status/1375601495916285952">Brian Marick</a></cite></footer> </blockquote> This seems to imply that property-based testing isn't effective, because (if you accept the paper's conclusions) partition testing isn't effective. </p> <p> There's certainly overlap between partition testing and property-based testing, but it's not complete. Some property-based testing isn't partition testing, or the other way around: </p> <p> <img src="/content/binary/partition-property-based-testing-venn.png" alt="Venn diagram of partition testing and property-based testing."> </p> <p> To be fair, the overlap may easily be larger than the figure implies, but you can certainly describes properties without having to partition a function's domain. </p> <p> In fact, the canonical example of property-based testing (that reversing a list twice yields the original list: <code>reverse (reverse xs) == xs</code>) does <em>not</em> rely on partitioning. It works for all finite lists. </p> <p> You may think that this is only because the case is so simple, but that's not the case. You can also <a href="/2015/01/10/diamond-kata-with-fscheck">avoid partitioning on the slightly more complex problem presented by the Diamond kata</a>. In fact, <a href="/2015/02/23/property-based-testing-without-a-property-based-testing-framework">the domain for that problem is so small that you don't need a property-based framework</a>. </p> <p> You may argue that the Diamond kata is another toy problem, but I've also <a href="/2021/02/15/when-properties-are-easier-than-examples">solved a realistic, complex business problem with property-based testing without relying on partitioning</a>. Granted, the property shown in that article doesn't sample uniformly from the entire domain of the System Under Test, but the property (there's only one) doesn't rely on partitioning. Instead, it relies on incremental tightening of preconditions to tease out the desired behaviour. </p> <p> I'll show another example next. </p> <h3 id="1c81c19841b74fe7af2726b20689291c"> FizzBuzz via partitioning <a href="#1c81c19841b74fe7af2726b20689291c" title="permalink">#</a> </h3> <p> When introducing equivalence classes and property-based testing in workshops, I sometimes use the <a href="https://codingdojo.org/kata/FizzBuzz">FizzBuzz kata</a> as an example. When I do this, I first introduce the concept of equivalence classes and then proceed to explain how instead of manually picking values from each partition, you can randomly sample from them: </p> <p> <pre>[&lt;Property(QuietOnSuccess&nbsp;=&nbsp;<span style="color:blue;">true</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``FizzBuzz.transform&nbsp;returns&nbsp;Buzz``&nbsp;(number&nbsp;:&nbsp;int)&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;(number&nbsp;%&nbsp;5&nbsp;=&nbsp;0&nbsp;&amp;&amp;&nbsp;number&nbsp;%&nbsp;3&nbsp;&lt;&gt;&nbsp;0)&nbsp;==&gt;&nbsp;<span style="color:blue;">lazy</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;FizzBuzz.transform&nbsp;number &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;expected&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Buzz&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;expected&nbsp;=&nbsp;actual</pre> </p> <p> (That's <a href="https://fsharp.org">F#</a> code, but the rest of the code in this article is going to be Haskell.) </p> <p> While this gently introduces the concept of testing based on randomly sampling inputs, it relies heavily on partitioning. The above example filters inputs so that it only runs with numbers that are divisible by five, but not by three. </p> <p> As at least one workshop attendee objected, it's getting perilously close to reproducing the implementation logic in the test. It always hurts when someone directs valid criticism at you, but he was right. That's not a problem with property-based testing, though, but rather with the way I presented it. </p> <p> We can do better. </p> <h3 id="a26215089b75410da8da386a3b29b25c"> FizzBuzz with proper properties <a href="#a26215089b75410da8da386a3b29b25c" title="permalink">#</a> </h3> <p> The trick to 'true' property-based testing is identifying proper properties for the problem being solved. Granted, this can be difficult and often requires some creative thinking (which is also why I find it so enjoyable). Fortunately, certain patterns tend to recur; for example, <a href="https://fsharpforfunandprofit.com/">Scott Wlaschin</a> has a <a href="https://fsharpforfunandprofit.com/posts/property-based-testing-2/">small collection of property-based testing patterns</a>. </p> <p> As the FizzBuzz kata is described, the domain for a <code>fizzBuzz</code> function is only the numbers from one to 100. Let's be generous, however, and expand it to all integers, since it makes no practical difference. </p> <p> In <a href="https://www.haskell.org">Haskell</a>, for example, we might aim for a function with this API: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;(<span style="color:blue;">Integral</span>&nbsp;a,&nbsp;<span style="color:blue;">Show</span>&nbsp;a)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span></pre> </p> <p> Is it possible to test-drive the correct implementation with <a href="https://en.wikipedia.org/wiki/QuickCheck">QuickCheck</a> without relying on partitioning? </p> <p> I must admit that I can't figure out how to entirely avoid partitioning, but it's possible to bootstrap the process using only a single partition. If you know of a way to entirely do without partitioning, <a href="https://github.com/ploeh/ploeh.github.com#readme">leave a comment</a>. </p> <h3 id="e2bddf57cd8247f799ef6b9bd6e7c726"> FizzBuzz <a href="#e2bddf57cd8247f799ef6b9bd6e7c726" title="permalink">#</a> </h3> <p> In order to anchor the behaviour, we have to describe how at least a single value translates to a string, for example that all multiples of both three and five translate to "FizzBuzz". It might be enough to simply state that a small number like <code>0</code> or <code>15</code> translates to <code>"FizzBuzz"</code>, but we might as well exercise that entire partition: </p> <p> <pre>testProperty&nbsp;<span style="color:#a31515;">&quot;Divisible&nbsp;by&nbsp;both&nbsp;3&nbsp;and&nbsp;5&quot;</span>&nbsp;$&nbsp;\&nbsp;(seed&nbsp;::&nbsp;Int)&nbsp;-&gt; &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;i&nbsp;=&nbsp;seed&nbsp;*&nbsp;3&nbsp;*&nbsp;5 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actual&nbsp;=&nbsp;fizzBuzz&nbsp;i &nbsp;&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span>&nbsp;===&nbsp;actual</pre> </p> <p> Here I take <em>any</em> integer <code>seed</code> and use it to produce an integer <code>i</code> which is guaranteed to belong to the partition that always produces the output <code>"FizzBuzz"</code>. </p> <p> Certainly, this tests only a single partition, but as <a href="https://twitter.com/johanneslink/status/1375681159166881793">Johannes Link points out</a>, property-based testing still performs randomised testing <em>within</em> the partition. </p> <p> The simplest implementation that passes the test is this: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;<span style="color:blue;">Integral</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;_&nbsp;=&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span></pre> </p> <p> From here, however, it's possible to describe the rest of the problem without relying on partition testing. </p> <h3 id="961b66d9d9124f279d1f080ff9cb9044"> At least one number in three consecutive values <a href="#961b66d9d9124f279d1f080ff9cb9044" title="permalink">#</a> </h3> <p> How to proceed from there long eluded me. Then it dawned on me that while it's hard to test <em>a single call</em> to the <code>fizzBuzz</code> function without relying on partitioning, you can examine the output from projecting a small range of inputs to outputs. </p> <p> What happens if we pick a random number, use it as an origin to enumerate three numbers in total (that is: two more numbers), and then call <code>fizzBuzz</code> with each of them? </p> <p> Imagine what happens if we randomly pick <em>10</em>. In that case, we're going to enumerate three numbers, starting with <em>10: 10, 11, 12</em>. What's the expected output of applying these three numbers to <code>fizzBuzz</code>? It's <em>Buzz, 11, Fizz</em>. Let's try a few more, and make a table of it: </p> <table border="1"> <thead> <tr> <th><em>i</em></th> <th><em>i+1</em></th> <th><em>i+2</em></th> </tr> </thead> <tbody> <tr> <td><em>10 → Buzz</em></td> <td><em>11 → 11</em></td> <td><em>12 → Fizz</em></td> </tr> <tr> <td><em>11 → 11</em></td> <td><em>12 → Fizz</em></td> <td><em>13 → 13</em></td> </tr> <tr> <td><em>12 → Fizz</em></td> <td><em>13 → 13</em></td> <td><em>14 → 14</em></td> </tr> <tr> <td><em>13 → 13</em></td> <td><em>14 → 14</em></td> <td><em>15 → FizzBuzz</em></td> </tr> <tr> <td><em>14 → 14</em></td> <td><em>15 → FizzBuzz</em></td> <td><em>16 → 16</em></td> </tr> </tbody> </table> <p> Do you notice a pattern? </p> <p> There's more than a single pattern, but one is that there's <em>always at least one number</em> among the three results. Even if you have both a <em>Fizz</em> and a <em>Buzz</em>, as is the case with <em>10, 11, 12</em>, at least one of the results (<em>11</em>) remains a number. Think about it some more to convince yourself that this should always be the case for three consecutive numbers. </p> <p> That's a <em>property</em> of <code>fizzBuzz</code>, and it holds universally (also for negative integers). </p> <p> You can turn it into a QuickCheck property like this: </p> <p> <pre>testProperty&nbsp;<span style="color:#a31515;">&quot;At&nbsp;least&nbsp;one&nbsp;number&nbsp;in&nbsp;3&nbsp;consecutive&nbsp;values&quot;</span>&nbsp;$&nbsp;\&nbsp;(i&nbsp;::&nbsp;Int)&nbsp;-&gt; &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;range&nbsp;=&nbsp;[i..i+2] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actual&nbsp;=&nbsp;fizzBuzz&nbsp;&lt;$&gt;&nbsp;range &nbsp;&nbsp;<span style="color:blue;">in</span>&nbsp;counterexample &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:blue;">show</span>&nbsp;range&nbsp;++&nbsp;<span style="color:#a31515;">&quot;-&gt;&quot;</span>&nbsp;++&nbsp;<span style="color:blue;">show</span>&nbsp;actual)&nbsp;$ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">any</span>&nbsp;(\x&nbsp;-&gt;&nbsp;isJust&nbsp;(readMaybe&nbsp;x&nbsp;::&nbsp;Maybe&nbsp;Int))&nbsp;actual</pre> </p> <p> This test doesn't rely on input partitioning. It works for <em>all</em> integers. </p> <p> In this test I used QuickCheck's <code>counterexample</code> function to provide a helpful message in case of failure. Running the test suite against the above version of <code>fizzBuzz</code> yields a failure like this: </p> <p><pre>At least one number in 3 consecutive values: [<span style="color:red;">Failed</span>] *** Failed! Falsified (after 1 test): 0 [0,1,2]-&gt;["FizzBuzz","FizzBuzz","FizzBuzz"] (used seed -6204080625786338123)</pre> </p> <p> Here we see that the sequence <code>[0,1,2]</code> produces the output <code>["FizzBuzz","FizzBuzz","FizzBuzz"]</code>, which is not only wrong, but is specifically incorrect in the sense that none of the values can be parsed as an integer. </p> <p> Given the current implementation, that's hardly surprising. </p> <p> Using <a href="/2019/10/07/devils-advocate">the Devil's Advocate</a> technique, I chose to pass both tests with this implementation: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;<span style="color:blue;">Integral</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;i&nbsp;=&nbsp;<span style="color:blue;">if</span>&nbsp;i&nbsp;`mod`&nbsp;15&nbsp;==&nbsp;0&nbsp;<span style="color:blue;">then</span>&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span>&nbsp;<span style="color:blue;">else</span>&nbsp;<span style="color:#a31515;">&quot;2112&quot;</span></pre> </p> <p> The property I just added doesn't check whether the number is one of the input numbers, so the implementation can get away with returning the hard-coded string <code>"2112"</code>. </p> <h3 id="00d606085bea441abecad26711655016"> At least one Fizz in three consecutive values <a href="#00d606085bea441abecad26711655016" title="permalink">#</a> </h3> <p> Take a look at the above table. Do you notice any other patterns? </p> <p> Of each set of three results, there's always a string that <em>starts with Fizz</em>. Sometimes, as we see with the input <em>15</em>, the output is <em>FizzBuzz</em>, so it's not always just <em>Fizz</em>, but there's always a string that starts with <em>Fizz</em>. </p> <p> This is another universal property of the <code>fizzBuzz</code> function, which we can express as a test: </p> <p> <pre>testProperty&nbsp;<span style="color:#a31515;">&quot;At&nbsp;least&nbsp;one&nbsp;Fizz&nbsp;in&nbsp;3&nbsp;consecutive&nbsp;values&quot;</span>&nbsp;$&nbsp;\&nbsp;(i&nbsp;::&nbsp;Int)&nbsp;-&gt; &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;range&nbsp;=&nbsp;[i..i+2] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actual&nbsp;=&nbsp;fizzBuzz&nbsp;&lt;$&gt;&nbsp;range &nbsp;&nbsp;<span style="color:blue;">in</span>&nbsp;counterexample &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:blue;">show</span>&nbsp;range&nbsp;++&nbsp;<span style="color:#a31515;">&quot;-&gt;&quot;</span>&nbsp;++&nbsp;<span style="color:blue;">show</span>&nbsp;actual)&nbsp;$ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">any</span>&nbsp;(<span style="color:#a31515;">&quot;Fizz&quot;</span>&nbsp;`isPrefixOf`)&nbsp;actual</pre> </p> <p> Again, no partitioning is required to express this property. The arbitrary parameter <code>i</code> is unconstrained. </p> <p> To pass all tests, I implemented <code>fizzBuzz</code> like this: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;<span style="color:blue;">Integral</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;i&nbsp;=&nbsp;<span style="color:blue;">if</span>&nbsp;i&nbsp;`mod`&nbsp;3&nbsp;==&nbsp;0&nbsp;<span style="color:blue;">then</span>&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span>&nbsp;<span style="color:blue;">else</span>&nbsp;<span style="color:#a31515;">&quot;2112&quot;</span></pre> </p> <p> It doesn't look as though much changed, but notice that the modulo check changed from <em>modulo 15</em> to <em>modulo 3</em>. While incorrect, it passes all tests. </p> <h3 id="f08b2d56249b4390808ee727273825a9"> Only one Buzz in five consecutive values <a href="#f08b2d56249b4390808ee727273825a9" title="permalink">#</a> </h3> <p> Using the same reasoning as above, another property emerges. If, instead of looking at sequences of three input arguments, you create five values, only one of them should result in a <em>Buzz</em> result; e.g. <em>8, 9, 10, 11, 12</em> should result in <em>8, Fizz, Buzz, 11, Fizz</em>. Sometimes, however, the <em>Buzz</em> value is <em>FizzBuzz</em>, for example when the origin is <em>11: 11, 12, 13, 14, 15</em> should produce <em>11, Fizz, 13, 14, FizzBuzz</em>. </p> <p> Like the above property, there's only one <em>Buzz</em>, but sometimes it's part of a compound word. What's clear, though, is that there should be only one result that ends with <em>Buzz</em>. </p> <p> Not only is the idea similar to the one above, so is the test: </p> <p> <pre>testProperty&nbsp;<span style="color:#a31515;">&quot;Only&nbsp;one&nbsp;Buzz&nbsp;in&nbsp;5&nbsp;consecutive&nbsp;values&quot;</span>&nbsp;$&nbsp;\&nbsp;(i&nbsp;::&nbsp;Int)&nbsp;-&gt; &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;range&nbsp;=&nbsp;[i..i+4] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actual&nbsp;=&nbsp;fizzBuzz&nbsp;&lt;$&gt;&nbsp;range &nbsp;&nbsp;<span style="color:blue;">in</span>&nbsp;counterexample &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:blue;">show</span>&nbsp;range&nbsp;++&nbsp;<span style="color:#a31515;">&quot;-&gt;&quot;</span>&nbsp;++&nbsp;<span style="color:blue;">show</span>&nbsp;actual)&nbsp;$ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;==&nbsp;<span style="color:blue;">length</span>&nbsp;(<span style="color:blue;">filter</span>&nbsp;(<span style="color:#a31515;">&quot;Buzz&quot;</span>&nbsp;`isSuffixOf`)&nbsp;actual)</pre> </p> <p> Again, no partitioning is required to express this property. </p> <p> This version of <code>fizzBuzz</code> passes all tests: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;<span style="color:blue;">Integral</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;5&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;3&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Fizz&quot;</span> fizzBuzz&nbsp;_&nbsp;=&nbsp;<span style="color:#a31515;">&quot;2112&quot;</span></pre> </p> <p> We're not quite there yet, but we're getting closer. </p> <h3 id="13c4e94f5b38409fb8bf99ac268f40cf"> At least one literal Buzz in ten consecutive values <a href="#13c4e94f5b38409fb8bf99ac268f40cf" title="permalink">#</a> </h3> <p> What's wrong with the above implementation? </p> <p> It never returns <em>Buzz</em>. How can we express a property that forces it to do that? </p> <p> We can keep going in the same vein. We know that if we sample a sufficiently large sequence of numbers, it might produce a <em>FizzBuzz</em> value, but even if it does, there's going to be a <em>Buzz</em> value five positions before and after. For example, if the input sequence contains <em>30</em> (producing <em>FizzBuzz</em>) then both <em>25</em> and <em>35</em> should produce <em>Buzz</em>. </p> <p> How big a range should we sample to be certain that there's at least one <em>Buzz</em>? </p> <p> If it's not immediately clear, try setting up a table similar to the one above: </p> <table border="1"> <thead> <tr> <th><em>i</em></th> <th><em>i+1</em></th> <th><em>i+2</em></th> <th><em>i+3</em></th> <th><em>i+4</em></th> <th><em>i+5</em></th> <th><em>i+6</em></th> <th><em>i+7</em></th> <th><em>i+8</em></th> <th><em>i+9</em></th> </tr> </thead> <tbody> <tr> <td><em>10 →<br/>Buzz</em></td> <td><em>11 →<br/>11</em></td> <td><em>12 →<br/>Fizz</em></td> <td><em>13 →<br/>13</em></td> <td><em>14 →<br/>14</em></td> <td><em>15 →<br/>FizzBuzz</em></td> <td><em>16 →<br/>16</em></td> <td><em>17 →<br/>17</em></td> <td><em>18 →<br/>Fizz</em></td> <td><em>19 →<br/>19</em></td> </tr> <tr> <td><em>11 →<br/>11</em></td> <td><em>12 →<br/>Fizz</em></td> <td><em>13 →<br/>13</em></td> <td><em>14 →<br/>14</em></td> <td><em>15 →<br/>FizzBuzz</em></td> <td><em>16 →<br/>16</em></td> <td><em>17 →<br/>17</em></td> <td><em>18 →<br/>Fizz</em></td> <td><em>19 →<br/>19</em></td> <td><em>20 →<br/>Buzz</em></td> </tr> <tr> <td><em>17 →<br/>17</em></td> <td><em>18 →<br/>Fizz</em></td> <td><em>19 →<br/>19</em></td> <td><em>20 →<br/>Buzz</em></td> <td><em>21 →<br/>Fizz</em></td> <td><em>22 →<br/>22</em></td> <td><em>23 →<br/>23</em></td> <td><em>24 →<br/>Fizz</em></td> <td><em>25 →<br/>Buzz</em></td> <td><em>26 →<br/>26</em></td> </tr> </tbody> </table> <p> Notice that as one <em>Buzz</em> drops off to the left, a new one appears to the right. Additionally, there may be more than one literal <em>Buzz</em>, but there's always at least one (that is, one that's exactly <em>Buzz</em>, and not just ending in <em>Buzz</em>). </p> <p> That's another universal property: for any consecutive sequence of numbers of length ten, there's at least one exact <em>Buzz</em>. Here's how to express that as a QuickCheck property: </p> <p> <pre>testProperty&nbsp;<span style="color:#a31515;">&quot;At&nbsp;least&nbsp;one&nbsp;literal&nbsp;Buzz&nbsp;in&nbsp;10&nbsp;values&quot;</span>&nbsp;$&nbsp;\&nbsp;(i&nbsp;::&nbsp;Int)&nbsp;-&gt; &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;range&nbsp;=&nbsp;[i..i+9] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actual&nbsp;=&nbsp;fizzBuzz&nbsp;&lt;$&gt;&nbsp;range &nbsp;&nbsp;<span style="color:blue;">in</span>&nbsp;counterexample &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:blue;">show</span>&nbsp;range&nbsp;++&nbsp;<span style="color:#a31515;">&quot;-&gt;&quot;</span>&nbsp;++&nbsp;<span style="color:blue;">show</span>&nbsp;actual)&nbsp;$ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">elem</span>&nbsp;<span style="color:#a31515;">&quot;Buzz&quot;</span>&nbsp;actual</pre> </p> <p> Again, no partitioning is required to express this property. </p> <p> This version of <code>fizzBuzz</code> passes all tests: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;<span style="color:blue;">Integral</span>&nbsp;a&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;15&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;3&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Fizz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;5&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Buzz&quot;</span> fizzBuzz&nbsp;_&nbsp;=&nbsp;<span style="color:#a31515;">&quot;2112&quot;</span></pre> </p> <p> What's left? Only that the number is still hard-coded. </p> <h3 id="a8d4a2c885c04aba85b33cfbb592dca5"> Numbers round-trip <a href="#a8d4a2c885c04aba85b33cfbb592dca5" title="permalink">#</a> </h3> <p> How to get rid of the hard-coded number? </p> <p> From one of the above properties, we know that if we pick an arbitrary consecutive sequence of three numbers, at least one of the results will be a string representation of the input number. </p> <p> It's not guaranteed to be the origin, though. If the origin is, say, <em>3</em>, the input sequence is <em>3, 4, 5</em>, which should yield the resulting sequence <em>Fizz, 4, Buzz</em>. </p> <p> Since we don't know which number(s) will remain, how can we check that it translates correctly? We can use a variation of a common property-based testing pattern - the one that Scott Wlaschin calls <em>There and back again</em>. </p> <p> We can take any sequence of three outputs and try to parse them back to integers. All successfully parsed numbers must belong to the input sequence. </p> <p> That's another universal property. Here's how to express that as a QuickCheck property: </p> <p> <pre>testProperty&nbsp;<span style="color:#a31515;">&quot;Numbers&nbsp;round-trip&quot;</span>&nbsp;$&nbsp;\&nbsp;(i&nbsp;::&nbsp;Int)&nbsp;-&gt; &nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;range&nbsp;=&nbsp;[i..i+2] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actual&nbsp;=&nbsp;fizzBuzz&nbsp;&lt;$&gt;&nbsp;range &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;numbers&nbsp;=&nbsp;catMaybes&nbsp;$&nbsp;readMaybe&nbsp;&lt;$&gt;&nbsp;actual &nbsp;&nbsp;<span style="color:blue;">in</span>&nbsp;counterexample &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<span style="color:blue;">show</span>&nbsp;range&nbsp;++&nbsp;<span style="color:#a31515;">&quot;-&gt;&quot;</span>&nbsp;++&nbsp;<span style="color:blue;">show</span>&nbsp;actual)&nbsp;$ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">all</span>&nbsp;(`elem`&nbsp;range)&nbsp;numbers</pre> </p> <p> The parsed <code>numbers</code> may contain one or two elements, but in both cases, all of them must be an element of <code>range</code>. </p> <p> Again, no partitioning is required to express this property. </p> <p> This version of <code>fizzBuzz</code> passes all tests: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;(<span style="color:blue;">Integral</span>&nbsp;a,&nbsp;<span style="color:blue;">Show</span>&nbsp;a)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;15&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;3&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Fizz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;5&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Buzz&quot;</span> fizzBuzz&nbsp;i&nbsp;=&nbsp;<span style="color:blue;">show</span>&nbsp;i</pre> </p> <p> This looks good. Let's call it a day. </p> <p> Not so fast, though. </p> <h3 id="03a0a3395a0c40deb33404f342985102"> Redundant property? <a href="#03a0a3395a0c40deb33404f342985102" title="permalink">#</a> </h3> <p> With the new round-trip property, isn't the property titled <em>At least one number in 3 consecutive values</em> redundant? </p> <p> You might think so, but it's not. What happens if we remove it? </p> <p> If you remove the <em>At least one number in 3 consecutive values</em> property, the Devil's Advocate can corrupt <code>fizzBuzz</code> like this: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;(<span style="color:blue;">Integral</span>&nbsp;a,&nbsp;<span style="color:blue;">Show</span>&nbsp;a)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;15&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;3&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Fizz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;5&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Buzz&quot;</span> fizzBuzz&nbsp;_&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Pop&quot;</span></pre> </p> <p> This passes all tests if you remove <em>At least one number in 3 consecutive values</em>. Why doesn't the <em>Numbers round-trip</em> property fail? </p> <p> It doesn't fail because with the above implementation of <code>fizzBuzz</code> its <em>numbers</em> list is always empty. This property doesn't require <em>numbers</em> to be non-empty. It doesn't have to, because that's the job of the <em>At least one number in 3 consecutive values</em> property. Thus, that property isn't redundant. Leave it in. </p> <h3 id="5efa5b0c3ed9457fb9914e94c4e9690c"> Intuition behind the paper <a href="#5efa5b0c3ed9457fb9914e94c4e9690c" title="permalink">#</a> </h3> <p> What about the results from the Hamlet & Taylor paper? Are the conclusions in the paper wrong? </p> <p> They may be, but that's not my take. Rather, the way I understand the paper, it says that partition testing isn't much more efficient at detecting errors than pure random sampling. </p> <p> I've been using the rather schizophrenic version of the Devil's Advocate technique (the one that <a href="/outside-in-tdd">I call Gollum style</a>) for so long that this conclusion rings true for me. </p> <p> Consider a truly adversarial <a href="https://fsharpforfunandprofit.com/posts/property-based-testing/">developer from Hell</a>. He or she could subvert <code>fizzBuzz</code> like this: </p> <p> <pre><span style="color:#2b91af;">fizzBuzz</span>&nbsp;::&nbsp;(<span style="color:blue;">Integral</span>&nbsp;a,&nbsp;<span style="color:blue;">Show</span>&nbsp;a)&nbsp;<span style="color:blue;">=&gt;</span>&nbsp;a&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span> fizzBuzz&nbsp;18641&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Pwnd&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;15&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;FizzBuzz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;3&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Fizz&quot;</span> fizzBuzz&nbsp;i&nbsp;|&nbsp;i&nbsp;`mod`&nbsp;&nbsp;5&nbsp;==&nbsp;0&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Buzz&quot;</span> fizzBuzz&nbsp;i&nbsp;=&nbsp;<span style="color:blue;">show</span>&nbsp;i</pre> </p> <p> The test suite is <em>very unlikely</em> to detect the error - even if you ask it to run each property a million times: </p> <p> <pre>$ stack test --ta "-a 1000000" FizzBuzzHaskellPropertyBased&gt; test (suite: FizzBuzz-test, args: -a 1000000) Divisible by both 3 and 5: [<span style="color:green;">OK, passed 1000000 tests</span>] At least one number in 3 consecutive values: [<span style="color:green;">OK, passed 1000000 tests</span>] At least one Fizz in 3 consecutive values: [<span style="color:green;">OK, passed 1000000 tests</span>] Only one Buzz in 5 consecutive values: [<span style="color:green;">OK, passed 1000000 tests</span>] At least one literal Buzz in 10 values: [<span style="color:green;">OK, passed 1000000 tests</span>] Numbers round-trip: [<span style="color:green;">OK, passed 1000000 tests</span>] Properties Total Passed <span style="color:green;">6</span> <span style="color:green;">6</span> Failed 0 0 Total <span style="color:green;">6</span> <span style="color:green;">6</span> FizzBuzzHaskellPropertyBased&gt; Test suite FizzBuzz-test passed</pre> </p> <p> How many times should we run these properties before we'd expect the <em>At least one number in 3 consecutive values</em> property to detect the error? </p> <p> In Haskell, <code>Int</code> is an <a href="https://hackage.haskell.org/package/base/docs/Data-Int.html">integer type with at least the range [-2^29 .. 2^29-1]</a> - that is, from -536,870,912 to 536,870,911, for a total range of 1,073,741,823 numbers. </p> <p> In order to detect the error, the <em>At least one number in 3 consecutive values</em> property needs to hit <em>18,641</em>, which it can only do if QuickCheck supplies an <code>i</code> value of <em>18,639</em>, <em>18,640</em>, or <em><em>18,641</em></em>. That's three values out of 1,073,741,823. </p> <p> If we assume a uniform distribution, the chance of detecting the error is <em>3 / 1,073,741,823</em>, or approximately one in 333 million. </p> <p> Neither property-based testing nor randomised testing is likely to detect this kind of error. That's basically the intuition that makes sense to me when reading the Hamlet & Taylor paper. If you don't know where to look, partition testing isn't going to help you detect errors like the above. </p> <p> I can live with that. After all, the value I get out of property-based testing is as a variation on test-driven development, rather than only quality assurance. It <a href="/2021/02/15/when-properties-are-easier-than-examples">enables me to incrementally flesh out a problem in a way that example-based testing sometimes can't</a>. </p> <h3 id="8ada6d6c1deb4a39a71876b49e5b8278"> Conclusion <a href="#8ada6d6c1deb4a39a71876b49e5b8278" title="permalink">#</a> </h3> <p> There's a big overlap between partition testing and property-based testing. Often, identifying equivalence classes is the first step to expressing a property. A conspicuous example can be seen in my article series <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a>, which shows a detailed walk-through of the <a href="https://codingdojo.org/kata/Tennis/">Tennis kata</a> done with <a href="https://fscheck.github.io/FsCheck/">FsCheck</a>. For a hybrid approach, see <a href="/2016/06/28/roman-numerals-via-property-based-tdd">Roman numerals via property-based TDD</a>. </p> <p> In my experience, it's much easier to partition a domain into equivalence classes than it is to describe universal properties of a system. Thus, many properties I write tend to be a kind of partition testing. On the other hand, it's more satisfying when you can express universal properties. I'm not sure that it's always possible, but I find that when it is, it better decouples the tests from implementation details. </p> <p> Based on the FizzBuzz example shown here, you may find it unappealing that there's more test code than 'production code'. Clearly, for a problem like FizzBuzz, this is unwarranted. That, however, wasn't the point with the example. The point was to show an easily digestible example of universal properties. For a more realistic example, I'll refer you to <a href="/2021/02/15/when-properties-are-easier-than-examples">the scheduling problem I also linked to earlier</a>. While the production code ultimately turned out to be compact, it's far from trivial. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/06/28/property-based-testing-is-not-the-same-as-partition-testing Agile pull requests https://blog.ploeh.dk/2021/06/21/agile-pull-requests/ Mon, 21 Jun 2021 05:44:00 UTC <div id="post"> <p> <em>If it hurts, do it more often.</em> </p> <p> The agile software development movement has been instrumental in <a href="https://agilemanifesto.org">uncovering better ways of developing software</a>. Under that umbrella term you find such seminal ideas as test-driven development, continuous delivery, responding to change, and so on. Yet, as we're entering the third decade of agile software development, most organisations still struggle to take in the ethos and adopt its practices. </p> <p> Change is hard. A typical reaction from a development organisation would be: </p> <p> <em>"We tried it, but it doesn't work for us."</em> </p> <p> The usual agile response to such foot-draggery is: <a href="https://martinfowler.com/bliki/FrequencyReducesDifficulty.html">if it hurts, do it more often</a>. </p> <p> I'd like to suggest exactly that remedy for a perceived problem that many agile proponents seem to believe exist. </p> <h3 id="5f207852a69a424fb5ad9625c0e5c1c4"> Pull request problems and solutions <a href="#5f207852a69a424fb5ad9625c0e5c1c4" title="permalink">#</a> </h3> <p> I like collaborating with other developers via pull requests, but I also admit that my personality may influence that preference. I like deep contemplation; I like doing things on my own time, to my own schedule; I like having the freedom to self-organise. Yes, I fit <a href="http://amzn.to/1FWUzrM">the description of an introvert</a>. Pull requests do enable contemplation, they do let me self-organise. </p> <p> Yet, I'm quite aware that there are plenty of problems with pull requests. First, many pull requests are poorly done. They are too big, bundle together unrelated things and introduce noise. I wrote an article titled <a href="/2015/01/15/10-tips-for-better-pull-requests">10 tips for better Pull Requests</a> to help developers create better pull requests. With a little practice, you can write small, focused pull requests. </p> <p> If it hurts, do it more often. </p> <p> Another problem with pull requests is in the review process. The most common criticism of the pull request process with its review phase is that it takes too long. I discuss this problem, and a remedy, in my coming book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>: <blockquote> <p> "The problem with typical approaches is illustrated by [the figure below]. A developer submits a piece of work for review. Then much time passes before the review takes place. </p> <p> <img src="/content/binary/timeline-with-long-wait-time.jpg" alt="Timeline with a long wait time between a feature is submitted for review and the review actually takes place."> </p> <p> "[Figure caption:] How not to do code reviews: let much time pass between completion of a feature and the review. (The smaller boxes to the right of the review indicates improvements based on the initial review, and a subsequent review of the improvements.) </p> <p> "[The figure below] illustrates an obvious solution to the problem. Reduce the wait time. Make code reviews part of the daily rhythm of the organisation. </p> <p> <img src="/content/binary/timeline-with-minimal-wait-time.jpg" alt="Timeline with short wait time between a feature is submitted for and the review actually takes place."> </p> <p> "[Figure caption:] Reduce the wait time between feature completion and code review. A review will typically spark some improvements, and a smaller review of those improvements. These activities are indicated by the smaller boxes to the right of the review. </p> <p> "Most people already have a routine that they follow. You should make code reviews part of that routine. You can do that on an individual level, or you can structure your team around a daily rhythm. Many teams already have a daily stand-up. Such a regularly occurring event creates an anchor around which the day revolves. Typically, lunchtime is another natural break in work. </p> <p> "Consider, for example, setting aside half an hour each morning, as well as half an hour after lunch, for reviews. </p> <p> "Keep in mind that you should make only small sets of changes. Sets that represent less than half a day's work. If you do that, and all team members review those small changes twice a day, the maximum wait time will be around four hours." </p> </blockquote> I've tried this in a small organisation, and it <em>can</em> work. I'm not claiming that it's easy, but it's hardly impossible. </p> <p> If it hurts, do it more often. </p> <p> An underlying problem is that people often feel that they don't have the time to review their colleagues' code. This is a real problem. If you are being measured (formally or informally) on your 'individual contribution', then anything you do to help your team looks like a waste of time. This is, in my opinion, an organisational problem, rather than a problem with doing reviews. </p> <p> It's also a problem that pair programming <em>doesn't</em> solve. </p> <h3 id="0b6cf5764f084c22adb075e197249e3d"> Pull requests versus pair programming <a href="#0b6cf5764f084c22adb075e197249e3d" title="permalink">#</a> </h3> <p> You <em>can</em> make the pull request process work, but should you? Isn't pair (or ensemble) programming better? </p> <p> Pair programming can also be effective. I discuss that too in <a href="/code-that-fits-in-your-head">my new book</a>. What works best, I believe, is a question of trade-offs. What's more important to you? <a href="/2020/03/16/conways-law-latency-versus-throughput">Latency or throughput</a>? </p> <p> In other words, while I have a personality-based preference for the contemplative, asynchronous pull request process, I readily admit that pair or ensemble programming may be better in many situations. </p> <p> I suspect, however, that many proponents of pair programming are as driven by their personality-based preference as I am, but that since they might be extroverts, they favour close personal interaction over contemplation. </p> <p> In any case, use what works for you, but be wary of unequivocal claims that one way is clearly better than the other. We have <a href="/2020/05/25/wheres-the-science">scant scientific knowledge about software development</a>. Most of what I write, and what industry luminaries write, is based on <a href="https://martinfowler.com/bliki/AnecdotalEvidence.html">anecdotal evidence</a>. This also applies to this discussion of pull requests versus pair programming. </p> <h3 id="3bfdb00387e64164a634722325f9710e"> Conclusion <a href="#3bfdb00387e64164a634722325f9710e" title="permalink">#</a> </h3> <p> I have anecdotal evidence that pull requests can work in an 'agile' setting. One team had implemented continuous deployment and used pull requests because more than half the team members were working from remote (this was before the COVID-19 pandemic). Pull requests were small and reviews could typically be done in five-ten minutes. Knowing this, reviews were prompt and frequent. Turnaround-time was good. </p> <p> I also have anecdotal evidence that ensemble programming works well. To me, it solves a completely different problem, but I've used it to great effect for knowledge transfer. </p> <p> Programmers more extrovert than me report anecdotal evidence that pair programming is best, and I accept that this is true - for them. I do not, however, accept it as a universal truth. Neither do I claim that my personal preference for pull request is incontrovertibly best. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="b91ee20d71f840b9901d1150ba7e9fc0"> <div class="comment-author">Timothée</div> <div class="comment-content"> <p> Hi. Thanks for this insight. And thank you for the emphasize about 'anecdotal' vs 'scientific proof'. </p> <p> About this topic, do you have any information regarding <a href="http://www.knosof.co.uk/ESEUR/">Evidence-based Software Engineering (free ebook)</a> ? If so, is it worth reading ? (Yep, I have total confidence about your knowledge and your judgment) </p> </div> <div class="comment-date">2021-06-21 20:36 UTC</div> </div> <div class="comment" id="89eeaad6eded422b859e901e1157a589"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Timothée, thank you for writing. I haven't read or heard about <em>Evidence-based Software Engineering</em>. After having read both <a href="http://bit.ly/leprechauns-of-software-engineering">The Leprechauns of Software Engineering</a> (<a href="https://www.goodreads.com/review/show/1956107880">wonderful book</a>) and <a href="https://amzn.to/2OBNBoY">Making Software: What Really Works, and Why We Believe It</a> (<a href="https://www.goodreads.com/review/show/3718825945">not so much</a>), I don't feel like reading another one. </p> </div> <div class="comment-date">2021-06-23 5:23 UTC</div> </div> <div class="comment" id="51b23b2d7a974445a5c80fee82407a93"> <div class="comment-author">Gonzalo Waszczuk</div> <div class="comment-content"> <p> You mention the adage "If it hurts, do it more often", and I 100% agree. But couldn't it also apply to those personality traits you mention? If you like doing things in your own time, to your own schedule, having the freedom to self-organize, then it means that doing the opposite "hurts", as an introvert. Couldn't that mean that it would be a good idea to actually try it out, and "do it more often"? I am an introvert too, and the urge to do things on my own and in peace is strong. But over the past years I've realized that perhaps the #1 most important aspect in our work is communication. I try to go against my introvert nature and talk to others, and be involved in face-to-face instances as much as I can. </p> <p> In regards to code reviews, I found that a face-to-face code review works well, and is a sensible middle point between pair programming and pull-request-based code review. You get the benefits of pair programming where you can transfer knowledge to someone else; have a face to face discussion on design decisions; it's easy to have a back and forth of ideas; it's easier to develop a shared coding standard; etc. On the other hand it's easier to apply this to every feature/development since it takes "less time" from developers than pair programming (which could be harder to apply or convince management to do, since it theoretically halves developer throughput). You can also forego the back and forths that would be done via comments in a pull request, having them occur in the moment, instead of over a span of a few days/hours. The author can answer questions and doubts from the reviewer much more quickly; the author can provide context and a "story" of the feature so the reviewer has it easier to review it. I found that is provides a lot of benefits. However, I must admit I have had more experience with this face-to-face style of code review than the pull-request style of code review. What do you think? </p> </div> <div class="comment-date">2021-06-23 14:43 UTC</div> </div> <div class="comment" id="d13706d1689c405fbf9c0dc579a22237"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Gonzalo, thank you for writing. You're right, it goes both ways. For what it's worth, I've done quite a bit of ensemble programming the last few years, and I find it quite effective for knowledge transfer. </p> <p> In general, there's definitely a case to be made for face-to-face communication. Earlier in my career, once or twice I've fallen into the trap of maintaining a written discussion for weeks. Then, when someone finally called a meeting, we could amiably resolve the issues within an hour. </p> <p> What concerns me about face-to-face code reviews, however, is the following: When you, as a reviewer, encounter something that you don't understand, you can immediately ask about it. What happens when you receive an answer? Do you then accept the answer and move on? </p> <p> If so, haven't you collectively failed to address an underlying problem with the code? If there's something you don't understand, and you have to ask the original programmer, what happens if that colleague is no longer around? Or what happens when that team member has also forgotten the answer? </p> <p> The code is the only artefact that contains the truth about how the software is defined. The code <em>is</em> the specification. If the code is difficult to understand, aren't you relying on collective tacit knowledge? </p> <p> That's my concern, but it may be misplaced. I haven't worked in a team that does code reviews as you describe, so I have no experience with it. </p> </div> <div class="comment-date">2021-06-26 4:18 UTC</div> </div> <div class="comment" id="d2ce7f6191214e97a8f1ed70063f4d28"> <div class="comment-author">Gonzalo Waszczuk</div> <div class="comment-content"> <p>Hi Mark. If, in the code review, I find something I don't understand, the author responds, and I agree with his response, how is it any different than making a comment in the pull request, the author responding, and me taking that comment/change request back?</p> <p>If he responds and I still find it confusing, or I still believe it should be changed, then I would ask him to change it, and the feature should not be merged until he makes those changes. I don't see what could be different from the pull-request based approach here</p> </div> <div class="comment-date">2021-07-01 14:41 UTC</div> </div> <div class="comment" id="7c5640fbc0a8418799e4b7a6266a01b2"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Gonzalo, thank you for writing. I suppose you can make it work with an oral review as well, but doesn't it require more discipline to stick to protocol? </p> <p> As a reviewer, whether or not <em>I</em>, personally, understand the proposed code is a local concern. The broader responsibility is to ensure that the code, itself, is understandable. <a href="https://en.wikipedia.org/wiki/Immanuel_Kant">Kant's</a> <a href="https://en.wikipedia.org/wiki/Categorical_imperative">categorical imperative</a> comes to mind: <blockquote> <p> "Act only according to that maxim whereby you can, at the same time, will that it should become a universal law." </p> <footer><cite><a href="https://www.goodreads.com/review/show/1892459700">Immanuel Kant</a></cite></footer> </blockquote> A code review should be conducted in such a manner that the implied protocol can be raised to a universal rule to the benefit of all team members. As a team member, I'd like the code review process to benefit <em>me</em>, even when I'm taking no part in it. </p> <p> Assume that I'm not the person doing the review. Instead, assume that another team member performs the review. If she runs into something she doesn't understand, it doesn't help <em>me</em> that she receives an answer that satisfies her. If I have to maintain the code, I'm not aware of the exchange that took place during the review. </p> <p> If there's an issue with the proposed code, it's a symptom. You can relieve the symptom by answering an immediate query, or you can address the underlying problem. I prefer the latter. </p> <p> When doing a written pull request review, most online services (GitHub, Azure DevOps) keep track of issues and require you to actively mark ongoing discussions as resolved. When I perform a review, I usually don't consider an <em>answer</em> as a resolution to the issue. An answer doesn't change the code, which means that the issue remains for the next reader to struggle with. </p> <p> Instead, I will request that the contributor amends the proposed code to address the problem. This may include refactoring, renaming a method, or just adding a comment to the code. In its most basic form, if I had a question, other team members may have the same question. If the contributor can satisfactorily answer the question, then the least he or she can do is to add the answer as a comment to the code base so that it's readily available to all readers of it. </p> <p> This turns <a href="https://en.wikipedia.org/wiki/Tacit_knowledge">tacit knowledge</a> into explicit knowledge. </p> <p> In my new book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> I propose a <em>hierarchy of communication:</em> <ol> <li>Guide the reader by giving APIs distinct types.</li> <li>Guide the reader by giving methods helpful names.</li> <li>Guide the reader by writing good comments.</li> <li>Guide the reader by providing illustrative examples as automated tests.</li> <li>Guide the reader by writing helpful commit messages in Git.</li> <li>Guide the reader by writing good documentation</li> </ol> I admit that I, like everyone else, am biased by my experience. The above suggested heuristic arose in a context. Most development organisations I've worked with has a major problem with tacit knowledge. I'm biased toward combating that problem by encouraging team members to capture knowledge in writing, and put it where it's discoverable. </p> <p> If you don't have a problem with tacit knowledge, I suppose that most of the above doesn't apply. </p> <p> What concerns me about an oral code review is that knowledge remains tacit. I suppose that with a sufficient rigorous review protocol, you could still address that problem. You could keep a log of the questions you ask, so that even if the reviewer receives a satisfactory answer, the log still states that the question was asked. The log indicates that there are unresolved issues with the proposed code. After the review, the contributor would have to take the log and address the questions by updating the pull request. </p> <p> I suppose I'm not convinced that most people have the discipline to follow such a protocol, which is why I favour the nudging provided by review tools like those offered by GitHub and Azure DevOps. </p> <p> Perhaps I'm painting myself into a corner here. Perhaps your concerns are completely different. Are you addressing a different problem? </p> </div> <div class="comment-date">2021-07-02 6:35 UTC</div> </div> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/06/21/agile-pull-requests New book: Code That Fits in Your Head https://blog.ploeh.dk/2021/06/14/new-book-code-that-fits-in-your-head/ Mon, 14 Jun 2021 11:00:00 UTC <div id="post"> <p> <em>The expanded universe.</em> </p> <p> It gives me great pleasure to announce that my new book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> will be out in September 2021. The subtitle is <em>Heuristics for Software Engineering</em>. </p> <p> <img src="/content/binary/ctfiyh.jpg" alt="Book cover."> </p> <p> Many regular readers have been expecting me to write a book about functional programming, and while that may also some day happen, this book is neither about object-oriented nor functional programming per se. Rather, it takes a step back and looks at various software development techniques and practices that I've found myself teaching for years. It covers both coding, troubleshooting, software design, team work, refactoring, and architecture. </p> <p> The target audience is all the hard-working <a href="/2012/12/18/RangersandZookeepers">enterprise developers</a> in our industry. I estimate that there's great overlap with the general readership of this blog. In other words, if you find this blog useful, I hope that you'll also find the book useful. </p> <p> As the title suggests, the theme is working effectively with code in a way that acknowledges the limitations of the human brain. This is a theme I've already explored in my <a href="https://cleancoders.com/episode/humane-code-real-episode-1">Humane Code</a> video, but in the book I expand the scope. </p> <h3 id="b73fe8b865384190a031e05915227d9a"> Expanded universe <a href="#b73fe8b865384190a031e05915227d9a" title="permalink">#</a> </h3> <p> I've structured the book around a realistic sample application. You'll see how to bootstrap a code base, but also how to work effectively with existing code. Along with the book, you'll get access to a complete Git repository with more than 500 commits and more than 6,000 lines of lovingly crafted code. </p> <p> While I was developing the sample code, I solved many interesting problems. The best and most universal examples I used in the book, but many didn't make the cut. The book aims broadly at programmers comfortable with a C-based programming language: Java, C#, JavaScript, C++, and so on. Some of the problems I solved along the way were specific to .NET, so I found them a poor fit for the book. I didn't want these great lessons to go to waste, so instead I've been blogging about them. </p> <p> These are the articles based on the code base from the book: <ul> <li><a href="/2020/07/20/closing-database-connections-during-test-teardown">Closing database connections during test teardown</a></li> <li><a href="/2020/08/03/using-the-nameof-c-keyword-with-aspnet-3-iurlhelper">Using the nameof C# keyword with ASP.NET 3 IUrlHelper</a></li> <li><a href="/2020/08/10/an-aspnet-core-url-builder">An ASP.NET Core URL Builder</a></li> <li><a href="/2020/08/24/adding-rest-links-as-a-cross-cutting-concern">Adding REST links as a cross-cutting concern</a></li> <li><a href="/2020/09/28/ensuresuccessstatuscode-as-an-assertion">EnsureSuccessStatusCode as an assertion</a></li> <li><a href="/2020/10/05/fortunately-i-dont-squash-my-commits">Fortunately, I don't squash my commits</a></li> <li><a href="/2020/10/19/monomorphic-functors">Monomorphic functors</a></li> <li><a href="/2020/11/02/signing-urls-with-aspnet">Signing URLs with ASP.NET</a></li> <li><a href="/2020/11/09/checking-signed-urls-with-aspnet">Checking signed URLs with ASP.NET</a></li> <li><a href="/2020/11/16/redirect-legacy-urls">Redirect legacy URLs</a></li> <li><a href="/2020/11/30/name-by-role">Name by role</a></li> <li><a href="/2020/12/07/branching-tests">Branching tests</a></li> <li><a href="/2021/01/11/waiting-to-happen">Waiting to happen</a></li> <li><a href="/2021/01/18/parametrised-test-primitive-obsession-code-smell">Parametrised test primitive obsession code smell</a></li> <li><a href="/2021/01/25/self-hosted-integration-tests-in-aspnet">Self-hosted integration tests in ASP.NET</a></li> <li><a href="/2021/02/01/aspnet-poco-controllers-an-experience-report">ASP.NET POCO Controllers: an experience report</a></li> <li><a href="/2021/02/15/when-properties-are-easier-than-examples">When properties are easier than examples</a></li> <li><a href="/2021/03/01/pendulum-swing-internal-by-default">Pendulum swing: internal by default</a></li> <li><a href="/2021/03/08/pendulum-swing-sealed-by-default">Pendulum swing: sealed by default</a></li> <li><a href="/2021/04/19/consider-including-identity-in-urls">Consider including identity in URLs</a></li> <li><a href="/2021/04/26/leaky-abstraction-by-omission">Leaky abstraction by omission</a></li> <li><a href="/2021/05/03/structural-equality-for-better-tests">Structural equality for better tests</a></li> <li><a href="/2021/05/10/simplifying-code-with-decorated-commands">Simplifying code with Decorated Commands</a></li> </ul> Some of these articles also use code examples from other sources, or code written specifically for that post, but whenever you see a code example from the <em>restaurant reservation</em> domain, it's from the book's code base. </p> <p> That the above list represents the <em>outtakes</em> from the book's example code base should give you an idea of the richness of it. </p> <p> I may add to the list in the future if I write more articles that use the book's example code base. </p> <h3 id="736024dff4af41659a6396dc8e773554"> Conclusion <a href="#736024dff4af41659a6396dc8e773554" title="permalink">#</a> </h3> <p> A decade after <a href="https://amzn.to/36xLycs">my first book</a>, I've finally written a completely new book. Over the years, I had a few false starts. This book wasn't the book I thought that I'd be writing if you'd asked me five years ago, but when it finally dawned on me that the topic ought to be <em>Code That Fits in Your Head: Heuristics for Software Engineering</em>, the book almost wrote itself. </p> <p> This one is for all the software developers out there who aspire to improve their practical skills. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="e019d48894ed466689e92b95022785a7"> <!-- Just some random GUID? --> <div class="comment-author"><a href="https://ericvruder.dk">Eric V. Ruder</a></div> <div class="comment-content"> <p> When will the book be available for pre-purchase in Europe/Denmark? Looking forward to reading it! </p> </div> <div class="comment-date">2021-06-23 12:26 UTC</div> </div> <div class="comment" id="7cfe04d6068f49a88db5e7317f0fe11d"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Eric, thank you for writing. The book has already made its way to <a href="https://www.amazon.de/Code-That-Fits-Your-Head/dp/0137464401">amazon.de</a> and <a href="https://www.amazon.fr/Code-That-Fits-Your-Head/dp/0137464401">amazon.fr</a>. On the other hand, it seems to be available neither on amazon.co.uk nor amazon.se. </p> <p> Granted, it doesn't look as though you can pre-order on those two sites yet. </p> <p> If you wish to buy the book directly in Denmark, I think that your best bet is to contact the book store of your preference and ask if and when they're going to carry it. </p> <p> When and how to offer a book for sale is ultimately the purview of book sellers, so not something I can accurately answer. That said, you can already today <a href="https://amzn.to/3pMPw8S">pre-order the book on amazon.com</a>, but it's probably going to cost you a little extra in shipping cost. </p> <p> I'd expect that when the book is finally published, many of the above sites will also sell it. For what it's worth, the manuscript has been done for months. The book is currently 'in production', being proofed and set. As I understand it, this is a fairly predictable process, so I don't expect significant delays relative to the late September 2021 timeline. </p> </div> <div class="comment-date">2021-06-25 5:40 UTC</div> </div> <div class="comment" id="eddd9051446447b8ae4831a703c1ccbd"> <div class="comment-author"><a href="https://github.com/srogovtsev">Serg Rogovtsev</a></div> <div class="comment-content"> <p> Will it be available as an eBook? Unexpectedly, Google shows no results. </p> </div> <div class="comment-date">2021-06-28 14:13 UTC</div> </div> <div class="comment" id="6ef395bd0b3b48299861798582d2e492"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Serg, thank you for writing. Yes, the book will be available as both PDF and for Kindle. </p> </div> <div class="comment-date">2021-06-29 8:58 UTC</div> </div> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/06/14/new-book-code-that-fits-in-your-head Abstruse nomenclature https://blog.ploeh.dk/2021/06/07/abstruse-nomenclature/ Mon, 07 Jun 2021 05:36:00 UTC <div id="post"> <p> <em>Some thoughts on programming terminology.</em> </p> <p> Functional programming has a reputation for <a href="https://en.wikipedia.org/wiki/Fumblerules">abstruse nomenclature</a>: <blockquote> <p> "Functional programmer: (noun) One who names variables "x", names functions "f", and names code patterns "zygohistomorphic prepromorphism"" </p> <footer><cite><a href="https://twitter.com/jamesiry/status/598547781515485184">James Iry</a></cite></footer> </blockquote> I've already discussed <a href="/2015/08/17/when-x-y-and-z-are-great-variable-names">when x, y, and z are great variable names</a>, and I don't intend to say more about that sort of naming here. (And to be clear, <a href="https://twitter.com/kmett/status/1144981306654318594">zygohistomorphic prepromorphisms are a joke</a>.) </p> <p> What I <em>would</em> like to talk about is the contrast to the impenetrable jargon of functional programming: the crystal-clear vocabulary of object-oriented design. Particularly, I'd like to talk about <em>polymorphism</em>. </p> <h3 id="5bf4938cae564d3984e2a77b8f6a017e"> Etymology <a href="#5bf4938cae564d3984e2a77b8f6a017e" title="permalink">#</a> </h3> <p> As <a href="https://en.wikipedia.org/wiki/Polymorphism_(computer_science)">Wikipedia puts it</a> (retrieved 2021-06-04), <em>polymorphism is the provision of a single interface to entities of different types</em>. This doesn't quite fit with the actual meaning of the word, though. </p> <p> The word <em>polymorphism</em> is derived from Greek. <em>Poly</em> means <em>many</em>, and <em>morphism</em> stems from <em>μορφή</em> (<em>morphḗ</em>), which means <em>shape</em>. Putting all of this together, <em>polymorphism</em> means <em>many-shape</em>. </p> <p> How does that fit with the idea of having a single interface? Not very well, I think. </p> <h3 id="21df55548c334577bcde7bf988a73ae6"> A matter of perspective? <a href="#21df55548c334577bcde7bf988a73ae6" title="permalink">#</a> </h3> <p> I suppose that if you view the idea of object-oriented polymorphism from the implementer's perspective, talking about many shapes makes marginal sense. Consider, for example, two classes from <a href="/2021/05/24/tennis-kata-using-the-state-pattern">a recent article</a>. Imagine, for example, that we replace every character in the <code>Advantage</code> code with an <code>x</code>: </p> <p> <pre>xxxxxx xxxxxx xxxxxxxxx x xxxxxx x xxxxxx xxxxxxxxxxxxxxxx xxxxxxx x xxxxxx x xxxxxxx x xxxxxx xxxxxx xxxxxx x xxxx xxxx x xxxxxx xxxx xxxxxxxxxxxxx xxxxxxx xxxx xxxxx x xx xxxxxxx xx xxxxxxx xxxxxxxxxx x xxx xxxxxxxxxxxxxxxxxxxxxx xxxx xxxxxxxxxx x xxxxxxxxxxxxxxx x x</pre> </p> <p> This trick of replacing all characters with <code>x</code> to see the shape of code is one I picked up from <a href="https://en.wikipedia.org/wiki/Kevlin_Henney">Kevlin Henney</a>. Try to do the same with the <code>Deuce</code> struct from the same article: </p> <p> <pre>xxxxxx xxxxxx xxxxx x xxxxxx x xxxxxx xxxxxxxx xxxxxx xxxxxx xxxxxxxx x xxx xxxxxxxx xxxxxx xxxx xxxxxxxxxxxxx xxxxxxx xxxx xxxxx x xxxxxxxxxx x xxx xxxxxxxxxxxxxxxxxx x x</pre> </p> <p> Clearly, these two classes have different shapes. </p> <p> You could argue that all classes have different shapes, but what unites <code>Advantage</code> with <code>Deuce</code> (and three other classes) is that they implement a common interface called <code>IScore</code>. In a sense you can view an <code>IScore</code> object as an object that can have multiple shapes; i.e. a <em>polymorphism</em>. </p> <p> While there's some soundness to this view, as terminology goes, the most important part is only implicitly understood. Yes, all objects have different shapes (<em>poly-morphic</em>), but in order to be a polymorphism, they must <em>present as one</em>. </p> <p> In practice, most of us understand what the other means if one of us says <em>polymorphism</em>, but this is only because we've learned what the word means in the context of object-oriented programming. It's not because the word itself is particularly communicative, even if you pick up the Greek roots. </p> <h3 id="fe0c4a7d14284b10b243c7fa6751aa3d"> Common interface <a href="#fe0c4a7d14284b10b243c7fa6751aa3d" title="permalink">#</a> </h3> <p> The above outline doesn't present how I usually think about polymorphism. I've deliberately tried to steelman it. </p> <p> When I think of polymorphism, I usually focus on what two or more classes may have in common. Instead of replacing every character with an <code>x</code>, try instead to reduce the <code>Advantage</code> and <code>Deuce</code> structs to their public interfaces. First, <code>Advantage</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">Advantage</span>&nbsp;:&nbsp;IScore { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Advantage</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Player&nbsp;Player&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) }</pre> </p> <p> Now do the same with <code>Deuce</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">Deuce</span>&nbsp;:&nbsp;IScore { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IScore&nbsp;Instance &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) }</pre> </p> <p> These two APIs are clearly different, yet they have something in common: the <code>BallTo</code> method. In fact, you can draw a <a href="https://en.wikipedia.org/wiki/Venn_diagram">Venn diagram</a> of the public members of all five <code>IScore</code> classes: </p> <p> <img src="/content/binary/venn-diagram-of-score-classes.png" alt="Venn diagram of the members of five classes."> </p> <p> Incidentally, three of the five classes (<code>Forty</code>, <code>Advantage</code>, and <code>CompletedGame</code>) also share a <code>Player</code> property, but all five share the <code>BallTo</code> method. Singling out that method yields the <code>IScore</code> interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IScore</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>); }</pre> </p> <p> Such a (statically-typed) common API is what I usually think of when I think of polymorphism. It's the <em>shape</em> that all five classes have in common. When viewed through the lens of the <code>IScore</code> interface, all five classes <em>have the same form!</em> </p> <p> The term <em>polymorphism</em> (<em>many shapes</em>) makes little sense in this light. Really, it ought to have been called <em>isomorphism</em> (<em>equal shape</em>), but unfortunately, <a href="https://en.wikipedia.org/wiki/Isomorphism">that word already means something else</a>. </p> <p> Sometimes, when you discover that the Greek word for a term is already taken, you can use Latin instead. Let's see, what would <em>one shape</em> be in Latin? <em>Uniform?</em> Yeah, that's also taken. </p> <p> Okay, I'm cheating by deliberately picking words that are already taken. Perhaps a better option might be <em>idiomorphism</em>, from Greek, <em>ἴδιος</em> (<em>idios</em>, “own, personal, distinct”). </p> <h3 id="1bee363b4c554063933820905bee76c0"> Opacity <a href="#1bee363b4c554063933820905bee76c0" title="permalink">#</a> </h3> <p> The point of all of this really isn't to harp on <em>polymorphism</em> in particular. This term is well understood in our industry, so there's no pragmatic reason to change it. </p> <p> Rather, I wish to point out the following: <ul> <li>Object-oriented design also includes Greek terms</li> <li>Even if you can decipher a Greek term, the name may not be helpful</li> <li>In fact, the name may be outright misleading</li> </ul> Ultimately, learning any jargon involves learning how particular words - even <em>normal</em> words - are understood in a particular context (what in <a href="http://amzn.to/WBCwx7">DDD</a> may be know as a <em>bounded context</em>). For example, the word <em>capital</em> means something completely different in architecture and finance. </p> <p> This is true also in programming. Without a context, <a href="https://en.wikipedia.org/wiki/Polymorphism">polymorphism can mean many things</a>. In biology, for example, <a href="https://en.wikipedia.org/wiki/Polymorphism_(biology)">it means the occurrence of two or more clearly different forms within a species</a>, for example light and black <a href="https://en.wikipedia.org/wiki/Jaguar">jaguars</a> (the animal, not <a href="https://en.wikipedia.org/wiki/Jaguar_Cars">the car</a> - another example that a word belongs in a context). </p> <p> This type of polymorphism in biology reminds me more of <a href="https://martinfowler.com/bliki/RoleInterface.html">role interfaces</a>, where a single class can implement several interfaces, but perhaps that's just me. </p> <p> Ultimately, industry terminology is opaque until you learn it. Some words may be easier to learn than others, but looks can be deceiving. <em>Inheritance</em> may sound straightforward, but in object-oriented design, inheritance doesn't entail the death of someone else. Additionally, in programming languages with single inheritance, descendants can only inherit once. As a metaphor, <em>inheritance</em> is mediocre at best. </p> <p> Another friendly-sounding piece of terminology is <em>encapsulation</em> - despite the fact that it's essentially Latin, just warped by two millennia of slight linguistic drift. Even so, this most fundamental concept of object-oriented design <a href="/encapsulation-and-solid">is also the most misunderstood</a>. The word itself doesn't much help communicating the concept. </p> <p> Finally, I wish to remind my English-speaking readers that not all programmers have English as their native language. For many programmers, words like <em>class</em>, <em>object</em>, or <em>encapsulation</em> may be words that they only know via programming. These could be words that have no prior, intrinsic meaning to a speaker of Hungarian or Japanese. </p> <h3 id="457f568704e347d790ed01e28c4c10eb"> Functional programming terminology <a href="#457f568704e347d790ed01e28c4c10eb" title="permalink">#</a> </h3> <p> Is functional programming terminology harder than object-oriented jargon? I don't think so. </p> <p> A nice little word like <em>monoid</em>, for example, is <a href="https://cleancoders.com/episode/humane-code-real-episode-2">Greek for <em>one-like</em></a>. Again, it's not self-explanatory, but once <a href="/2017/10/06/monoids">the concept of a monoid</a> is explained, it makes sense: it's an abstraction that enables you to treat many things as though they are a single thing (with possible loss of fidelity, though). As names go, I find this more accurate than <em>polymorphism</em>. </p> <p> Granted, there's more Greek in functional programming than in object-oriented design, but (Latin) English is still present: <em>recursion</em>, <em>fold</em>, and <em>traversal</em> are common terms. </p> <p> And then there's the occasional nonsense word, like <a href="/2018/03/22/functors">functor</a>. Despite some of digging, <a href="https://cleancoders.com/episode/humane-code-real-episode-5">I've only managed to learn that <em>functor</em> is a compaction of <em>function</em> and <em>factor</em></a> - that is, a <em>function factor</em>, but what does that tell you? </p> <p> In many ways, I prefer nonsense words like <em>functor</em>, because at least, they aren't misleading. When you learn that word, you have no preconception that you think you already know what it means. <a href="https://michaelfeathers.silvrback.com/a-book-of-form">Michael Feathers is experimenting with a similar idea, but in another context</a>, inventing words like <em>exot</em>, <em>lavin</em>, <em>endot</em>, <em>parzo</em>, <em>duon</em>, and <em>tojon</em>. </p> <h3 id="cc8da4b8866149a5ab6421afa9b395d3"> Conclusion <a href="#cc8da4b8866149a5ab6421afa9b395d3" title="permalink">#</a> </h3> <p> It's easy to dismiss the alien as incomprehensible. This often happens in programming. <a href="/2015/08/03/idiomatic-or-idiosyncratic">New ideas are dismissed as <em>non-idiomatic</em></a>. Alternative paradigms like functional programming are rejected because some words aren't immediately forthcoming. </p> <p> This, to me, says more about the person spurning new knowledge than it says about the ideas themselves. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/06/07/abstruse-nomenclature From State tennis to endomorphism https://blog.ploeh.dk/2021/05/31/from-state-tennis-to-endomorphism/ Mon, 31 May 2021 06:29:00 UTC <div id="post"> <p> <em>You can refactor the State pattern to pure functions.</em> </p> <p> In a previous article you saw how to do <a href="/2021/05/24/tennis-kata-using-the-state-pattern">the Tennis kata with the State design pattern</a>. Like most other patterns in <a href="http://amzn.to/XBYukB">Design Patterns</a>, the <a href="https://en.wikipedia.org/wiki/State_pattern">State pattern</a> relies on mutation. If you favour functional programming and immutable data, you may not like that. Fortunately, converting the API to immutable data and <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a> is plain sailing. </p> <p> In this post I'll show you how I did it. </p> <h3 id="aa55df271b85405da98ba72ce27cf573"> Return Score <a href="#aa55df271b85405da98ba72ce27cf573" title="permalink">#</a> </h3> <p> Recall from the previous article that the <code>IScore</code> interface defined a single method, <code>BallTo</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IScore</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>); }</pre> </p> <p> With its <code>void</code> return type, it clearly indicate that <code>BallTo</code> mutates the state of <em>something</em> - although it's less clear whether it's the object itself, <code>game</code>, or both. </p> <p> As a first step towards turning the method into a pure function, then, you can change the return type so that it returns an <code>IScore</code> object: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IScore</span> { &nbsp;&nbsp;&nbsp;&nbsp;IScore&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>); }</pre> </p> <p> In itself, <a href="/2020/02/24/discerning-and-maintaining-purity">this doesn't guarantee that the function is pure</a>. In fact, after this small step, none of the implementations are. Here, for example, is the updated <code>Advantage</code> implementation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;IScore&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(winner&nbsp;==&nbsp;Player) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompletedGame(winner); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;Deuce.Instance; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;game.Score; }</pre> </p> <p> This implementation still modifies <code>game.Score</code> before returning it. All the other <code>IScore</code> implementations do the same. </p> <h3 id="cd54ec4b37dd4b7c86dcefb4bb29e2f9"> Use the returned score <a href="#cd54ec4b37dd4b7c86dcefb4bb29e2f9" title="permalink">#</a> </h3> <p> Now that the <code>BallTo</code> method returns an <code>IScore</code> object, you can edit the <code>Game</code> class' <code>BallTo</code> method so that it <em>uses</em> the returned value: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Score&nbsp;=&nbsp;Score.BallTo(player,&nbsp;<span style="color:blue;">this</span>); }</pre> </p> <p> Given that all the <code>IScore</code> implementations currently mutate <code>game.Score</code>, this seems redundant, but sets you up for the next refactoring step. </p> <h3 id="dad8032221d14d31b07a64c08284a78d"> Remove State mutation <a href="#dad8032221d14d31b07a64c08284a78d" title="permalink">#</a> </h3> <p> You can now remove the mutation of <code>game.Score</code> from all the implementations of <code>IScore</code>. Here's <code>Advantage</code> after the refactoring: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;IScore&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(winner&nbsp;==&nbsp;Player) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;CompletedGame(winner); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Deuce.Instance; }</pre> </p> <p> Notice that this implementation no longer uses the <code>game</code> parameter. </p> <p> The other <code>IScore</code> implementations get a similar treatment. </p> <h3 id="03d390895456430e87eb609245596458"> Remove game parameter <a href="#03d390895456430e87eb609245596458" title="permalink">#</a> </h3> <p> Since no implementations use the <code>game</code> parameter you can remove it from the interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IScore</span> { &nbsp;&nbsp;&nbsp;&nbsp;IScore&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>); }</pre> </p> <p> and, of course, from each of the implementations: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;IScore&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(winner&nbsp;==&nbsp;Player) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;CompletedGame(winner); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Deuce.Instance; }</pre> </p> <p> The above method, again, is the implementation of <code>Advantage</code>. </p> <h3 id="145be3db73ff40339eaef927342ca1e5"> Return Game <a href="#145be3db73ff40339eaef927342ca1e5" title="permalink">#</a> </h3> <p> You can now make the same sequence of changes to the <code>Game</code> class itself. Recall from above that its <code>BallTo</code> method returns <code>void</code>. As a the first refactoring step towards turning that method into a pure function, then, change the return type: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Game&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Score&nbsp;=&nbsp;Score.BallTo(player); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">this</span>; }</pre> </p> <p> The mutation remains a little while longer, but the method looks like something that <em>could</em> be a pure function. </p> <h3 id="5bead23264dd4833b64731b1b8f8563e"> Return new Game <a href="#5bead23264dd4833b64731b1b8f8563e" title="permalink">#</a> </h3> <p> The next refactoring step is to return a <em>new</em> <code>Game</code> instance instead of the same (mutated) instance: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Game&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Score&nbsp;=&nbsp;Score.BallTo(player); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Game(Score); }</pre> </p> <p> The first line still mutates <code>Score</code>, but now you're only one step away from an immutable implementation. </p> <h3 id="162337d4c9c44a1a93bcddb4e60fc7c0"> Remove Game mutation <a href="#162337d4c9c44a1a93bcddb4e60fc7c0" title="permalink">#</a> </h3> <p> Finally, you can remove the mutation of the <code>Game</code> class. First, remove the <code>internal</code> setter from the <code>Score</code> property: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;IScore&nbsp;Score&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;}</pre> </p> <p> You can now <em>lean on the compiler</em>, as Michael Feathers explains in <a href="http://bit.ly/working-effectively-with-legacy-code">Working Effectively with Legacy Code</a>. This forces you to fix the the <code>BallTo</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Game&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Game(Score.BallTo(player)); }</pre> </p> <p> This is also the only refactoring that requires you to edit the unit tests. Here a few methods as examples: </p> <p> <pre>[Theory] [InlineData(Player.One,&nbsp;Point.Love)] [InlineData(Player.One,&nbsp;Point.Fifteen)] [InlineData(Player.One,&nbsp;Point.Thirty)] [InlineData(Player.Two,&nbsp;Point.Love)] [InlineData(Player.Two,&nbsp;Point.Fifteen)] [InlineData(Player.Two,&nbsp;Point.Thirty)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FortyWins</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Point&nbsp;<span style="color:#1f377f;">otherPlayerPoint</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Game(<span style="color:blue;">new</span>&nbsp;Forty(winner,&nbsp;otherPlayerPoint)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.BallTo(winner); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;CompletedGame(winner),&nbsp;actual.Score); } [Theory] [InlineData(Player.One)] [InlineData(Player.Two)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FortyThirty</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Game(<span style="color:blue;">new</span>&nbsp;Forty(player,&nbsp;Point.Thirty)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.BallTo(player.Other()); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Deuce.Instance,&nbsp;actual.Score); }</pre> </p> <p> These are the same test methods as shown in the previous article. The changes are: the introduction of <a href="/2020/11/30/name-by-role">the <code>actual</code> variable</a>, and that the assertion now compares the expected value to <code>actual.Score</code> rather than <code>sut.Score</code>. </p> <p> Both variations of <code>BallTo</code> are now <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphisms</a>. </p> <h3 id="81d185ebdb8c4febaf079dc667edb0c4"> Explicit endomorphism <a href="#81d185ebdb8c4febaf079dc667edb0c4" title="permalink">#</a> </h3> <p> If you're not convinced that the refactored <code>IScore</code> interface describes an endomorphism, you can make it explicit - strictly for illustrative purposes. First, introduce an explicit <code>IEndomorphism</code> interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IEndomorphism</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">Run</span>(T&nbsp;<span style="color:#1f377f;">x</span>); }</pre> </p> <p> This is the same interface as already introduced in the article <a href="/2020/02/17/builder-as-a-monoid">Builder as a monoid</a>. To be clear, I wouldn't use such an interface in normal C# code. I only use it here to illustrate how the <code>BallTo</code> method describes an endomorphism. </p> <p> You can turn a <code>Player</code> into an endomorphism with an extension method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEndomorphism&lt;IScore&gt;&nbsp;<span style="color:#74531f;">ToEndomorphism</span>(<span style="color:blue;">this</span>&nbsp;Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ScoreEndomorphism(player); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">ScoreEndomorphism</span>&nbsp;:&nbsp;IEndomorphism&lt;IScore&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ScoreEndomorphism</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Player&nbsp;=&nbsp;player; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Player&nbsp;Player&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IScore&nbsp;<span style="color:#74531f;">Run</span>(IScore&nbsp;<span style="color:#1f377f;">score</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;score.BallTo(Player); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This is equivalent to <a href="https://en.wikipedia.org/wiki/Partial_application">partial function application</a>. It applies the <code>player</code>, and by doing that returns an <code>IEndomorphism&lt;IScore&gt;</code>. </p> <p> The <code>Game</code> class' <code>BallTo</code> implementation can now <code>Run</code> the endomorphism: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Game&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEndomorphism&lt;IScore&gt;&nbsp;<span style="color:#1f377f;">endo</span>&nbsp;=&nbsp;player.ToEndomorphism(); &nbsp;&nbsp;&nbsp;&nbsp;IScore&nbsp;<span style="color:#1f377f;">newScore</span>&nbsp;=&nbsp;endo.Run(Score); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Game(newScore); }</pre> </p> <p> Again, I'm not recommending this style of C# programming. I'm only showing this to illustrate how the object playing the State role now describes an endomorphism. </p> <p> You could subject the <code>Game</code> class' <code>BallTo</code> method to the same treatment, but if you did, you'd have to call the extension method something that would distinguish it from the above <code>ToEndomorphism</code> extension method, since C# doesn't allow overloading exclusively on return type. </p> <h3 id="66f6b83887e9435792187f761596b95c"> Conclusion <a href="#66f6b83887e9435792187f761596b95c" title="permalink">#</a> </h3> <p> Like many of the other patterns in <a href="http://amzn.to/XBYukB">Design Patterns</a>, the State pattern relies on mutation. It's straightforward, however, to refactor it to a set of pure functions. For what it's worth, these are all endomorphisms. </p> <p> This article used a take on the <a href="https://codingdojo.org/kata/Tennis">tennis kata</a> as an example. </p> </div><hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/05/31/from-state-tennis-to-endomorphism Tennis kata using the State pattern https://blog.ploeh.dk/2021/05/24/tennis-kata-using-the-state-pattern/ Mon, 24 May 2021 07:03:00 UTC <div id="post"> <p> <em>An example of using the State design pattern.</em> </p> <p> Regular readers of this blog will know that I keep coming back to the <a href="https://codingdojo.org/kata/Tennis">tennis kata</a>. It's an interesting little problem to attack from various angles. </p> <p> I don't think you have to <a href="/2020/01/13/on-doing-katas">do the kata</a> that many times before you realise that you're <a href="/2021/03/29/table-driven-tennis-scoring">describing a simple state machine</a>. A few years ago I decided to use that insight to get reacquainted with the <a href="https://en.wikipedia.org/wiki/State_pattern">State design pattern</a>. </p> <p> In this article I'll show you what the code looks like. </p> <h3 id="132c5bdbc1984e0ea87a6ac2f9279600"> Context <a href="#132c5bdbc1984e0ea87a6ac2f9279600" title="permalink">#</a> </h3> <p> As part of the exercise, I decided to stay close to the pattern description in <a href="http://amzn.to/XBYukB">Design Patterns</a>. The public API should be exposed as a single class that hides all the internal state machinery. In the general pattern description, this class is called <code>Context</code>. The TCP example given in the book, however, calls the example class <code>TCPConnection</code>. This indicates that you don't have to use the word <em>context</em> when naming the class. I chose to simply call it <code>Game</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Game</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Game</span>()&nbsp;:&nbsp;<span style="color:blue;">this</span>(<span style="color:blue;">new</span>&nbsp;Points(Point.Love,&nbsp;Point.Love)) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Game</span>(IScore&nbsp;<span style="color:#1f377f;">score</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Score&nbsp;=&nbsp;score; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IScore&nbsp;Score&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Score.BallTo(player,&nbsp;<span style="color:blue;">this</span>); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Since the <code>Game</code> class delegates all behaviour to its <code>Score</code> property, it's basically redundant. This may be a degenerate example, but as an exercise of staying true to the pattern, I decided to keep it. It's the class that all tests work through. </p> <h3 id="1d796d3f77b84a6dbcc1cf312d0fafd7"> Test <a href="#1d796d3f77b84a6dbcc1cf312d0fafd7" title="permalink">#</a> </h3> <p> All tests look similar. This parametrised test verifies what happens after <em>deuce:</em> </p> <p> <pre>[Theory] [InlineData(Player.One)] [InlineData(Player.Two)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ScoreDeuce</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Game(Deuce.Instance); &nbsp;&nbsp;&nbsp;&nbsp;sut.BallTo(winner); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;Advantage(winner),&nbsp;sut.Score); }</pre> </p> <p> This is code that I wrote years ago, so it uses <a href="https://xunit.net">xUnit.net</a> 2.3.1 and runs on .NET Framework 4.6.1, but I don't think it'd have looked different today. It follows my <a href="/2013/06/24/a-heuristic-for-formatting-code-according-to-the-aaa-pattern">heuristic for formatting unit tests</a>. </p> <h3 id="c58be115b320472cb4348058d8a111dd"> Structural equality <a href="#c58be115b320472cb4348058d8a111dd" title="permalink">#</a> </h3> <p> The <a href="/2021/05/03/structural-equality-for-better-tests">equality assertion works because <code>Advantage</code> has structural equality</a>. In this exercise, I found it simpler to declare types as <a href="https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/value-types">value types</a> instead of overriding <code>Equals</code> and <code>GetHashCode</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">Advantage</span>&nbsp;:&nbsp;IScore { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Advantage</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Player&nbsp;=&nbsp;player; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Player&nbsp;Player&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(winner&nbsp;==&nbsp;Player) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompletedGame(winner); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;Deuce.Instance; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This turned out to be possible throughout, since all types emerged as mere compositions of other value types. The above <code>Advantage</code> struct, for example, <a href="https://en.wikipedia.org/wiki/Adapter_pattern">adapts</a> a <code>Player</code>, which, unsurprisingly, is an <code>enum</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">enum</span>&nbsp;<span style="color:#2b91af;">Player</span> { &nbsp;&nbsp;&nbsp;&nbsp;One&nbsp;=&nbsp;0, &nbsp;&nbsp;&nbsp;&nbsp;Two }</pre> </p> <p> One of the states holds no data at all, so I made it a <a href="https://en.wikipedia.org/wiki/Singleton_pattern">Singleton</a>, as suggested in <a href="http://amzn.to/XBYukB">the book</a>. (Contrary to popular belief, <a href="https://stackoverflow.com/a/67331100/126014">I don't consider Singleton an anti-pattern</a>.) </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">Deuce</span>&nbsp;:&nbsp;IScore { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IScore&nbsp;Instance&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Deuce(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Advantage(winner); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Since it's a Singleton, from an equality perspective it doesn't matter whether it's a value or reference type, but I made it a <code>struct</code> <a href="/2021/05/17/against-consistency">for consistency's sake</a>. </p> <h3 id="f94a31a78e4741139adb53cde96eb927"> State <a href="#f94a31a78e4741139adb53cde96eb927" title="permalink">#</a> </h3> <p> In the State design pattern's formal structure, the <code>Context</code> delegates all behaviour to an abstract <code>State</code> class. Since I consider inheritance harmful (as well as <a href="/2018/02/19/abstract-class-isomorphism">redundant</a>), I instead chose to model the state as an interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IScore</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>); }</pre> </p> <p> As the pattern suggests, the State object exposes methods that take the Context as an extra parameter. This enables concrete State implementation to change the state of the Context, as both the above structs (<code>Advantage</code> and <code>Deuce</code>) demonstrate. They both implement the interface. </p> <p> When I do the kata, I always seem to arrive at five distinct states. I'm not sure if this reflects the underlying properties of the problem, or if it's just because that's what worked for me years ago, and I'm now stuck in some cognitive local maximum. In any case, that's what happened here as well. Apart from the above <code>Advantage</code> and <code>Deuce</code> there's also a <code>Forty</code> implementation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">Forty</span>&nbsp;:&nbsp;IScore { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Forty</span>(Player&nbsp;<span style="color:#1f377f;">player</span>,&nbsp;Point&nbsp;<span style="color:#1f377f;">otherPlayerPoint</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Player&nbsp;=&nbsp;player; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OtherPlayerPoint&nbsp;=&nbsp;otherPlayerPoint; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Player&nbsp;Player&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Point&nbsp;OtherPlayerPoint&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Player&nbsp;==&nbsp;winner) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;CompletedGame(winner); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(OtherPlayerPoint&nbsp;==&nbsp;Point.Thirty) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;Deuce.Instance; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(OtherPlayerPoint&nbsp;==&nbsp;Point.Fifteen) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Forty(Player,&nbsp;Point.Thirty); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Forty(Player,&nbsp;Point.Fifteen); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Another thing that I've also noticed when doing the Tennis kata is that the state logic for <em>advantage</em> and <em>deuce</em> is simple, whereas the state transitions involving <em>points</em> is more complicated. If you think <code>Forty</code> looks complicated, then consider <code>Points</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">Points</span>&nbsp;:&nbsp;IScore { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Points</span>(Point&nbsp;<span style="color:#1f377f;">playerOnePoint</span>,&nbsp;Point&nbsp;<span style="color:#1f377f;">playerTwoPoint</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PlayerOnePoint&nbsp;=&nbsp;playerOnePoint; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PlayerTwoPoint&nbsp;=&nbsp;playerTwoPoint; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Point&nbsp;PlayerOnePoint&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Point&nbsp;PlayerTwoPoint&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">pp</span>&nbsp;=&nbsp;PlayerPoint(winner); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">opp</span>&nbsp;=&nbsp;PlayerPoint(winner.Other()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(pp&nbsp;==&nbsp;Point.Thirty) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Forty(winner,&nbsp;opp); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span>&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(winner&nbsp;==&nbsp;Player.One) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Points(Increment(PlayerOnePoint),&nbsp;PlayerTwoPoint); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;game.Score&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Points(PlayerOnePoint,&nbsp;Increment(PlayerTwoPoint)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;Point&nbsp;<span style="color:#74531f;">PlayerPoint</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(player&nbsp;==&nbsp;Player.One) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;PlayerOnePoint; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;PlayerTwoPoint; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Point&nbsp;<span style="color:#74531f;">Increment</span>(Point&nbsp;<span style="color:#1f377f;">point</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(point&nbsp;==&nbsp;Point.Love) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Point.Fifteen; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Point.Thirty; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The last <code>IScore</code> implementation represents a completed game: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">CompletedGame</span>&nbsp;:&nbsp;IScore { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">CompletedGame</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Player&nbsp;=&nbsp;player; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Player&nbsp;Player&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">BallTo</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Game&nbsp;<span style="color:#1f377f;">game</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> In a completed game, the <code>BallTo</code> implementation is a no-op, because <code>Player</code> has already won the game. </p> <h3 id="9a1fbf4d7d774ebea12bbe93173a5a71"> Miscellany <a href="#9a1fbf4d7d774ebea12bbe93173a5a71" title="permalink">#</a> </h3> <p> Here's a few more tests, just to back up my claim that all tests look similar: </p> <p> <pre>[Theory] [InlineData(Player.One,&nbsp;Point.Love)] [InlineData(Player.One,&nbsp;Point.Fifteen)] [InlineData(Player.One,&nbsp;Point.Thirty)] [InlineData(Player.Two,&nbsp;Point.Love)] [InlineData(Player.Two,&nbsp;Point.Fifteen)] [InlineData(Player.Two,&nbsp;Point.Thirty)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FortyWins</span>(Player&nbsp;<span style="color:#1f377f;">winner</span>,&nbsp;Point&nbsp;<span style="color:#1f377f;">otherPlayerPoint</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Game(<span style="color:blue;">new</span>&nbsp;Forty(winner,&nbsp;otherPlayerPoint)); &nbsp;&nbsp;&nbsp;&nbsp;sut.BallTo(winner); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;CompletedGame(winner),&nbsp;sut.Score); } [Theory] [InlineData(Player.One)] [InlineData(Player.Two)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FortyThirty</span>(Player&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Game(<span style="color:blue;">new</span>&nbsp;Forty(player,&nbsp;Point.Thirty)); &nbsp;&nbsp;&nbsp;&nbsp;sut.BallTo(player.Other()); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(Deuce.Instance,&nbsp;sut.Score); }</pre> </p> <p> The second of these test methods uses an extension method called <code>Other</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">PlayerEnvy</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Player&nbsp;<span style="color:#74531f;">Other</span>(<span style="color:blue;">this</span>&nbsp;Player&nbsp;<span style="color:#1f377f;">player</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(player&nbsp;==&nbsp;Player.One) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Player.Two; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">else</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Player.One; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> As is my custom, I named the class containing the extension method with the <code>Envy</code> suffix, because I often consider this kind of extension method a sign of Feature Envy. Alas, in C# you can't add methods to an <code>enum</code>. </p> <h3 id="a196bacd7b7041629b15ff6bd5ada849"> Conclusion <a href="#a196bacd7b7041629b15ff6bd5ada849" title="permalink">#</a> </h3> <p> Implementing the tennis kata with the classic State pattern is straightforward. </p> <p> After having spent the majority of the last decade with functional programming, I've come to realise that many problems are really just state machines waiting to be revealed as such. Implementing a finite state machine in a language with <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data types</a> is so easy that you often reach for that kind of modelling. </p> <p> Before I learned functional programming, when all I knew was procedural and object-oriented code, I rarely thought of problems in terms of finite state machines. Now I see them everywhere. It's an example of how learning a completely different thing can feed back on everyday programming. </p> <p> Once you recognise that a problem can be modelled as a finite state machine, you have new options. If you're in a conservative context where colleagues aren't keen on fancy FP shenanigans, you can always reach for the State design pattern. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="ee5552352ccc46c3a73451f899462d26"> <div class="comment-author"><a href="https://github.com/JimCooperFromGmailAccount">Jim Cooper</a></div> <div class="comment-content"> <p> Do you think that perhaps you are at risk of making too many problems look like nails for your state machine hammer? :-) Actually, you just want to convert a pair of points into a tennis score. That doesn't require a state machine, I don't think: </p> <p><pre> using NUnit.Framework; namespace TennisKata { public class Tests { private TennisGame tennisGame; [SetUp] public void Setup() { tennisGame = new TennisGame(); } [TestCase(0, 0, ExpectedResult = "Love All")] [TestCase(1, 1, ExpectedResult = "Fifteen All")] [TestCase(2, 2, ExpectedResult = "Thirty All")] [TestCase(3, 3, ExpectedResult = "Deuce")] [TestCase(4, 4, ExpectedResult = "Deuce")] [TestCase(1, 0, ExpectedResult = "Fifteen - Love")] [TestCase(2, 1, ExpectedResult = "Thirty - Fifteen")] [TestCase(3, 2, ExpectedResult = "Forty - Thirty")] [TestCase(4, 0, ExpectedResult = "Game Server")] [TestCase(0, 1, ExpectedResult = "Love - Fifteen")] [TestCase(1, 2, ExpectedResult = "Fifteen - Thirty")] [TestCase(2, 3, ExpectedResult = "Thirty - Forty")] [TestCase(0, 4, ExpectedResult = "Game Receiver")] [TestCase(4, 3, ExpectedResult = "Advantage Server")] [TestCase(3, 4, ExpectedResult = "Advantage Receiver")] [TestCase(5, 4, ExpectedResult = "Advantage Server")] [TestCase(4, 5, ExpectedResult = "Advantage Receiver")] [TestCase(5, 3, ExpectedResult = "Game Server")] [TestCase(3, 5, ExpectedResult = "Game Receiver")] [TestCase(5, 2, ExpectedResult = "Invalid score")] [TestCase(2, 5, ExpectedResult = "Invalid score")] public string ShouldConvertPointsToTennisStyleScore(int serverPoints, int receiverPoints) { SetServerPointsTo(serverPoints); SetReceiverPointsTo(receiverPoints); return tennisGame.Score; } private void SetServerPointsTo(int serverPoints) { for (var i = 0; i < serverPoints; i++) { tennisGame.PointToServer(); } } private void SetReceiverPointsTo(int serverPoints) { for (var i = 0; i < serverPoints; i++) { tennisGame.PointToReceiver(); } } } public class TennisGame { private int serverPoints; private int receiverPoints; public string Score => serverPoints switch { _ when serverPoints == receiverPoints && serverPoints >= 3 => "Deuce", _ when serverPoints == receiverPoints => $"{PointsAsWord(serverPoints)} All", _ when serverPoints >= 4 && serverPoints > receiverPoints => GetGameOrAdvantage(serverPoints, receiverPoints, "Server"), _ when receiverPoints >= 4 => GetGameOrAdvantage(receiverPoints, serverPoints, "Receiver"), _ => $"{PointsAsWord(serverPoints)} - {PointsAsWord(receiverPoints)}" }; public void PointToServer() { serverPoints++; } public void PointToReceiver() { receiverPoints++; } private static string GetGameOrAdvantage(int highScore, int lowScore, string highScorerName) { var scoreDifference = highScore - lowScore; return scoreDifference switch { 1 => $"Advantage {highScorerName}", _ when highScore > 4 && scoreDifference > 2 => "Invalid score", _ => $"Game {highScorerName}" }; } private string PointsAsWord(int points) { var pointNames = new [] { "Love", "Fifteen", "Thirty", "Forty"}; return pointNames[points]; } } }</pre> </p> </div> <div class="comment-date">2021-05-27 7:56 UTC</div> </div> <div class="comment" id="37f19a75fa454aae91a67b4b2a573ada"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Jim, thank you for writing. You're right: a state machine isn't <em>required</em>. It's a nice judo trick to keep track of the server and receiver points as two different numbers. That does simplify the code. </p> <p> I tried something similar many years ago (after all, the <a href="https://codingdojo.org/kata/Tennis/">kata description itself strongly hints at that alternative perspective</a>), but for various reasons ended with an implementation that wasn't as nice as yours. I never published it. I've done this exercise many times, and I've only published the ones that I find can be used to highlight some interesting point. </p> <p> The <a href="/2020/01/13/on-doing-katas">point of doing a coding kata is to experiment with variation</a>. The goal isn't always to reach the fewest lines of code, or complete the exercise as fast as possible. These can be interesting exercises in their own rights, but by doing a kata with other constraints can be illuminating as well. </p> <p> My goal with this variation was mainly to get reacquainted with the State pattern. Actually 'solving' the problem is a requirement, but not the goal. </p> <p> Modelling the problem with the State pattern has advantages and disadvantages. A major advantage is that it offers an API that enables client code to programmatically distinguish between the various states. When I did the exercise similar to your code, asserting against a string is easy. However, basing an API on a returned string may not be an adequate design. It's okay for an exercise, but imagine that you were asked to translate the scores. For example, in Danish, <em>advantage</em> is instead called <em>fordel</em>. Another requirement might be that you report players by name. So, for example, a Danish score might instead require something like <em>fordel Serena Williams</em>. </p> <p> Don't take this as a criticism of your code. Sometimes, you don't need more than what you've done, and in such cases, doing more would be over-engineering. </p> <p> On the other hand, if you find yourself in situations where e.g. translation is required, it can be helpful to be aware that other ways to model a problem are available. That's the underlying benefit of doing katas. The more variations you do, the better prepared you become to 'choose the right tool for the job.' </p> <p> All that said, though, with the tennis kata, you can <a href="/2021/03/29/table-driven-tennis-scoring">make it trivially simple modelling it as a finite state automaton</a>. </p> </div> <div class="comment-date">2021-05-30 9:09 UTC</div> </div> </div> <hr> This blog is totally free, but if you like it, please consider <a href="https://blog.ploeh.dk/support">supporting it</a>. Mark Seemann https://blog.ploeh.dk/2021/05/24/tennis-kata-using-the-state-pattern