ploeh blog 2021-10-18T07:37:59+00:00 Mark Seemann danish software design https://blog.ploeh.dk Readability verification https://blog.ploeh.dk/2021/10/18/readability-verification 2021-10-18T07:37:00+00:00 Mark Seemann <div id="post"> <p> <em>How do you know whether the code you wrote is readable?</em> </p> <p> In a recent Twitter thread about pair and mob programming, <a href="https://dannorth.net">Dan North</a> observes: </p> <blockquote> <p> "That’s the tricky problem I was referring to. If you think you can write code that other humans can understand, without collaborating or calibrating with other humans, assuming that an after-the-fact check will always be affirmative, then you are a better programmer than me." </p> <footer><cite><a href="https://twitter.com/tastapod/status/1448184718122487811">Dan North</a></cite></footer> </blockquote> <p> I neither think that I'm a better programmer than Dan nor that, without collaboration, I can write code that other humans can understand. That's why I'd like someone else to <em>review</em> my code. Not write it together with me, but <em>read it</em> after I've written it. </p> <h3 id="b9a6a0093d0c4c2193c4e39d519ef582"> Advantages of pair and ensemble programming <a href="#b9a6a0093d0c4c2193c4e39d519ef582" title="permalink">#</a> </h3> <p> Pair programming and ensemble (AKA <em>mob</em>) programming is an efficient way to develop software. It works for lots of people. I'm not insisting otherwise. </p> <p> By working together, you can pool skills. Imagine working on a feature for a typical web application. This involves user interface, business logic, data access, and possibly other things as well. Few people are experts in all those areas. Personally, I'm comfortable around business logic and data access, but know little about web front-end development. It's great to have someone else's expertise to draw on. </p> <p> By working together in real time, you avoid hand-offs. If I had to help implementing a feature in an asynchronous manner, I'd typically implement domain logic and data access in a REST API, then tell a front-end expert that the API is ready. This way of working <a href="/2020/03/16/conways-law-latency-versus-throughput">introduces wait times into the process</a>, and may also cause rework if it turns out that the way I designed the API doesn't meet the requirements of the front end. </p> <p> Real-time collaboration addresses some of these concerns. It also improves code ownership. In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, I quote <a href="https://twitter.com/birgitta410">Birgitta Böckeler</a> and <a href="https://sssggr.net">Nina Siessegger</a>: </p> <blockquote> <p> "Consistent pairing makes sure that every line of code was touched or seen by at least 2 people. This increases the chances that anyone on the team feels comfortable changing the code almost anywhere. It also makes the codebase more consistent than it would be with single coders only. </p> <p> "Pair programming alone does not guarantee you achieve collective code ownership. You need to make sure that you also rotate people through different pairs and areas of the code, to prevent knowledge silos." </p> <footer><cite>Birgitta Böckeler and Nina Siessegger, <a href="https://martinfowler.com/articles/on-pair-programming.html">On Pair Programming</a></cite></footer> </blockquote> <p> With mob programming, you take many of these advantages to the next level. If you include a domain expert in the group, you can learn about what the organisation actually needs as you're developing a feature. If you include specialised testers, they may see edge cases or error modes you didn't think of. If you include UX experts, you'll have a chance to develop software that users can actually figure out how to use. </p> <p> There are lots of benefits to be had from pair and ensemble programming. In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> I recommend that you try it. I've recommended it to my customers. I've had good experiences with it myself: </p> <blockquote> <p> "I’ve used [mob programming] with great success as a programming coach. In one engagement, I spent two to three days a week with a few other programmers, helping them apply test-driven development practices to their production code bases. After a few months of that, I went on vacation. Meanwhile those programmers kept going with test-driven development. Mob programming is great for knowledge transfer." </p> <footer><cite><a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a></cite></footer> </blockquote> <p> <a href="/2021/10/11/serendipity-driven-development">I don't, however, think that it's a one-size-fits-all solution</a>. </p> <h3 id="c57bfb2342d2437596ff90a13fb29c44"> The curse of knowledge <a href="#c57bfb2342d2437596ff90a13fb29c44" title="permalink">#</a> </h3> <p> While outlining the advantages of pair and ensemble programming, I didn't mention readability. I don't see how those ways of working address the problem of writing readable code. </p> <p> I've reviewed code written by pairs, and it was neither more nor less readable than code written by a single programmer. I think that there's an easy-to-understand reason for this. It relates to the <em>curse of knowledge:</em> </p> <blockquote> <p> "In 1990, Elizabeth Newton earned a Ph.D. in psychology at Stanford by studying a simple game in which she assigned people to one of two roles: “tappers” or “listeners.” Tappers received a list of twenty-five well-known songs, such as “Happy Birthday to You” and “The Star-Spangled Banner.” Each tapper was asked to pick a song and tap out the rhythm to a listener (by knocking on a table). The listener’s job was to guess the song, based on the rhythm being tapped. (By the way, this experiment is fun to try at home if there’s a good “listener” candidate nearby.) </p> <p> "The listener’s job in this game is quite difficult. Over the course of Newton’s experiment, 120 songs were tapped out. Listeners guessed only 2.5 percent of the songs: 3 out of 120. </p> <p> "But here’s what made the result worthy of a dissertation in psychology. Before the listeners guessed the name of the song, Newton asked the tappers to predict the odds that the listeners would guess correctly. They predicted that the odds were 50 percent. </p> <p> "The tappers got their message across 1 time in 40, but they thought they were getting their message across 1 time in 2. Why? </p> <p> "When a tapper taps, she is <em>hearing the song in her head</em>. Go ahead and try it for yourself—tap out “The Star-Spangled Banner.” It’s impossible to avoid hearing the tune in your head. Meanwhile, the listeners can’t hear that tune—all they can hear is a bunch of disconnected taps, like a kind of bizarre Morse Code. </p> <p> "In the experiment, tappers are flabbergasted at how hard the listeners seem to be working to pick up the tune. <em>Isn’t the song obvious?</em> The tappers’ expressions, when a listener guesses “Happy Birthday to You” for “The Star-Spangled Banner,” are priceless: <em>How could you be so stupid?</em> </p> <p> "It’s hard to be a tapper. The problem is that tappers have been given knowledge (the song title) that makes it impossible for them to imagine what it’s like to <em>lack</em> that knowledge. When they’re tapping, they can’t imagine what it’s like for the listeners to hear isolated taps rather than a song. This is the Curse of Knowledge. Once we know something, we find it hard to imagine what it was like not to know it. Our knowledge has “cursed” us. And it becomes difficult for us to share our knowledge with others, because we can’t readily re-create our listeners’ state of mind. </p> <p> "The tapper/listener experiment is reenacted every day across the world. The tappers and listeners are CEOs and frontline employees, teachers and students, politicians and voters, marketers and customers, writers and readers. All of these groups rely on ongoing communication, but, like the tappers and listeners, they suffer from enormous information imbalances. When a CEO discusses “unlocking shareholder value,” there is a tune playing in her head that the employees can’t hear." </p> <footer><cite>Chip Heath and Dan Heath, <a href="https://amzn.to/3viu26j">Made to Stick</a></cite></footer> </blockquote> <p> When you're writing code, you're a <em>tapper</em>. As you're writing the code, you know <em>why</em> you are writing it the way you do, you know what you've already tried that didn't work, the informal requirements that someone told you about over the water cooler, etc. </p> <p> Why should pair or ensemble programming change that? </p> <blockquote> <p> "One of the roles of a PR is to verify that someone who didn't write the new code can understand it. </p> <p> "The constant communication of pair programming can result in code only that pair understands. Does a book with two authors not need an editor?" </p> <footer><cite><a href="https://twitter.com/laurence/status/1448485971289260039">Laurence Gonsalves</a></cite></footer> </blockquote> <p> So, how do you verify that code is readable? </p> <h3 id="77efc0b4e41a4f5597ff6e072187698f"> Readability <a href="#77efc0b4e41a4f5597ff6e072187698f" title="permalink">#</a> </h3> <p> I often forget to remind the reader that discussions like this one, about software productivity, mostly rely on <a href="https://martinfowler.com/bliki/AnecdotalEvidence.html">anecdotal evidence</a>. There's <a href="/2020/05/25/wheres-the-science">little scientific evidence about these topics</a>. The ensuing discussions <a href="/2020/10/12/subjectivity">tend to rely on subjectivity</a>, and so, ultimately, does this one. </p> <p> In <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, I suggest heuristics for writing readable code, but ultimately, the only reliable test of readability that I can think of is simple: </p> <p> Ask someone else to <em>read</em> the code. </p> <p> That's what a code review ought to do. Anyone who took part in writing the code is a <em>tapper</em>. After I've written code, I'm a <em>tapper</em>. I'm in no position to evaluate whether the code I just wrote is readable. </p> <p> You need a <em>listener</em> (or, here: a <em>reader</em>) to evaluate whether or not sufficient information came across. </p> <p> I agree with Dan North that I need other humans to collaborate and calibrate. I just disagree that people who write code are in a position to evaluate whether the code is readable (and thereby can sustain the business in the long run). </p> <h3 id="8655f1951b6a414f82d38435aa317e5c"> Rejection <a href="#8655f1951b6a414f82d38435aa317e5c" title="permalink">#</a> </h3> <p> What happens, then, if I submit a pull request that the reviewer finds unreadable? </p> <p> The reviewer should either suggest improvements or decline the pull request. </p> <p> I can tell from Dan's tweet that he's harbouring a common misconception about the pull request review process: </p> <blockquote> <p> "assuming that an after-the-fact check will always be affirmative" </p> <footer><cite><a href="https://twitter.com/tastapod/status/1448184718122487811">Dan North</a></cite></footer> </blockquote> <p> No, I don't assume that my pull requests always pass muster. That's also the reason that <a href="/2015/01/15/10-tips-for-better-pull-requests">pull requests should be small</a>. They should be small enough that you can afford to have them rejected. </p> <p> I'm currently helping one of my clients with some code. I add some code and send an <a href="/2021/06/21/agile-pull-requests">agile pull request</a>. </p> <p> Several times in the last month, my pull requests have remained unmerged. In none of the cases, actually, have the reviewer outright rejected the pull request. He just started asking questions, then we had a short debate over GitHub, and then I came to the conclusion that I should close the pull request myself. </p> <p> No drama, just feedback. </p> <h3 id="ad0609e523b8401fbab92dc0e90c44d5"> Conclusion <a href="#ad0609e523b8401fbab92dc0e90c44d5" title="permalink">#</a> </h3> <p> How do you verify that code is readable? </p> <p> I can't think of anything better than asking someone else to read the code. </p> <p> Obviously, we shouldn't ask random strangers about readability. We should ask team members to review code. One implication of collective code ownership is that when a team member accepts a pull request, he or she is also taking on the shared responsibility of maintaining that code. As I write in <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, a fundamental criterion for evaluating a pull request is: <em>Will I be okay maintaining this?</em> </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>. Serendipity-driven development https://blog.ploeh.dk/2021/10/11/serendipity-driven-development 2021-10-11T05:54:00+00:00 Mark Seemann <div id="post"> <p> <em>How much does providence drive thought leadership?</em> </p> <p> I regularly listen to podcasts. Many podcast episodes are structured around an interview with a guest. A common interview technique (and icebreaker, I suppose) is to ask the guest how he or she became a voice in the field that's the topic for the episode. Surprisingly often, the answer is that it's basically a happy coincidence. He or she was young, had no specific plans, but tried a few things until eventually becoming enamoured with a particular topic. </p> <p> That's not just technology podcasts. I also listen to interviews with scientists and artists on a variety of topics. </p> <p> A <em>few</em> people are driven from an early age to study something specific. Most, it seems, are not. I'm no exception. I had a false start as an economist, but was so extremely fortunate that the 1990's were such a boom decade of IT that you could get a job in the field if you could spell HTML. </p> <p> It seems to me that it's a common (Western) experience for a young person to start adult life without much of a plan, but an unrealised responsiveness to certain stimuli. As a young person, you may have a general notion of your own inclinations, so you seek out certain activities and avoid others. Still, you may not really know yourself. </p> <p> I didn't know myself at 18. After <a href="https://en.wikipedia.org/wiki/Gymnasium_(school)">gymnasium</a> (~ high school) in 1989 my best friend started at computer science at the University of Copenhagen. I had no experience with computers and thought it sounded incredibly dry. I wanted to be a rock star or a comic book artist in the French-Belgian style. </p> <p> In order to get an education, though, I started at economics at the University of Copenhagen. Talk about a dry subject. </p> <p> Well, at least I learned game theory, n-dimensional topology, optimal control theory, chaos theory, and some other branches of mathematics, so perhaps the years weren't entirely wasted... </p> <p> Computers weren't on my radar, but I soon realised that it'd be practical to buy a PC in order to write my thesis. </p> <p> So, I bought one and soon found the computer much more interesting than economics. </p> <p> You may not realise that you'll love something until you try it. </p> <h3 id="1909691de650477189ee7d41a49cf22e"> Thought leadership <a href="#1909691de650477189ee7d41a49cf22e" title="permalink">#</a> </h3> <p> I recently wrote <a href="/2021/08/09/am-i-stuck-in-a-local-maximum">an article about the cognitive dissonance I felt</a> when interacting with many of my heroes. The <a href="https://twitter.com/ploeh/status/1424624134030602241">ensuing Twitter discussion</a> was enlightening. </p> <p> Many of my heroes balk at being called heroes or thought leaders, but I agree with <a href="https://hillelwayne.com/">Hillel Wayne</a>: </p> <blockquote> <p> "That's why, incidentally, "thought leaders" have so much weight in our industry. We like to make fun of them, but fact of the matter is that the Thought Leaders are the ones actually trying to communicate their techniques. </p> <p> "(That's why I want to unironically be a Thought Leader)" </p> <footer><cite><a href="https://twitter.com/hillelogram/status/1445435617047990273">Hillel Wayne</a></cite></footer> </blockquote> <p> I've been called a <em>though leader</em> a few times already, and like Hillel Wayne, I gratefully accept the label. </p> <p> There's <a href="/2020/05/25/wheres-the-science">little scientific evidence about what works in software development</a>, and most innovation happens behind closed doors. Thought leaders are those that observe and share the innovation with the rest of the world. </p> <p> I follow though leaders on Twitter, listen to podcasts on which they are guests, and <a href="https://www.goodreads.com/author/show/4383188.Mark_Seemann">read books</a>. </p> <p> I learned a lot from the discussion related to <a href="/2021/08/09/am-i-stuck-in-a-local-maximum">my article about feeling stuck</a>. I feel that I better understand why opposing views exist. Much has to do with context and nuance, two important factors easily lost on Twitter. </p> <p> I also think that personal experience plays a big role. Thought leaders share <a href="https://martinfowler.com/bliki/AnecdotalEvidence.html">anecdotal evidence</a>. As is also the case in science and business, we tend to share our successes. </p> <p> What feels like a success is what resonates with us. </p> <p> It's like the serendipity when you're young and finally encounter something that feels compatible with you. Should we call it serendipity-driven development? </p> <p> A couple of examples may be in order. </p> <h3 id="d4fb5cf60f584d7e8de3e0fcbcb902a7"> Pair programming <a href="#d4fb5cf60f584d7e8de3e0fcbcb902a7" title="permalink">#</a> </h3> <p> While I now have an increased awareness of what motivates other thought leaders, I still often disagree. It wouldn't be unnatural if our personal experiences with particular practices influence our positions. </p> <p> <img src="/content/binary/pair-programming.jpg" alt="Pair programming."> </p> <p> One such example is pair programming. In an interview (sorry, can't remember which) Robert C. Martin told how he found test-driven development dumb until either Kent Beck or Ward Cunningham paired with him to show him the light. Recently, <a href="http://www.exampler.com/">Brian Marick</a> shared a similar experience: </p> <blockquote> <p> "When I first heard of XP, I thought pair programming was the *second* stupidest idea I'd ever heard. The stupidest was everyone working in the same team room (*not* an "open office"). But..." </p> <footer><a href="https://twitter.com/marick/status/1446618423312715779">Brian Marick</a></footer> </blockquote> <p> This seems to be a common experience with pair programming. Most people dislike it until they have actually tried it. </p> <p> Well, I've tried both pair programming and ensemble (AKA mob) programming, and I don't <em>like</em> it. </p> <p> That's all: It's my <em>preference</em> - not any sort of objective truth. What little scientific evidence we can find in our field does seem to indicate that pair programming is efficient. In my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> I've put aside my dislike to instead endorse pair and ensemble programming as something you should consider. </p> <p> There's enough evidence (anecdotal and otherwise) that it works well for many people, so give it a try. </p> <p> I also use it myself. While I find it exhausting, I find ensemble programming incredibly well-suited to knowledge transfer. I've used it to great success when teaching development organisations new ways of doing things. </p> <p> Even with the nicest people in the room, however, the process drains me. One reason is probably that I've a strong introvert side to my personality. </p> <p> Another perspective to consider is the role you assume. </p> <p> A common theme when people share stories of how they saw the light of pair programming is that they learned it from luminaries. If Kent Beck or Ward Cunningham personally tutors you, it's easy to see how it could feel like a revelation. </p> <p> On the other hand, <a href="https://en.wikipedia.org/wiki/Survivorship_bias">survivorship bias</a> could be at work. Perhaps Kent Beck showed pair programming and test-driven development to many people who never caught the bug, and thus never discussed it in public. </p> <p> In my own experience, I mostly taught myself test-driven development long before I tried pair programming, and I'd heard about pair programming long before I tried it. When I did try it, I wasn't the person being taught. I was in the role of the teacher. </p> <p> Teaching is both a satisfying and exhausting activity. I do consider myself a teacher of sorts, but I prefer to write. Whenever I've taught a workshop, given a lecture, or consulted, I'm always left happy but exhausted. It's really hard work. </p> <p> So is pair programming, in my experience. Efficient, most likely, but hard work. I can't muster much enthusiasm about it. </p> <h3 id="4b17192456614ca28a4e69cb5f86e23b"> REST <a href="#4b17192456614ca28a4e69cb5f86e23b" title="permalink">#</a> </h3> <p> Another topic about which I regularly disagree with others is <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a>. Just try to find some of my articles <a href="/tags/#REST-ref">tagged REST</a> and read the comments. </p> <p> For the record, the crowd who disagrees with me is a completely different set of people than those with whom I disagree about pair programming and other agile practices. </p> <p> The people who disagree with me about REST may be right, and I could be wrong. My views on REST are strongly influenced by early experience. Do be aware of the pattern. </p> <p> In early 2012 a client asked for my help designing a stable API. The customer didn't ask me to design a REST API - in fact, I think he had a <a href="https://en.wikipedia.org/wiki/SOAP">SOAP</a> API in mind, but he was open to other options. One requirement was clear, though: The API had to be exceptionally stable and backwards compatible. There was a reason for this. </p> <p> My customer's business was to provide a consumer-grade online service. They were currently talking to a hardware producer who'd include support for the service in consumer hardware. Imagine thousands (perhaps millions) of devices sitting in people's homes, using the online service via the API we were about to design. </p> <p> Even if the hardware producer were to enable firmware upgrades of the devices, there'd be no way we could roll out new versions of client software in a controlled way. This meant that backwards compatibility was a top priority. </p> <p> I'd recently learned enough about REST to see the opportunity, so I suggested it as a principle for designing APIs that could evolve without breaking backwards compatibility. </p> <p> The resulting REST API was a success, and I worked with that client for many years on other projects. </p> <p> This experience clearly shaped my view on REST. To me, the major benefit of REST is the ability to design evolvable APIs without breaking changes. It does work best, however, if you design <a href="https://martinfowler.com/articles/richardsonMaturityModel.html">level 3 REST APIs</a>. </p> <p> People use HTTP APIs for all sorts of other reasons. Perhaps the driving factor isn't evolvability, but rather interoperability. Perhaps they're developing <a href="https://samnewman.io/patterns/architectural/bff/">backends for frontends</a> or APIs strictly for internal use in an organisation. In some scenarios you can easier schedule updates of clients to coincide with updates to the API, in which case backwards compatibility is less of a concern. </p> <p> Another concern about API design is <a href="https://thoughtbot.com/blog/who-is-empowered-by-your-design">who's empowered by your design</a>. It seems fair to say that a level 2 REST API is an easier sell. To many client developers, that's all they've ever encountered - they've never seen a level 3 REST API. </p> <p> I readily admit that a level 3 REST API puts an additional up-front burden on client developers. Such a design is a long game. If the API is active for many years, such investments are likely to pay off, while it may not be worthwhile in the short term. It could even hurt initial adoption, so it's not a one-size-fits-all architectural choice. </p> <p> In the context of thought leadership, however, my point is that I acknowledge that my view on REST, too, is flavoured by initial personal success. </p> <h3 id="f6e7da07a61340ef9f1617cb5fb19071"> Conclusion <a href="#f6e7da07a61340ef9f1617cb5fb19071" title="permalink">#</a> </h3> <p> I think it's natural to latch on to certain practices via serendipity, You go through life without being aware of a thing that turns out to be highly compatible with your preferences in a given context. Until you one day <em>do</em> encounter it, and it changes your life. </p> <p> I consider this only human. It's certainly happened to me multiple times, and I'd be surprised if it doesn't happen to others. </p> <p> Perhaps the people extolling the virtues of pair programming had great initial experiences that they've managed to carry forward. For me, the experience has been another. </p> <p> Likewise, I had an initial positive experience with REST that surely influenced my position on its virtues. Other people could have had a negative experience, and naturally protest against my ideas. There's nothing wrong with that. </p> <blockquote> <p> "Only a crisis - actual or perceived - produces real change. When that crisis occurs, the actions that are taken depend on the ideas that are lying around. That, I believe, is our basic function: to develop alternatives to existing policies, to keep them alive and available until the politically impossible becomes the politically inevitable" </p> <footer><a href="https://amzn.to/3BsIqLG">Milton Friedman</a></footer> </blockquote> <p> Thought leadership strikes me as similar to Friedman's ideas on policy alternatives. I don't see my role as an <em>enforcer</em> of ideas. I write in order to keep certain ideas alive, in the hope that one day, someone picks them up and uses them. </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>. Reader as a contravariant functor https://blog.ploeh.dk/2021/10/04/reader-as-a-contravariant-functor 2021-10-04T05:47:00+00:00 Mark Seemann <div id="post"> <p> <em>Any function gives rise to a contravariant functor. An article for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. In the <a href="/2021/09/06/the-command-handler-contravariant-functor">first example article</a>, you saw how the Command Handler pattern gives rise to a contravariant functor. <a href="/2021/09/09/the-specification-contravariant-functor">The next article</a> gave another example based on predicates. </p> <p> In the <a href="/2021/09/02/contravariant-functors">overview article</a> I also mentioned that equivalence and comparison form contravariant functors. Each can be described with an interface, or just function syntax. Let's put them in a table to compare them: </p> <p> <table border="1"> <thead> <tr> <th><em>Name</em></th> <th><em>C# method signature</em></th> <th><em>C# delegate(s)</em></th> <th><em>Haskell type(s)</em></th> </tr> </thead> <tbody> <tr> <td>Command Handler</td> <td><code><span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(TCommand&nbsp;<span style="color:#1f377f;">command</span>);</code></td> <td><code>Action&lt;TCommand&gt;</code></td> <td><code>a -&gt; ()</code><br/><code>a -&gt; IO ()</code></td> </tr> <tr> <td>Specification</td> <td><code><span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T&nbsp;<span style="color:#1f377f;">candidate</span>);</code></td> <td><code>Predicate&lt;T&gt;</code><br/><code>Func&lt;T, bool&gt;</code></td> <td><code>a -&gt; Bool</code></td> </tr> <tr> <td>Equivalence</td> <td><code><span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(T&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">y</span>);</code></td> <td><code>Func&lt;T, T, bool&gt;</code></td> <td><code>a -&gt; a -&gt; Bool</code></td> </tr> <tr> <td>Comparison</td> <td><code><span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">Compare</span>(T&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">y</span>);</code></td> <td><code>Func&lt;T, T, int&gt;</code></td> <td><code>a -&gt; a -&gt; Ordering</code></td> </tr> </tbody> </table> </p> <p> In some cases, there's more than one possible representation. For example, in C# <a href="https://docs.microsoft.com/dotnet/api/system.predicate-1">Predicate</a> is isomorphic to <code>Func&lt;T, bool&gt;</code>. When it comes to the <a href="https://www.haskell.org">Haskell</a> representation of a Command Handler, the 'direct' translation of <code>Action&lt;T&gt;</code> is <code>a -&gt; ()</code>. In (Safe) Haskell, however, a function with that type is always a no-op. More realistically, a 'handler' function would have the type <code>a -&gt; IO ()</code> in order to allow side effects to happen. </p> <p> Do you notice a pattern? </p> <h3 id="920ac139cb1449789dac402d3e05c368"> Input variance <a href="#920ac139cb1449789dac402d3e05c368" title="permalink">#</a> </h3> <p> There's a pattern emerging from the above table. Notice that in all the examples, the function types are generic (AKA <em>parametrically polymorphic</em>) in their <em>input</em> types. </p> <p> This turns out to be part of a general rule. The actual rule is a little more complicated than that. I'll recommend <a href="https://reasonablypolymorphic.com">Sandy Maguire</a>'s <a href="https://www.goodreads.com/review/show/3406773267">excellent</a> book <a href="https://thinkingwithtypes.com">Thinking with Types</a> if you're interested in the details. </p> <p> For first-order functions, you can pick and fix <em>any</em> type as the return type and let the input type(s) vary: that function will give rise to a contravariant functor. </p> <p> In the above table, various handlers fix <code>void</code> (which is <a href="/2018/01/15/unit-isomorphisms">isomorphic to <em>unit</em></a> (<code>()</code>) as the output type and let the input type vary. Both Specification and Equivalence fix <code>bool</code> as the output type, and Comparison fix <code>int</code> (or, in Haskell, the more sane type <code>Ordering</code>), and allow the input type to vary. </p> <p> You can pick any other type. If you fix it as <em>the</em> output type for a function and let the input vary, you have the basis for a contravariant functor. </p> <h3 id="11651dbe49d04a6989c45fc52744ebf8"> Reader <a href="#11651dbe49d04a6989c45fc52744ebf8" title="permalink">#</a> </h3> <p> Consider this <code>IReader</code> interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReader</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;<span style="color:#74531f;">Run</span>(R&nbsp;<span style="color:#1f377f;">environment</span>); }</pre> </p> <p> If you fix the environment type <code>R</code> and let the output type <code>A</code> vary, <a href="/2021/08/30/the-reader-functor">you have a (covariant) functor</a>. If, on the other hand, you fix the <em>output</em> type <code>A</code> and allow the input type <code>R</code> to vary, you can have yourself a contravariant functor: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IReader&lt;R1,&nbsp;A&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IReader&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">reader</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;R1,&nbsp;R&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;FuncReader&lt;R1,&nbsp;A&gt;(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;reader.Run(selector(r))); }</pre> </p> <p> As an example, you may have this (rather unwarranted) interface implementation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">MinutesReader</span>&nbsp;:&nbsp;IReader&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;TimeSpan&nbsp;<span style="color:#74531f;">Run</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">environment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;TimeSpan.FromMinutes(environment); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> You can fix the output type to <code>TimeSpan</code> and let the input type vary using the <code>ContraMap</code> functions: </p> <p> <pre>[Fact] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">WrappedContravariantExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;MinutesReader(); &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">projected</span>&nbsp;=&nbsp;r.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;<span style="color:blue;">int</span>.Parse(s)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(<span style="color:blue;">new</span>&nbsp;TimeSpan(0,&nbsp;21,&nbsp;0),&nbsp;projected.Run(<span style="color:#a31515;">&quot;21&quot;</span>)); }</pre> </p> <p> When you <code>Run</code> the <code>projected</code> reader with the input string <code>"21"</code>, the <code>ContraMap</code> function first calls the <code>selector</code>, which (in this case) parses <code>"21"</code> to the integer <code>21</code>. It then calls <code>Run</code> on the 'original' <code>reader</code> with the value <code>21</code>. Since the 'original' <code>reader</code> is a <code>MinutesReader</code>, the output is a <code>TimeSpan</code> value that represents 21 minutes. </p> <h3 id="d147d424c6de412d9ad83cf659812ef6"> Raw functions <a href="#d147d424c6de412d9ad83cf659812ef6" title="permalink">#</a> </h3> <p> As was also the case when I introduced the Reader (covariant) functor, the <code>IReader</code> interface is just a teaching device. You don't need the interface in order to turn first-order functions into contravariant functors. It works on raw functions too: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;R1,&nbsp;A&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">R1</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">func</span>,&nbsp;Func&lt;R1,&nbsp;R&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;func(selector(r)); }</pre> </p> <p> In the following I'm going to dispense with the <code>IReader</code> interface and instead work with raw functions. </p> <h3 id="ad09f6dd9b3542b4ba8c01a01baa6afa"> Identity law <a href="#ad09f6dd9b3542b4ba8c01a01baa6afa" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for functions. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the identity law: </p> <p> <pre>[Theory] [InlineData(42)] [InlineData(1337)] [InlineData(2112)] [InlineData(90125)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ContravariantIdentityLaw</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;i.ToString(); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;f.ContraMap((<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">i</span>)&nbsp;=&gt;&nbsp;i); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(f(input),&nbsp;actual(input)); }</pre> </p> <p> Here I'm using the <code>(int i) =&gt; i</code> lambda expression as the identity function. As usual, you can't easily compare functions for equality, so you'll have to call them to verify that they produce the same output, which they do. </p> <h3 id="2e1d05c3d61c4773820dbbaec5967565"> Composition law <a href="#2e1d05c3d61c4773820dbbaec5967565" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(4.2)] [InlineData(13.37)] [InlineData(21.12)] [InlineData(901.25)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ContravariantCompositionLaw</span>(<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">input</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;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">double</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;TimeSpan.FromSeconds(i); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TimeSpan,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;ts.ToString(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.ContraMap((<span style="color:blue;">double</span>&nbsp;<span style="color:#1f377f;">d</span>)&nbsp;=&gt;&nbsp;g(f(d)))(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.ContraMap(g).ContraMap(f)(input)); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to invoke both compositions to verify that they return the same <code>int</code> value. </p> <p> They do. </p> <h3 id="392a90e5e3204d459dae673d23be92e1"> Isomorphisms <a href="#392a90e5e3204d459dae673d23be92e1" title="permalink">#</a> </h3> <p> Now that we understand that any first-order function is contravariant, we can see that the previous examples of predicates, handlers, comparisons, and equivalences are really just special cases of the Reader contravariant functor. </p> <p> For example, <code>Predicate&lt;T&gt;</code> is trivially isomorphic to <code>Func&lt;T, bool&gt;</code>. Still, it might be worthwhile to flesh out how other translations might work: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#74531f;">AsSpecification</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Predicate&lt;T&gt;&nbsp;<span style="color:#1f377f;">predicate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;DelegateSpecificationAdapter&lt;T&gt;(predicate); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#74531f;">AsSpecification</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;T,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">predicate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;DelegateSpecificationAdapter&lt;T&gt;(predicate); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">DelegateSpecificationAdapter</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;ISpecification&lt;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Predicate&lt;T&gt;&nbsp;predicate; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DelegateSpecificationAdapter</span>(Predicate&lt;T&gt;&nbsp;<span style="color:#1f377f;">predicate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.predicate&nbsp;=&nbsp;predicate; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DelegateSpecificationAdapter</span>(Func&lt;T,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">predicate</span>)&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>((Predicate&lt;T&gt;)(<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;predicate(x))) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T&nbsp;<span style="color:#1f377f;">candidate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;predicate(candidate); &nbsp;&nbsp;&nbsp;&nbsp;} } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Predicate&lt;T&gt;&nbsp;<span style="color:#74531f;">AsPredicate</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">specification</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">candidate</span>&nbsp;=&gt;&nbsp;specification.IsSatisfiedBy(candidate); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;T, bool&gt;&nbsp;<span style="color:#74531f;">AsFunc</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">specification</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">candidate</span>&nbsp;=&gt;&nbsp;specification.IsSatisfiedBy(candidate); }</pre> </p> <p> Above are conversions between <code>ISpecification&lt;T&gt;</code> on the one hand, and <code>Predicate&lt;T&gt;</code> and <code>Func&lt;T, bool&gt;</code> on the other. Not shown are the conversions between <code>Predicate&lt;T&gt;</code> and <code>Func&lt;T, bool&gt;</code>, since they are already built into C#. </p> <p> Most saliently in this context is that it's possible to convert both <code>ISpecification&lt;T&gt;</code> and <code>Predicate&lt;T&gt;</code> to <code>Func&lt;T, bool&gt;</code>, and <code>Func&lt;T, bool&gt;</code> to <code>ISpecification&lt;T&gt;</code> or <code>Predicate&lt;T&gt;</code> without any loss of information. Specifications and predicates are isomorphic to an open constructed <code>Func</code> - that is, a Reader. </p> <p> I'll leave the other isomorphisms as exercises, with the following hints: </p> <ul> <li>You can only convert an <code>ICommandHandler&lt;T&gt;</code> to a <code>Func</code> if you introduce a <code>Unit</code> value, but you could also try to use <code>Action&lt;T&gt;</code>.</li> <li>For Equivalence, you'll need to translate the two input arguments to a single object or value.</li> <li>The same goes for Comparison.</li> </ul> <p> All the contravariant functor examples shown so far in this article series are isomorphic to the Reader contravariant functor. </p> <p> Particularly, this also explains why <a href="/2021/09/27/the-equivalence-contravariant-functor">it was possible to make <code>IEqualityComparer.GetHashCode</code> contravariant</a>. </p> <h3 id="fa845ae308634182bf6e82298205c9a8"> Haskell <a href="#fa845ae308634182bf6e82298205c9a8" title="permalink">#</a> </h3> <p> The Haskell <em>base</em> package comes with a <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">Contravariant type class</a> and various instances. </p> <p> In order to replicate the above <code>MinutesReader</code> example, we can start by implementing a function with equivalent behaviour: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; minutes m = secondsToDiffTime (60 * m) Prelude Data.Functor.Contravariant Data.Time&gt; :t minutes minutes :: Integer -&gt; DiffTime</pre> </p> <p> As GHCi reports, the <code>minutes</code> function has the type <code>Integer -&gt; DiffTime</code> (<code>DiffTime</code> corresponds to .NET's <code>TimeSpan</code>). </p> <p> The above C# example contramaps a <code>MinutesReader</code> with a function that parses a <code>string</code> to an <code>int</code>. In Haskell, we can use the built-in <code>read</code> function to equivalent effect. </p> <p> Here's where Haskell gets a little odd. In order to fit the <code>Contravariant</code> type class, we need to flip the type arguments of a function. A normal function is usually written as having the type <code>a -&gt; b</code>, but we can also write it as the type <code>(-&gt;) a b</code>. With this notation, <code>minutes</code> has the type <code>(-&gt;) Integer DiffTime</code>. </p> <p> In order to make <code>minutes</code> a contravariant instance, we need to fix <code>DiffTime</code> and let the input vary. What we'd like to have is something like this: <code>(-&gt;) a DiffTime</code>. Alas, that's not how you define a legal type class instance in Haskell. We have to flip the types around so that we can partially apply the type. The built-in <code>newtype Op</code> does that: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; :t Op minutes Op minutes :: Op DiffTime Integer</pre> </p> <p> Since the general, partially applied type <code>Op a</code> is a <code>Contravariant</code> instance, it follows that the specific type <code>Op DiffTime</code> is. This means that we can <code>contramap</code> <code>Op minutes</code> with <code>read</code>: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; :t contramap read (Op minutes) contramap read (Op minutes) :: Op DiffTime String</pre> </p> <p> Notice that this maps an <code>Op DiffTime Integer</code> to an <code>Op DiffTime String</code>. </p> <p> How do you use it? </p> <p> You can retrieve the function wrapped in <code>Op</code> with the <code>getOp</code> function: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; :t getOp (contramap read (Op minutes)) getOp (contramap read (Op minutes)) :: String -&gt; DiffTime</pre> </p> <p> As you can tell, this expression indicates a <code>String -&gt; DiffTime</code> function. This means that if you call it with a string representation of an integer, you should get a <code>DiffTime</code> value back: </p> <p> <pre>Prelude Data.Functor.Contravariant Data.Time&gt; getOp (contramap read (Op minutes)) "21" 1260s</pre> </p> <p> As usual, this is way too complicated to be immediately useful, but it once again demonstrates that contravariant functors are ubiquitous. </p> <h3 id="c5952616e8b24528900fcdc9b2b75535"> Conclusion <a href="#c5952616e8b24528900fcdc9b2b75535" title="permalink">#</a> </h3> <p> Normal first-order functions give rise to contravariant functors. With sufficiently tinted glasses, <a href="/2018/01/08/software-design-isomorphisms">most programming constructs look like functions</a>. To me, at least, this indicates that a contravariant functor is a fundamental abstraction in programming. </p> <p> This result looks quite abstract, but future articles will build on it to arrive at a (to me) fascinating conclusion. Until then, though... </p> <p> <strong>Next:</strong> Functor variance compared to C#'s notion of variance. </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>. The Equivalence contravariant functor https://blog.ploeh.dk/2021/09/27/the-equivalence-contravariant-functor 2021-09-27T06:08:00+00:00 Mark Seemann <div id="post"> <p> <em>An introduction to the Equivalence contravariant functor for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. In previous articles, you saw examples of <a href="/2021/09/06/the-command-handler-contravariant-functor">the Command Handler</a> and <a href="/2021/09/09/the-specification-contravariant-functor">Specification</a> contravariant functors. This article presents another example. </p> <p> In <a href="/2021/09/20/keep-ids-internal-with-rest">a recent article</a> I described how I experimented with removing the <code>id</code> property from a JSON representation in a REST API. I also mentioned that doing that made one test fail. In this article you'll see the failing test and how the Equivalence contravariant functor can improve the situation. </p> <h3 id="be01e1b437a94b2689f5fdd3a68ae33f"> Baseline <a href="#be01e1b437a94b2689f5fdd3a68ae33f" title="permalink">#</a> </h3> <p> Before I made the change, the test in question looked like this: </p> <p> <pre>[Theory] [InlineData(1049,&nbsp;19,&nbsp;00,&nbsp;<span style="color:#a31515;">&quot;juliad@example.net&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Julia&nbsp;Domna&quot;</span>,&nbsp;5)] [InlineData(1130,&nbsp;18,&nbsp;15,&nbsp;<span style="color:#a31515;">&quot;x@example.com&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Xenia&nbsp;Ng&quot;</span>,&nbsp;9)] [InlineData(&nbsp;956,&nbsp;16,&nbsp;55,&nbsp;<span style="color:#a31515;">&quot;kite@example.edu&quot;</span>,&nbsp;<span style="color:blue;">null</span>,&nbsp;2)] [InlineData(&nbsp;433,&nbsp;17,&nbsp;30,&nbsp;<span style="color:#a31515;">&quot;shli@example.org&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Shanghai&nbsp;Li&quot;</span>,&nbsp;5)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">PostValidReservationWhenDatabaseIsEmpty</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">days</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">hours</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">minutes</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">email</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">name</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">at</span>&nbsp;=&nbsp;DateTime.Now.Date&nbsp;+&nbsp;<span style="color:blue;">new</span>&nbsp;TimeSpan(days,&nbsp;hours,&nbsp;minutes,&nbsp;0); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">db</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;FakeDatabase(); &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;ReservationsController( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;SystemClock(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;InMemoryRestaurantDatabase(Grandfather.Restaurant), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dto</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDto &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;<span style="color:#a31515;">&quot;B50DF5B1-F484-4D99-88F9-1915087AF568&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;=&nbsp;at.ToString(<span style="color:#a31515;">&quot;O&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;email, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;=&nbsp;name, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;quantity &nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;sut.Post(dto); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guid.Parse(dto.Id), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Email(email), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Name(name&nbsp;??&nbsp;<span style="color:#a31515;">&quot;&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;quantity); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Contains(expected,&nbsp;db.Grandfather); }</pre> </p> <p> You can find this test in the code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>, although I've slightly simplified the initialisation of <code>expected</code> since I froze the code for the manuscript. I've already discussed this particular test in the articles <a href="/2020/12/07/branching-tests">Branching tests</a>, <a href="/2021/01/11/waiting-to-happen">Waiting to happen</a>, and <a href="/2021/01/18/parametrised-test-primitive-obsession-code-smell">Parametrised test primitive obsession code smell</a>. It's the gift that keeps giving. </p> <p> It's a <a href="/2019/04/01/an-example-of-state-based-testing-in-c">state-based integration test</a> that verifies the state of the <code>FakeDatabase</code> after 'posting' a reservation to 'the REST API'. I'm using quotes because the test doesn't really perform an HTTP POST request (it's not <a href="/2021/01/25/self-hosted-integration-tests-in-aspnet">a self-hosted integration test</a>). Rather, it directly calls the <code>Post</code> method on the <code>sut</code>. In the assertion phase, it uses Back Door Manipulation (as <a href="http://bit.ly/xunitpatterns">xUnit Test Patterns</a> terms it) to verify the state of the <a href="http://xunitpatterns.com/Fake%20Object.html">Fake</a> <code>db</code>. </p> <p> If you're wondering about the <code>Grandfather</code> property, <a href="/2020/11/16/redirect-legacy-urls">it represents the original restaurant that was grandfathered in</a> when I expanded the REST API to a multi-tenant service. </p> <p> Notice, particularly, the use of <code>dto.Id</code> when defining the <code>expected</code> reservation. </p> <h3 id="be8ae690e33a4e7fb3b5d5f15d6ddce9"> Brittle assertion <a href="#be8ae690e33a4e7fb3b5d5f15d6ddce9" title="permalink">#</a> </h3> <p> When I <a href="/2021/09/20/keep-ids-internal-with-rest">made the <code>Id</code> property <code>internal</code></a>, this test no longer compiled. I had to delete the assignment of <code>Id</code>, which also meant that I couldn't use a deterministic <code>Guid</code> to define the <code>expected</code> value. While I could create an arbitrary <code>Guid</code>, that would never pass the test, since the <code>Post</code> method also generates a new <code>Guid</code>. </p> <p> In order to <a href="/2019/10/21/a-red-green-refactor-checklist">get to green</a> as quickly as possible, I rewrote the assertion: </p> <p> <pre>Assert.Contains( &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;&nbsp;&nbsp;DateTime.Parse(dto.At,&nbsp;CultureInfo.InvariantCulture)&nbsp;==&nbsp;r.At &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span style="color:blue;">new</span>&nbsp;Email(dto.Email)&nbsp;==&nbsp;r.Email &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;<span style="color:blue;">new</span>&nbsp;Name(dto.Name&nbsp;??&nbsp;<span style="color:#a31515;">&quot;&quot;</span>)&nbsp;==&nbsp;r.Name &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;dto.Quantity&nbsp;==&nbsp;r.Quantity);</pre> </p> <p> This passed the test so that I could move on. It may even be the simplest thing that could possibly work, but it's brittle and noisy. </p> <p> It's brittle because it explicitly considers the four properties <code>At</code>, <code>Email</code>, <code>Name</code>, and <code>Quantity</code> of the <code>Reservation</code> class. What happens if you add a new property to <code>Reservation</code>? What happens if you have similar assertions scattered over the code base? </p> <p> This is one reason that <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> also applies to unit tests. You want to have as few places as possible that you have to edit when making changes. Otherwise, the risk increases that you forget one or more. </p> <p> Not only is the assertion brittle - it's also noisy, because it's hard to read. There's parsing, null coalescing and object initialisation going on in those four lines of Boolean operations. Perhaps it'd be better to extract a well-named helper method, but while I'm often in favour of doing that, I'm also a little concerned that too many ad-hoc helper methods obscure something essential. After all: </p> <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> The hardest part of abstraction is striking the right balance. Does a well-named helper method effectively communicate the essentials while eliminating <em>only</em> the irrelevant. While I favour good names over bad names, I'm also aware that <a href="/2020/11/23/good-names-are-skin-deep">good names are skin-deep</a>. If I can draw on a universal abstraction rather than coming up with an ad-hoc name, I prefer doing that. </p> <p> Which universal abstraction might be useful in this situation? </p> <h3 id="724d8609add4401cae58a14c259c5698"> Relaxed comparison <a href="#724d8609add4401cae58a14c259c5698" title="permalink">#</a> </h3> <p> The baseline version of the test relied on the structural equality of the <code>Reservation</code> class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>?&nbsp;<span style="color:#1f377f;">obj</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id.Equals(reservation.Id)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;==&nbsp;reservation.At&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;Email&gt;.Default.Equals(Email,&nbsp;reservation.Email)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;Name&gt;.Default.Equals(Name,&nbsp;reservation.Name)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;==&nbsp;reservation.Quantity; }</pre> </p> <p> This implementation was auto-generated by a Visual Studio <em>Quick Action</em>. From C# 9, I could also have made <code>Reservation</code> a <a href="https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/record">record</a>, in which case the compiler would be taking care of implementing <code>Equals</code>. </p> <p> The <code>Reservation</code> class already defines the canonical way to compare two reservations for equality. Why can't we use that? </p> <p> The <code>PostValidReservationWhenDatabaseIsEmpty</code> test can no longer use the <code>Reservation</code> class' structural equality because it doesn't know what the <code>Id</code> is going to be. </p> <p> One way to address this problem is to inject a hypothetical <code>IGuidGenerator</code> dependency into <code>ReservationsController</code>. I consider this a valid alternative, since the Controller already takes an <code>IClock</code> dependency. I might be inclined towards such a course of action <a href="/2020/03/23/repeatable-execution">for other reasons</a>, but here I wanted to explore other options. </p> <p> Can we somehow reuse the <code>Equals</code> implementation of <code>Reservation</code>, but relax its behaviour so that it doesn't consider the <code>Id</code>? </p> <p> This would be <a href="https://docs.microsoft.com/archive/msdn-magazine/2010/october/msdn-magazine-the-working-programmer-multiparadigmatic-net-part-2">what Ted Neward called <em>negative variability</em></a> - the ability to subtract from an existing feature. As he implied in 2010, normal programming languages don't have that capability. That strikes me as true in 2021 as well. </p> <p> The best we can hope for, then, is to put the required custom comparison somewhere central, so that at least it's not scattered across the entire code base. Since the test uses <a href="https://xunit.net">xUnit.net</a>, a class that implements <code>IEqualityComparer&lt;Reservation&gt;</code> sounds like just the right solution. </p> <p> This is definitely doable, but it's odd having to define a custom equality comparer for a class that already has structural equality. In the context of the <code>PostValidReservationWhenDatabaseIsEmpty</code> test, we understand the reason, but for a future team member who may encounter the class out of context, it might be confusing. </p> <p> Are there other options? </p> <h3 id="df0297c4c0274368843e9e0f5bb98cba"> Reuse <a href="#df0297c4c0274368843e9e0f5bb98cba" title="permalink">#</a> </h3> <p> It turns out that, by lucky accident, the code base already contains an equality comparer that almost fits: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReservationDtoComparer</span>&nbsp;:&nbsp;IEqualityComparer&lt;ReservationDto&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(ReservationDto?&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;ReservationDto?&nbsp;<span style="color:#1f377f;">y</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">datesAreEqual</span>&nbsp;=&nbsp;Equals(x?.At,&nbsp;y?.At); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!datesAreEqual&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime.TryParse(x?.At,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">xDate</span>)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime.TryParse(y?.At,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">yDate</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datesAreEqual&nbsp;=&nbsp;Equals(xDate,&nbsp;yDate); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;datesAreEqual &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;Equals(x?.Email,&nbsp;y?.Email) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;Equals(x?.Name,&nbsp;y?.Name) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;&nbsp;Equals(x?.Quantity,&nbsp;y?.Quantity); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>(ReservationDto&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dateHash</span>&nbsp;=&nbsp;obj.At?.GetHashCode(StringComparison.InvariantCulture); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(DateTime.TryParse(obj.At,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">dt</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dateHash&nbsp;=&nbsp;dt.GetHashCode(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(dateHash,&nbsp;obj.Email,&nbsp;obj.Name,&nbsp;obj.Quantity); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This class already compares two reservations' dates, emails, names, and quantities, while ignoring any IDs. Just what we need? </p> <p> There's only one problem. <code>ReservationDtoComparer</code> compares <code>ReservationDto</code> objects - not <code>Reservation</code> objects. </p> <p> Would it be possible to somehow, on the spot, without writing a new class, transform <code>ReservationDtoComparer</code> to an <code>IEqualityComparer&lt;Reservation&gt;</code>? </p> <p> Well, yes it is. </p> <h3 id="affeb3f683624666a9c1bb3b0bae342a"> Contravariant functor <a href="#affeb3f683624666a9c1bb3b0bae342a" title="permalink">#</a> </h3> <p> We can contramap an <code>IEqualityComparer&lt;ReservationDto&gt;</code> to a <code>IEqualityComparer&lt;Reservation&gt;</code> because <em>equivalence</em> gives rise to a contravariant functor. </p> <p> In order to enable contravariant mapping, you must add a <code>ContraMap</code> method: </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;">Equivalance</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEqualityComparer&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IEqualityComparer&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>)&nbsp;<span style="color:blue;">where</span>&nbsp;T&nbsp;:&nbsp;<span style="color:blue;">notnull</span> &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ContraMapComparer&lt;T,&nbsp;T1&gt;(source,&nbsp;selector); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ContraMapComparer</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;&nbsp;:&nbsp;IEqualityComparer&lt;T1&gt;&nbsp;<span style="color:blue;">where</span>&nbsp;T&nbsp;:&nbsp;<span style="color:blue;">notnull</span> &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IEqualityComparer&lt;T&gt;&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ContraMapComparer</span>(IEqualityComparer&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &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;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.selector&nbsp;=&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>([AllowNull]&nbsp;T1&nbsp;<span style="color:#1f377f;">x</span>,&nbsp;[AllowNull]&nbsp;T1&nbsp;<span style="color:#1f377f;">y</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(x&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>&nbsp;&amp;&amp;&nbsp;y&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">true</span>; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(x&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>&nbsp;||&nbsp;y&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">false</span>; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.Equals(selector(x),&nbsp;selector(y)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>(T1&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.GetHashCode(selector(obj)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Since the <code>IEqualityComparer&lt;T&gt;</code> interface defines <em>two</em> methods, the <code>selector</code> must contramap the behaviour of both <code>Equals</code> and <code>GetHashCode</code>. Fortunately, that's possible. </p> <p> Notice that, as explained in the overview article, in order to map from an <code>IEqualityComparer&lt;T&gt;</code> to an <code>IEqualityComparer&lt;T1&gt;</code>, the <code>selector</code> has to go the other way: from <code>T1</code> to <code>T</code>. How this is possible will become more apparent with an example, which will follow later in the article. </p> <h3 id="911357268ea14f09ac03bac6a781333e"> Identity law <a href="#911357268ea14f09ac03bac6a781333e" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for the <code>IEqualityComparer&lt;T&gt;</code> interface. In this article, you'll see parametrised tests written with xUnit.net. First, the identity law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;2,&nbsp;<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;2)] [InlineData(<span style="color:#a31515;">&quot;19:00&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;19:00&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1,&nbsp;<span style="color:#a31515;">&quot;19:00&quot;</span>,&nbsp;1)] [InlineData(<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;2,&nbsp;<span style="color:#a31515;">&quot;18:30&quot;</span>,&nbsp;1)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time1</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">size1</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time2</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">size2</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;TimeDtoComparer(); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;TimeDto&gt;?&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.ContraMap&lt;TimeDto,&nbsp;TimeDto&gt;(id); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dto1</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDto&nbsp;{&nbsp;Time&nbsp;=&nbsp;time1,&nbsp;MaximumPartySize&nbsp;=&nbsp;size1&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">dto2</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDto&nbsp;{&nbsp;Time&nbsp;=&nbsp;time2,&nbsp;MaximumPartySize&nbsp;=&nbsp;size2&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(sut.Equals(dto1,&nbsp;dto2),&nbsp;actual.Equals(dto1,&nbsp;dto2)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(sut.GetHashCode(dto1),&nbsp;actual.GetHashCode(dto1)); }</pre> </p> <p> In order to observe that the two comparers have identical behaviours, the test must invoke both the <code>Equals</code> and the <code>GetHashCode</code> methods on both <code>sut</code> and <code>actual</code> to assert that the two different objects produce the same output. </p> <p> All test cases pass. </p> <h3 id="c2228ba4c0044dc8b90ad92354850a22"> Composition law <a href="#c2228ba4c0044dc8b90ad92354850a22" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;&nbsp;7:45&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;18:13&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;18:13&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;18:13&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;22&quot;</span>&nbsp;&nbsp;&nbsp;,&nbsp;<span style="color:#a31515;">&quot;22&quot;</span>&nbsp;&nbsp;&nbsp;)] [InlineData(<span style="color:#a31515;">&quot;22:32&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;22&quot;</span>&nbsp;&nbsp;&nbsp;)] [InlineData(&nbsp;<span style="color:#a31515;">&quot;9&quot;</span>&nbsp;&nbsp;&nbsp;,&nbsp;&nbsp;<span style="color:#a31515;">&quot;9&quot;</span>&nbsp;&nbsp;&nbsp;)] [InlineData(&nbsp;<span style="color:#a31515;">&quot;9&quot;</span>&nbsp;&nbsp;&nbsp;,&nbsp;&nbsp;<span style="color:#a31515;">&quot;8&quot;</span>&nbsp;&nbsp;&nbsp;)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">CompositionLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time1</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">time2</span>) { &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;TimeDto&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDtoComparer(); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;(<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>)&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;(s,&nbsp;s.Length); &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;(<span style="color:blue;">string</span>&nbsp;s,&nbsp;<span style="color:blue;">int</span>&nbsp;i),&nbsp;TimeDto&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;TimeDto&nbsp;{&nbsp;Time&nbsp;=&nbsp;t.s,&nbsp;MaximumPartySize&nbsp;=&nbsp;t.i&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;<span style="color:blue;">string</span>&gt;?&nbsp;<span style="color:#1f377f;">projection1</span>&nbsp;=&nbsp;sut.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))); &nbsp;&nbsp;&nbsp;&nbsp;IEqualityComparer&lt;<span style="color:blue;">string</span>&gt;?&nbsp;<span style="color:#1f377f;">projection2</span>&nbsp;=&nbsp;sut.ContraMap(g).ContraMap(f); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection1.Equals(time1,&nbsp;time2), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection2.Equals(time1,&nbsp;time2)); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection1.GetHashCode(time1), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection2.GetHashCode(time1)); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to call both <code>Equals</code> and <code>GetHashCode</code> on <code>projection1</code> and <code>projection2</code> to verify that they return the same values. </p> <p> They do. </p> <h3 id="857e86fbf0944fe4b985cae73a9edb4b"> Relaxed assertion <a href="#857e86fbf0944fe4b985cae73a9edb4b" title="permalink">#</a> </h3> <p> The code base already contains a function that converts <code>Reservation</code> values to <code>ReservationDto</code> objects: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ReservationDto&nbsp;<span style="color:#74531f;">ToDto</span>(<span style="color:blue;">this</span>&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(reservation&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(reservation)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDto &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;reservation.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;=&nbsp;reservation.At.ToIso8601DateTimeString(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;reservation.Email.ToString(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;=&nbsp;reservation.Name.ToString(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;reservation.Quantity &nbsp;&nbsp;&nbsp;&nbsp;}; }</pre> </p> <p> Given that it's possible to map from <code>Reservation</code> to <code>ReservationDto</code>, it's also possible to map equality comparers in the contrary direction: from <code>IEqualityComparer&lt;ReservationDto&gt;</code> to <code>IEqualityComparer&lt;Reservation&gt;</code>. That's just what the <code>PostValidReservationWhenDatabaseIsEmpty</code> test needs! </p> <p> Most of the test stays the same, but you can now write the assertion as: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Reservation( &nbsp;&nbsp;&nbsp;&nbsp;Guid.NewGuid(), &nbsp;&nbsp;&nbsp;&nbsp;at, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Email(email), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;Name(name&nbsp;??&nbsp;<span style="color:#a31515;">&quot;&quot;</span>), &nbsp;&nbsp;&nbsp;&nbsp;quantity); Assert.Contains( &nbsp;&nbsp;&nbsp;&nbsp;expected, &nbsp;&nbsp;&nbsp;&nbsp;db.Grandfather, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDtoComparer().ContraMap((Reservation&nbsp;<span style="color:#1f377f;">r</span>)&nbsp;=&gt;&nbsp;r.ToDto()));</pre> </p> <p> Instead of using the too-strict equality comparison of <code>Reservation</code>, the assertion now takes advantage of the relaxed, test-specific comparison of <code>ReservationDto</code> objects. </p> <p> What's not to like? </p> <p> To be truthful, this probably isn't a trick I'll perform often. I think it's fair to consider contravariant functors an advanced programming concept. On a team, I'd be concerned that colleagues wouldn't understand what's going on here. </p> <p> The purpose of this article series isn't to advocate for this style of programming. It's to show some realistic examples of contravariant functors. </p> <p> Even in <a href="https://www.haskell.org">Haskell</a>, where contravariant functors are en explicit part of <a href="https://hackage.haskell.org/package/base/docs/index.html">the <em>base</em> package</a>, I can't recall having availed myself of this functionality. </p> <h3 id="50a1d26e56054e8f896af110d176e3a5"> Equivalence in Haskell <a href="#50a1d26e56054e8f896af110d176e3a5" title="permalink">#</a> </h3> <p> The <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">Haskell <em>Data.Functor.Contravariant</em> module</a> defines a <code>Contravariant</code> type class and some instances to go with it. One of these is a <code>newtype</code> called <code>Equivalence</code>, which is just a wrapper around <code>a -&gt; a -&gt; Bool</code>. </p> <p> In Haskell, equality is normally defined by the <code>Eq</code> type class. You can trivially 'promote' any <code>Eq</code> instance to an <code>Equivalence</code> instance using the <code>defaultEquivalence</code> value. </p> <p> To illustrate how this works in Haskell, you can reproduce the two reservation types: </p> <p> <pre><span style="color:blue;">data</span>&nbsp;Reservation&nbsp;=&nbsp;Reservation&nbsp;{ &nbsp;&nbsp;<span style="color:#2b91af;">reservationID</span>&nbsp;::&nbsp;<span style="color:blue;">UUID</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationAt</span>&nbsp;::&nbsp;<span style="color:blue;">LocalTime</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationEmail</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationName</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">reservationQuantity</span>&nbsp;::&nbsp;<span style="color:#2b91af;">Int</span>&nbsp;} &nbsp;&nbsp;<span style="color:blue;">deriving</span>&nbsp;(<span style="color:#2b91af;">Eq</span>,&nbsp;<span style="color:#2b91af;">Show</span>) <span style="color:blue;">data</span>&nbsp;ReservationJson&nbsp;=&nbsp;ReservationJson&nbsp;{ &nbsp;&nbsp;<span style="color:#2b91af;">jsonAt</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">jsonEmail</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">jsonName</span>&nbsp;::&nbsp;<span style="color:#2b91af;">String</span>, &nbsp;&nbsp;<span style="color:#2b91af;">jsonQuantity</span>&nbsp;::&nbsp;<span style="color:#2b91af;">Double</span>&nbsp;} &nbsp;&nbsp;<span style="color:blue;">deriving</span>&nbsp;(<span style="color:#2b91af;">Eq</span>,&nbsp;<span style="color:#2b91af;">Show</span>,&nbsp;<span style="color:#2b91af;">Read</span>,&nbsp;<span style="color:#2b91af;">Generic</span>)</pre> </p> <p> The <code>ReservationJson</code> type doesn't have an ID, whereas <code>Reservation</code> does. Still, you can easily convert from <code>Reservation</code> to <code>ReservationJson</code>: </p> <p> <pre><span style="color:#2b91af;">reservationToJson</span>&nbsp;::&nbsp;<span style="color:blue;">Reservation</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">ReservationJson</span> reservationToJson&nbsp;(Reservation&nbsp;_&nbsp;at&nbsp;email&nbsp;name&nbsp;q)&nbsp;= &nbsp;&nbsp;ReservationJson&nbsp;(<span style="color:blue;">show</span>&nbsp;at)&nbsp;email&nbsp;name&nbsp;(<span style="color:blue;">fromIntegral</span>&nbsp;q)</pre> </p> <p> Now imagine that you have two reservations that differ only on <code>reservationID</code>: </p> <p> <pre><span style="color:#2b91af;">reservation1</span>&nbsp;::&nbsp;<span style="color:blue;">Reservation</span> reservation1&nbsp;= &nbsp;&nbsp;Reservation &nbsp;&nbsp;&nbsp;&nbsp;(fromWords&nbsp;3822151499&nbsp;288494060&nbsp;2147588346&nbsp;2611157519) &nbsp;&nbsp;&nbsp;&nbsp;(LocalTime&nbsp;(fromGregorian&nbsp;2021&nbsp;11&nbsp;11)&nbsp;(TimeOfDay&nbsp;12&nbsp;30&nbsp;0)) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;just.inhale@example.net&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;Justin&nbsp;Hale&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;2 <span style="color:#2b91af;">reservation2</span>&nbsp;::&nbsp;<span style="color:blue;">Reservation</span> reservation2&nbsp;= &nbsp;&nbsp;Reservation &nbsp;&nbsp;&nbsp;&nbsp;(fromWords&nbsp;1263859666&nbsp;288625132&nbsp;2147588346&nbsp;2611157519) &nbsp;&nbsp;&nbsp;&nbsp;(LocalTime&nbsp;(fromGregorian&nbsp;2021&nbsp;11&nbsp;11)&nbsp;(TimeOfDay&nbsp;12&nbsp;30&nbsp;0)) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;just.inhale@example.net&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;Justin&nbsp;Hale&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;2</pre> </p> <p> If you compare these two values using the standard equality operator, they're (not surprisingly) not the same: </p> <p> <pre>&gt; reservation1 == reservation2 False</pre> </p> <p> Attempting to compare them using the default <code>Equivalence</code> value doesn't help, either: </p> <p> <pre>&gt; (getEquivalence $ defaultEquivalence) reservation1 reservation2 False</pre> </p> <p> But if you promote the comparison to <code>Equivalence</code> and then <code>contramap</code> it with <code>reservationToJson</code>, they do look the same: </p> <p> <pre>&gt; (getEquivalence $ contramap reservationToJson $ defaultEquivalence) reservation1 reservation2 True</pre> </p> <p> This Haskell example is equivalent in spirit to the above C# assertion. </p> <p> Notice that <code>Equivalence</code> is only a wrapper around any function of the type <code>a -&gt; a -&gt; Bool</code>. This corresponds to the <code>IEqualityComparer</code> interface's <code>Equals</code> method. On the other hand, <code>Equivalence</code> has no counterpart to <code>GetHashCode</code> - that's a .NETism. </p> <p> When using Haskell as inspiration for identifying universal abstractions, it's not entirely clear how <code>Equivalence</code> is similar to <code>IEqualityComparer&lt;T&gt;</code>. While <code>a -&gt; a -&gt; Bool</code> is isomorphic to its <code>Equals</code> method, and thus gives rise to a contravariant functor, what about the <code>GetHashCode</code> method? </p> <p> As this article has demonstrated, it turned out that it's possible to also contramap the <code>GetHashCode</code> method, but was that just a fortunate accident, or is there something more fundamental going on? </p> <h3 id="d51dbd1743e14420ab8c38b25bc02369"> Conclusion <a href="#d51dbd1743e14420ab8c38b25bc02369" title="permalink">#</a> </h3> <p> Equivalence relations give rise to a contravariant functor. In this article, you saw how this property can be used to relax assertions in unit tests. </p> <p> Strictly speaking, an equivalence relation is exclusively a function that compares two values to return a Boolean value. No <code>GetHashCode</code> method is required. That's a .NET-specific implementation detail that, unfortunately, has been allowed to leak into the <code>object</code> base class. It's not part of the concept of an equivalence relation, but still, it's possible to form a contravariant functor from <code>IEqualityComparer&lt;T&gt;</code>. Is this just a happy coincidence, or could there be something more fundamental going on? </p> <p> Read on. </p> <p> <strong>Next:</strong> <a href="/2021/10/04/reader-as-a-contravariant-functor">Reader as a contravariant 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>. Keep IDs internal with REST https://blog.ploeh.dk/2021/09/20/keep-ids-internal-with-rest 2021-09-20T06:21:00+00:00 Mark Seemann <div id="post"> <p> <em>Instead of relying on entity IDs, use hypermedia to identify resources.</em> </p> <p> Whenever I've helped teams design HTTP APIs, sooner or later one request comes up - typically from client developers: <em>Please add the entity ID to the representation.</em> </p> <p> In this article I'll show an alternative, but first: the normal state of affairs. </p> <h3 id="24703d08faec4fe6a650599e54e8dbf8"> Business as usual <a href="#24703d08faec4fe6a650599e54e8dbf8" title="permalink">#</a> </h3> <p> It's such a common requirement that, despite admonitions not to expose IDs, I did it myself in the code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. This code base is a <a href="https://martinfowler.com/articles/richardsonMaturityModel.html">level 3 REST API</a>, and still, I'd included the ID in the JSON representation of a reservation: </p> <p> <pre>{ &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;bf4e84130dac451b9c94049da8ea8c17&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> At least the ID is a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">GUID</a>, so I'm <a href="/2014/08/11/cqs-versus-server-generated-ids">not exposing internal database IDs</a>. </p> <p> After having written the book, the <code>id</code> property kept nagging me, and I wondered if it'd be possible to get rid of it. After all, in a true REST API, clients aren't supposed to construct URLs from templates. They're supposed to follow links. So why do you need the ID? </p> <h3 id="e480deb4e2b3470a847fc2995bdf406d"> Following links <a href="#e480deb4e2b3470a847fc2995bdf406d" title="permalink">#</a> </h3> <p> Early on in the system's lifetime, I began <a href="/2020/10/26/fit-urls">signing all URLs</a> to prevent clients from <a href="/2013/05/01/rest-lesson-learned-avoid-hackable-urls">retro-engineering URLs</a>. This also meant that most of my <a href="/2021/01/25/self-hosted-integration-tests-in-aspnet">self-hosted integration tests</a> were already following links: </p> <p> <pre>[Theory] [InlineData(867,&nbsp;19,&nbsp;10,&nbsp;<span style="color:#a31515;">&quot;adur@example.net&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Adrienne&nbsp;Ursa&quot;</span>,&nbsp;2)] [InlineData(901,&nbsp;18,&nbsp;55,&nbsp;<span style="color:#a31515;">&quot;emol@example.gov&quot;</span>,&nbsp;<span style="color:#a31515;">&quot;Emma&nbsp;Olsen&quot;</span>,&nbsp;5)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">ReadSuccessfulReservation</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">days</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">hours</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">minutes</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">email</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">name</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">api</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;LegacyApi(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">at</span>&nbsp;=&nbsp;DateTime.Today.AddDays(days).At(hours,&nbsp;minutes) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ToIso8601DateTimeString(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;Create.ReservationDto(at,&nbsp;email,&nbsp;name,&nbsp;quantity); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">postResp</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;api.PostReservation(expected); &nbsp;&nbsp;&nbsp;&nbsp;Uri&nbsp;<span style="color:#1f377f;">address</span>&nbsp;=&nbsp;FindReservationAddress(postResp); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">getResp</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;api.CreateClient().GetAsync(address); &nbsp;&nbsp;&nbsp;&nbsp;getResp.EnsureSuccessStatusCode(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;getResp.ParseJsonContent&lt;ReservationDto&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual,&nbsp;<span style="color:blue;">new</span>&nbsp;ReservationDtoComparer()); &nbsp;&nbsp;&nbsp;&nbsp;AssertUrlFormatIsIdiomatic(address); }</pre> </p> <p> This parametrised test uses <a href="https://xunit.net">xUnit.net</a> 2.4.1 to first post a new reservation to the system, and then following the link provided in the response's <code>Location</code> header to verify that this resource contains a representation compatible with the reservation that was posted. </p> <p> A corresponding plaintext HTTP session would start like this: </p> <p> <pre>POST /restaurants/90125/reservations?sig=aco7VV%2Bh5sA3RBtrN8zI8Y9kLKGC60Gm3SioZGosXVE%3D HTTP/1.1 Content-Type: application/json { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08&nbsp;20:30&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 } HTTP/1.1 201 Created Content-Type: application/json; charset=utf-8 Location: example.com/restaurants/90125/reservations/bf4e84130dac451b9c94049da8ea8c17?sig=ZVM%2[...] { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;bf4e84130dac451b9c94049da8ea8c17&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> That's the first request and response. Clients can now examine the response's headers to find the <code>Location</code> header. That URL is the actual, external ID of the resource, not the <code>id</code> property in the JSON representation. </p> <p> The client can save that URL and request it whenever it needs the reservation: </p> <p> <pre>GET /restaurants/90125/reservations/bf4e84130dac451b9c94049da8ea8c17?sig=ZVM%2[...] HTTP/1.1 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;bf4e84130dac451b9c94049da8ea8c17&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> The actual, intended use of the API doesn't rely on the <code>id</code> property, neither do the tests. </p> <p> Based on this consistent design principle, I had reason to hope that I'd be able to remove the <code>id</code> property. </p> <h3 id="f4fc880aa8434cc2ac1675fcdf68bc18"> Breaking change <a href="#f4fc880aa8434cc2ac1675fcdf68bc18" title="permalink">#</a> </h3> <p> My motivation for making this change was to educate myself. I wanted to see if it would be possible to design a REST API that doesn't expose IDs in their JSON (or XML) representations. Usually I'm having trouble doing this in practice because when I'm consulting, I'm typically present to help the organisation with test-driven development and how to organise their code. It's always hard to learn new ways of doing things, and I don't wish to overwhelm my clients with too many changes all at once. </p> <p> So I usually let them do <a href="https://martinfowler.com/articles/richardsonMaturityModel.html">level 2 APIs</a> because that's what they're comfortable with. With that style of HTTP API design, it's hard to avoid <code>id</code> fields. </p> <p> This wasn't a constraint for the book's code, so I'd gone full REST on that API, and I'm happy that I did. By habit, though, I'd exposed the <code>id</code> property in JSON, and I now wanted to perform an experiment: Could I remove the field? </p> <p> A word of warning: You can't just remove a JSON property from a production API. That would constitute a breaking change, and even though clients aren't supposed to use the <code>id</code>, <a href="https://www.hyrumslaw.com">Hyrum's law</a> says that someone somewhere probably already is. </p> <p> This is just an experiment that I carried out on a separate Git branch, for my own edification. </p> <h3 id="3cf78b876e2a4f91b3e49b91f89bde02"> Leaning on the compiler <a href="#3cf78b876e2a4f91b3e49b91f89bde02" title="permalink">#</a> </h3> <p> As outlined, I had relatively strong faith in my test suite, so I decided to modify the <a href="https://en.wikipedia.org/wiki/Data_transfer_object">Data Transfer Object</a> (DTO) in question. Before the change, it looked like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReservationDto</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;LinkDto[]?&nbsp;Links&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;">string</span>?&nbsp;Id&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;">string</span>?&nbsp;At&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;">string</span>?&nbsp;Email&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;">string</span>?&nbsp;Name&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;">int</span>&nbsp;Quantity&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} }</pre> </p> <p> At first, I simply tried to delete the <code>Id</code> property, but while it turned out to be not too bad in general, it did break one feature: The ability of <a href="/2020/08/24/adding-rest-links-as-a-cross-cutting-concern">the LinksFilter</a> to generate links to reservations. Instead, I changed the <code>Id</code> property to be internal: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReservationDto</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;LinkDto[]?&nbsp;Links&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;Id&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;">string</span>?&nbsp;At&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;">string</span>?&nbsp;Email&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;">string</span>?&nbsp;Name&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;">int</span>&nbsp;Quantity&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;<span style="color:blue;">set</span>;&nbsp;} }</pre> </p> <p> This enables the <code>LinksFilter</code> and other internal code to still access the <code>Id</code> property, while the unit tests no longer could. As expected, this change caused some compiler errors. That was expected, and my plan was to <em>lean on the compiler</em>, as <a href="https://michaelfeathers.silvrback.com">Michael Feathers</a> describes in <a href="http://bit.ly/working-effectively-with-legacy-code">Working Effectively with Legacy Code</a>. </p> <p> As I had hoped, relatively few things broke, and they were fixed in 5-10 minutes. Once everything compiled, I ran the tests. Only a single test failed, and this was a unit test that used some Back Door Manipulation, as <a href="http://bit.ly/xunitpatterns">xUnit Test Patterns</a> terms it. I'll return to that test in <a href="/2021/09/27/the-equivalence-contravariant-functor">a future article</a>. </p> <p> None of my self-hosted integration tests failed. </p> <h3 id="d65ef3b7816c4f73b1060af4532fe1dc"> ID-free interaction <a href="#d65ef3b7816c4f73b1060af4532fe1dc" title="permalink">#</a> </h3> <p> Since clients are supposed to follow links, they can still do so. For example, a <a href="https://en.wikipedia.org/wiki/Maître_d%27hôtel">maître d'hôtel</a> might request the day's schedule: </p> <p> <pre>GET /restaurants/90125/schedule/2021/12/8?sig=82fosBYsE9zSKkA4Biy5t%2BFMxl71XiLlFKaI2E[...] HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZXN0YXVyYW50IjpbIjEiLCIyMTEyIiwi[...] HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;The&nbsp;Vatican&nbsp;Cellar&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;year&quot;</span>:&nbsp;2021, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;month&quot;</span>:&nbsp;12, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;day&quot;</span>:&nbsp;8, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;days&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;date&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;entries&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;time&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;20:30:00&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;reservations&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;links&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;rel&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;urn:reservation&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;href&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;http://example.com/restaurants/90125/reservations/bf4e84130dac4[...]&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;], &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;] }</pre> </p> <p> I've edited the response quite heavily by removing other links, and so on. </p> <p> Clients that wish to navigate to Snow Moe Beal's reservation must locate its <code>urn:reservation</code> link and use the corresponding <code>href</code> value. This is an opaque URL that clients can use to make requests: </p> <p> <pre>GET /restaurants/90125/reservations/bf4e84130dac451b9c94049da8ea8c17?sig=vxkBT1g1GHRmx[...] HTTP/1.1 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-12-08T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;snomob@example.com&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Snow&nbsp;Moe&nbsp;Beal&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;1 }</pre> </p> <p> In none of these interactions do clients rely on the <code>id</code> property - which is also gone now. It's gone because the <code>Id</code> property on the C# DTO is <code>internal</code>, which means that it's not being rendered. </p> <p> Mission accomplished. </p> <h3 id="849eb1540d7145c78415976e8c662597"> Conclusion <a href="#849eb1540d7145c78415976e8c662597" title="permalink">#</a> </h3> <p> It always grates on me when I have to add an <code>id</code> property to a representation in an HTTP API. It's often necessary when working with a level 2 API, but with a proper hypermedia-driven REST API, it may not be necessary. </p> <p> At least, the experiment I performed with the code base from my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a> indicates that this may be so. </p> </div> <div id="comments"> <hr> <h2 id="comments-header">Comments</h2> <div class="comment" id="cd972bab11b74bf382c5796f5b0bec7a"> <div class="comment-author"><a href="https://www.relativisticramblings.com/">Christer van der Meeren</a></div> <div class="comment-content"> <p>It seems to me that this approach will cause problems if 3rd parties need to integrate with your API in a way where they themselves need to store references to entities in your system. For example, they may expose your entities to their users with additional data in their systems/integrations. Sure, it is <em>possible</em> for them to use the URI as a primary key (<em>if</em> you guarantee a sensible max URI length; another can of worms), but if you internally use INT or UNIQUEIDENTIFIER as your primary key, I would not want to force them to use VARCHAR(whatever) as primary key.</p> <p>Therefore, in all our APIs, we document in the API specification that the IDs, though required by <a target="_blank" href="https://jsonapi.org/">JSON:API</a> (which we follow) to be passed as string values for consistency, can be safely assumed to be integers (or GUIDs, if relevant). We even document that they are <em>32-bit</em> ints, so any clients know they can safely use INT fields instead of BIGINT.</p> <p>JSON:API requires all entities to have a single ID. For obvious reasons, IDs should be stable. Therefore, for entities that represent an association between two other entities and do not have a separate, persisted ID, we have a need to have API IDs that contain information about the associated entities. To combat Hyrum's law, we typically concatenate the associated IDs using a known delimiter and encode the resulting string using a non-standard, URL-friendly encoding (i.e., not Base64, which may contain non-URL-friendly characters and is often obvious). This way, the IDs appear opaque to API clients. Of course, the format of these IDs are not documented in our API specifications, as they are not intended to be stored. Instead, the actual association is documented and the related entities retrievable (of course, since this information inherent to the entity's very nature), and the associated IDs may be used by clients in a multi-column primary key, just like we do.</p> <p>All of the above assumes that the integrating clients use a SQL database or similar. Let's face it; many do. If you have (or may hve in the future) a single client that do this, you have to take the above into account.</p> </div> <div class="comment-date">2021-09-20 9:07 UTC</div> </div> <div class="comment" id="2fa9b78a83b64b33ae16182ed7db450c"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Christer, thank you for writing. I think that one of the problems with discussions about REST APIs, or just HTTP APIs in general, is that people use them for all sorts of things. At one extreme, you have <a href="https://samnewman.io/patterns/architectural/bff/">Backends For Frontends</a>, where, if you aren't writing the API with the single client in mind, you're doing something wrong. At the other extreme, you have APIs that may have uncountable and unknown clients. When I write about REST, I mostly have the latter kind in mind. </p> <p> When designing APIs for many unknown clients, it makes little sense to take 'special needs' into account. Different clients may present mutually exclusive requirements. </p> <p> Clients that need to 'bookmark' REST resources in a database can do that by defining two columns: one an ordinary primary key column on which the table defines its clustered index, and another column for the link value itself, with a <code>UNIQUE</code> constraint. Something like this (in T-SQL dialect): </p> <p> <pre><span style="color:blue;">CREATE</span>&nbsp;<span style="color:blue;">TABLE</span>&nbsp;[dbo]<span style="color:gray;">.</span>[Foo]<span style="color:blue;">&nbsp;</span><span style="color:gray;">(</span> &nbsp;&nbsp;&nbsp;&nbsp;[Id]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">INT</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL</span>&nbsp;<span style="color:blue;">IDENTITY</span>&nbsp;<span style="color:blue;">PRIMARY</span>&nbsp;<span style="color:blue;">KEY</span>&nbsp;<span style="color:blue;">CLUSTERED</span><span style="color:gray;">,</span> &nbsp;&nbsp;&nbsp;&nbsp;[Address]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">NVARCHAR&nbsp;</span><span style="color:gray;">(</span>850<span style="color:gray;">)</span>&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL</span>&nbsp;<span style="color:blue;">UNIQUE</span>&nbsp;<span style="color:blue;">NONCLUSTERED</span><span style="color:gray;">,</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">--&nbsp;Other&nbsp;columns&nbsp;go&nbsp;here...</span> <span style="color:gray;">);</span></pre> </p> <p> Client code can look up an API resource on internal key, or on address, as required. </p> </div> <div class="comment-date">2021-09-21 16:27 UTC</div> </div> <div class="comment" id="6a7b06cf97e9453bafe5ddafa5156093"> <div class="comment-author"><a href="https://www.relativisticramblings.com/">Christer van der Meeren</a></div> <div class="comment-content"> <p>Your URLs include a signature, which changes if you need to switch signing keys. Furthermore, the base URL for your API may change. The entities are still the same; the restaurant previously at old.domain/restaurants/1?sig=abc is the same as the restaurant now at new.domain/restaurants/1?sig=123. With your proposed bookmark-based solution, the API clients would effectively lose the associations in their system.</p> <p>Also, indexing a very long varchar column probably works fine for tables that are fairly small and not overly busy. But for large and/or busy tables containing entities that are created every second of every day (say, passages through gates at hundreds of large construction sites, which is one of the domains I work with), I think that the performance would suffer unreasonably. (Admittedly, I have of course not measured this; this is just speculation, and anyway not my main point.)</p> <p>You say you write APIs with arbitrary clients in mind. I do, too. That is one of the reasons I design my APIs at REST level 2 instead of 3. (JSON:API does offer some possibility of just "following links" if the client wishes to do that, though it is does not allow for APIs that are fully level 3/HATEOAS.) Having stable IDs with well-known formats and being able to construct URLs seems pragmatically like a good solution that keeps client developers happy. I do not have decades of experience, but I have never encountered clients who have been unhappy with my decision to go for level 2 instead of level 3. (I imagine I would have encountered some resistance in the opposite case, though that is pure speculation on my part.) Furthermore, I have never encountered the need for breaking changes that would be non-breaking by level 3 standards.</p> <p>You say it makes little sense to take "special needs" into account. Idealistically, I agree. Pragmatically, 1) SQL databases are so ubiquitous and have been for such a long time that making life better for those developers by including an ID with a guaranteed format seems like a fair decision, and 2) our APIs (and many others, I assume) are created not just for 3rd party integration but also for one or more 1st party front-ends, which naturally tends to receive some preferential treatment (e.g. features and designs that probably aren't useful to other clients).</p> </div> <div class="comment-date">2021-09-21 20:56 UTC</div> </div> <div class="comment" id="e1a154854b014ab8ad218b076579db4c"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Christer, thank you for writing. It's possible that I'm going about this the wrong way. I only report on what's been working for me, but that said, while I <em>do</em> have decades of general programming experience, I don't have decades of REST experience. I designed my first REST API in 2012. </p> <p> Additionally, just because one style of API design works well, that doesn't rule out that other types of design also work. </p> <p> Finally, this particular article is an experiment. I've never done something like this in the wild, so it's possible that it does have unforeseen issues. </p> <p> A couple of answers to your various points, though: </p> <p> I don't foresee having to change signing keys, but if that happens, it'd be a breaking change to remove support for old keys. One might have to, instead, retire old signing keys in the same way one can <a href="/2020/06/01/retiring-old-service-versions">retire old service versions</a>. Even if a key gets 'compromised', it's not an immediate issue. It only means that any client that possesses the leaked key <em>can</em> construct URLs directly by <a href="/2013/05/01/rest-lesson-learned-avoid-hackable-urls">retro-engineering implied URL templates</a>. This would still be undocumented and unsupported use of the API, which means that ultimately, it'd be against the client developers' own self-interest in doing that. </p> <p> <a href="/2020/10/26/fit-urls">Signing the URLs isn't a security measure</a>; it's more like a <a href="https://en.wikipedia.org/wiki/Nudge_theory">nudge</a>. </p> <blockquote> <p> "our APIs (and many others, I assume) are created not just for 3rd party integration but also for one or more 1st party front-ends, which naturally tends to receive some preferential treatment" </p> </blockquote> <p> I've written APIs like that as well, and if there's one thing I've learned from doing that is that if I'm ever again put in charge of such an API, I'll strongly resist giving preferential treatment to any clients. If a particular client needs a particular feature, the client team can develop and maintain a Backend for Frontend, which bases its own implementation on the general-purpose API. </p> <p> My experience with supporting particular clients is that client needs evolve much faster than APIs. This makes sense. Someone wants to do <a href="https://en.wikipedia.org/wiki/A/B_testing">A/B testing</a> on the client's user interface. Depending on the outcome of such a test, at least one of the supporting features will now be obsolete. I'm not much inclined having to support such features in an API where backwards compatibility is critical. </p> <p> But again, these things are never clear-cut. Much depends on the overall goals of the organisation - and these may also change over time. I'm not claiming that my way is <em>best</em> - only that it's possible. </p> </div> <div class="comment-date">2021-09-23 8:07 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>. Unit testing private helper methods https://blog.ploeh.dk/2021/09/13/unit-testing-private-helper-methods 2021-09-13T05:25:00+00:00 Mark Seemann <div id="post"> <p> <em>Evolving a private helper method, guided by tests.</em> </p> <p> A frequently asked question about unit testing and test-driven development (TDD) is how to test private helper methods. I've <a href="/2015/09/22/unit-testing-internals">already attempted to answer that question: <em>through the public API</em></a>, but a recent comment to <a href="https://stackoverflow.com/a/69141655/126014">a Stack Overflow question</a> made me realise that I've failed to supply a code example. </p> <p> Show, don't tell. </p> <p> In this article I'll show a code example that outlines how a private helper method can evolve under TDD. </p> <h3 id="03e1e533e1514945812c557b006883c3"> Threshold <a href="#03e1e533e1514945812c557b006883c3" title="permalink">#</a> </h3> <p> The code example in this article comes from my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>. When you buy the book, you get not only the finished code examples, but the entire Git repository, with detailed commit messages. </p> <p> A central part of the code base is a method that decides whether or not to accept a reservation attempt. It's essentially a solution to <a href="/2020/01/27/the-maitre-d-kata/">the Maître d' kata</a>. I wrote most of the book's code with TDD, and after commit <code>fa12fd69c158168178f3a75bcd900e5caa7e7dec</code> I decided that I ought to refactor the implementation. As I wrote in the commit message: </p> <p> <pre>Filter later reservations based on date The line count of the willAccept method has now risen to 28. Cyclomatic complexity is still at 7. It's ripe for refactoring.</pre> </p> <p> I think, by the way, that I made a small mistake. As far as I can tell, the <code>WillAccept</code> line count in this commit is <em>26</em> - not <em>28:</em> </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">WillAccept</span>( &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">existingReservations</span>, &nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">candidate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existingReservations&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(existingReservations)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(candidate&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(candidate)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">relevantReservations</span>&nbsp;=&nbsp;existingReservations &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Where(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;candidate.At.Date&nbsp;==&nbsp;r.At.Date); &nbsp;&nbsp;&nbsp;&nbsp;List&lt;Table&gt;&nbsp;<span style="color:#1f377f;">availableTables</span>&nbsp;=&nbsp;Tables.ToList(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">foreach</span>&nbsp;(var&nbsp;<span style="color:#1f377f;">r</span>&nbsp;<span style="color:#8f08c4;">in</span>&nbsp;relevantReservations) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">table</span>&nbsp;=&nbsp;availableTables.Find(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;r.Quantity&nbsp;&lt;=&nbsp;t.Seats); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Remove(table); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table.IsCommunal) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Add(table.Reserve(r.Quantity)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;availableTables.Any(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;candidate.Quantity&nbsp;&lt;=&nbsp;t.Seats); }</pre> </p> <p> Still, I knew that it wasn't done - that I'd be adding more tests that would increase both the size and complexity of the method. It was brushing against more than one <a href="/2020/04/13/curb-code-rot-with-thresholds">threshold</a>. I decided that it was time for a prophylactic refactoring. </p> <p> Notice that the <a href="/2019/10/21/a-red-green-refactor-checklist">red-green-refactor checklist</a> explicitly states that refactoring is part of the process. It doesn't, however, mandate that refactoring must be done in the same commit as the green phase. Here, I did <em>red-green-commit-refactor-commit</em>. </p> <p> While I decided to refactor, I also knew that I still had some way to go before <code>WillAccept</code> would be complete. With the code still in flux, I didn't want to couple tests to a new method, so I chose to extract a <code>private</code> helper method. </p> <h3 id="8db39405ecce4ee9b647866eed0e1383"> Helper method <a href="#8db39405ecce4ee9b647866eed0e1383" title="permalink">#</a> </h3> <p> After the refactoring, the code looked like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">WillAccept</span>( &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">existingReservations</span>, &nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">candidate</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existingReservations&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(existingReservations)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(candidate&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(candidate)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">relevantReservations</span>&nbsp;=&nbsp;existingReservations &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Where(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;candidate.At.Date&nbsp;==&nbsp;r.At.Date); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">availableTables</span>&nbsp;=&nbsp;Allocate(relevantReservations); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;availableTables.Any(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;candidate.Quantity&nbsp;&lt;=&nbsp;t.Seats); } <span style="color:blue;">private</span>&nbsp;IEnumerable&lt;Table&gt;&nbsp;<span style="color:#74531f;">Allocate</span>( &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;List&lt;Table&gt;&nbsp;<span style="color:#1f377f;">availableTables</span>&nbsp;=&nbsp;Tables.ToList(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">foreach</span>&nbsp;(var&nbsp;<span style="color:#1f377f;">r</span>&nbsp;<span style="color:#8f08c4;">in</span>&nbsp;reservations) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">table</span>&nbsp;=&nbsp;availableTables.Find(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;r.Quantity&nbsp;&lt;=&nbsp;t.Seats); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Remove(table); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(table.IsCommunal) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;availableTables.Add(table.Reserve(r.Quantity)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;availableTables; }</pre> </p> <p> I committed the change, and wrote in the commit message: </p> <p> <pre>Extract helper method from WillAccept This quite improves the complexity of the method, which is now 4, and at 18 lines of code. The new helper method also has a cyclomatic complexity of 4, and 17 lines of code. A remaining issue with the WillAccept method is that the code operates on different levels of abstraction. The call to Allocate represents an abstraction, while the filter on date is as low-level as it can get.</pre> </p> <p> As you can tell, I was well aware that there were remaining issues with the code. </p> <p> Since the new <code>Allocate</code> helper method is <code>private</code>, unit tests can't reach it directly. It's still <em>covered</em> by tests, though, just as that code block was before I extracted it. </p> <h3 id="b8928ae201444a78b7ca1715e486fb92"> More tests <a href="#b8928ae201444a78b7ca1715e486fb92" title="permalink">#</a> </h3> <p> I wasn't done with the <code>WillAccept</code> method, and after a bout of other refactorings, I added more test cases covering it. </p> <p> While the method ultimately grew to exhibit moderately complex behaviour, I had only two test methods covering it: one (not shown) for the rejection case, and another for the accept (<code>true</code>) case: </p> <p> <pre>[Theory,&nbsp;ClassData(<span style="color:blue;">typeof</span>(AcceptTestCases))] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Accept</span>( &nbsp;&nbsp;&nbsp;&nbsp;TimeSpan&nbsp;<span style="color:#1f377f;">seatingDuration</span>, &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Table&gt;&nbsp;<span style="color:#1f377f;">tables</span>, &nbsp;&nbsp;&nbsp;&nbsp;IEnumerable&lt;Reservation&gt;&nbsp;<span style="color:#1f377f;">reservations</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;MaitreD(seatingDuration,&nbsp;tables); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;Some.Reservation.WithQuantity(11); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.WillAccept(reservations,&nbsp;r); &nbsp;&nbsp;&nbsp;&nbsp;Assert.True(actual); }</pre> </p> <p> I based the example code on the <a href="/2020/03/02/impureim-sandwich">impureim sandwich architecture</a>, which meant that domain logic (including the <code>WillAccept</code> method) is all <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. The nice thing about pure functions is that <a href="/2015/05/07/functional-design-is-intrinsically-testable">they're easy to unit test</a>. </p> <p> The <code>Accept</code> test method uses an object data source (see the article <a href="/2021/01/18/parametrised-test-primitive-obsession-code-smell">Parametrised test primitive obsession code smell</a> for another example of the motivation behind using objects for test parametrisation), so adding more test cases were simply a matter of adding them to the data source: </p> <p> <pre><span style="color:silver;">Add(TimeSpan.FromHours(6), &nbsp;&nbsp;&nbsp;&nbsp;new[]&nbsp;{&nbsp;Table.Communal(11)&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;new[]&nbsp;{&nbsp;Some.Reservation.WithQuantity(11).TheDayAfter()&nbsp;});</span> Add(TimeSpan.FromHours(2.5), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Table.Standard(12)&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Some.Reservation.WithQuantity(11).AddDate( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeSpan.FromHours(-2.5))&nbsp;}); Add(TimeSpan.FromHours(1), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Table.Standard(14)&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;Some.Reservation.WithQuantity(9).AddDate( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeSpan.FromHours(1))&nbsp;});</pre> </p> <p> The bottom two test cases are new additions. In that way, by adding new test cases, I could keep evolving <code>WillAccept</code> and its various private helper methods (of which I added more). While no tests directly exercise the private helper methods, the unit tests still <a href="https://en.wikipedia.org/wiki/Transitive_relation">transitively</a> exercise the private parts of the code base. </p> <p> Since I followed TDD, no private helper methods sprang into existence untested. I didn't have to jump through hoops in order to be able to unit test private helper methods. Rather, the private helper methods were a natural by-product of the red-green-refactor process - particularly, the <em>refactor</em> phase. </p> <h3 id="6c5f4e12a3cb4318a3331cf4f2485028"> Conclusion <a href="#6c5f4e12a3cb4318a3331cf4f2485028" title="permalink">#</a> </h3> <p> Following TDD doesn't preclude the creation of private helper methods. In fact, private helper methods can (and should?) emerge during the refactoring phase of the red-green-refactoring cycle. </p> <p> For long-time practitioners of TDD, there's nothing new in this, but people new to TDD are still learning. This question keeps coming up, so I hope that this example is useful. </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>. The Specification contravariant functor https://blog.ploeh.dk/2021/09/09/the-specification-contravariant-functor 2021-09-09T09:12:00+00:00 Mark Seemann <div id="post"> <p> <em>An introduction for object-oriented programmers to the Specification contravariant functor.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. In the <a href="/2021/09/06/the-command-handler-contravariant-functor">previous article</a>, you saw an example of a contravariant functor based on the Command Handler pattern. This article gives another example. </p> <p> <a href="http://amzn.to/WBCwx7">Domain-Driven Design</a> discusses the benefits of the <a href="https://en.wikipedia.org/wiki/Specification_pattern">Specification pattern</a>. In its generic incarnation this pattern gives rise to a contravariant functor. </p> <h3 id="2d6538ee35d84c47808f6b162f61eeb3"> Interface <a href="#2d6538ee35d84c47808f6b162f61eeb3" title="permalink">#</a> </h3> <p> <a href="http://amzn.to/WBCwx7">DDD</a> introduces the pattern with a non-generic <code>InvoiceSpecification</code> interface. The book also shows other examples, and it quickly becomes clear that with generics, you can generalise the pattern to this interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">ISpecification</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T&nbsp;<span style="color:#1f377f;">candidate</span>); }</pre> </p> <p> Given such an interface, you can implement standard reusable Boolean logic such as <em>and</em>, <em>or</em>, and <em>not</em>. (Exercise: consider how implementations of <em>and</em> and <em>or</em> correspond to well-known <a href="/2017/10/06/monoids">monoids</a>. Do the implementations look like <a href="https://en.wikipedia.org/wiki/Composite_pattern">Composites</a>? <a href="/2018/03/12/composite-as-a-monoid">Is that a coincidence?</a>) </p> <p> The <code>ISpecification&lt;T&gt;</code> interface is really just a glorified predicate. These days the Specification pattern may seem somewhat exotic in languages with first-class functions. C#, for example, defines both a <a href="https://docs.microsoft.com/dotnet/api/system.predicate-1">specialised Predicate delegate</a>, as well as the more general <code>Func&lt;T, bool&gt;</code> delegate. Since you can pass those around as objects, that's often good enough, and you don't need an <code>ISpecification</code> interface. </p> <p> Still, for the sake of argument, in this article I'll start with the Specification pattern and demonstrate how that gives rise to a contravariant functor. </p> <h3 id="a13ce5becb564762847a6876f87aa16f"> Natural number specification <a href="#a13ce5becb564762847a6876f87aa16f" title="permalink">#</a> </h3> <p> Consider the <code>AdjustInventoryService</code> class from <a href="/2021/09/06/the-command-handler-contravariant-functor">the previous article</a>. I'll repeat the 'original' <code>Execute</code> method here: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantityAdjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.AdjustQuantity(quantityAdjustment); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InvalidOperationException(<span style="color:#a31515;">&quot;Can&#39;t&nbsp;decrease&nbsp;below&nbsp;0.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); }</pre> </p> <p> Notice the Guard Clause: </p> <p> <pre><span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0)</pre> </p> <p> Image that we'd like to introduce some flexibility here. It's admittedly a silly example, but just come along for the edification. Imagine that we'd like to use an injected <code>ISpecification&lt;ProductInventory&gt;</code> instead: </p> <p> <pre><span style="color:#8f08c4;">if</span>&nbsp;(!specification.IsSatisfiedBy(productInventory))</pre> </p> <p> That doesn't sound too difficult, but what if you only have an <code>ISpecification</code> implementation like the following? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">NaturalNumber</span>&nbsp;:&nbsp;ISpecification&lt;<span style="color:blue;">int</span>&gt; { &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;ISpecification&lt;<span style="color:blue;">int</span>&gt;&nbsp;Specification&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;NaturalNumber(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:#2b91af;">NaturalNumber</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">candidate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;0&nbsp;&lt;=&nbsp;candidate; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> That's essentially what you need, but alas, it only implements <code>ISpecification&lt;int&gt;</code>, not <code>ISpecification&lt;ProductInventory&gt;</code>. Do you <em>really</em> have to write a new <a href="https://en.wikipedia.org/wiki/Adapter_pattern">Adapter</a> just to implement the right interface? </p> <p> No, you don't. </p> <h3 id="069f9ff7ee4d41dab4cf9243804dc873"> Contravariant functor <a href="#069f9ff7ee4d41dab4cf9243804dc873" title="permalink">#</a> </h3> <p> Fortunately, an interface like <code>ISpecification&lt;T&gt;</code> gives rise to a contravariant functor. This will enable you to compose an <code>ISpecification&lt;ProductInventory&gt;</code> object from the <code>NaturalNumber</code> specification. </p> <p> In order to enable contravariant mapping, you must add a <code>ContraMap</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ISpecification&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<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;ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;T&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;ContraSpecification&lt;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;">ContraSpecification</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;&nbsp;:&nbsp;ISpecification&lt;T1&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;ISpecification&lt;T&gt;&nbsp;source; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;selector; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ContraSpecification</span>(ISpecification&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>,&nbsp;Func&lt;T1,&nbsp;T&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;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">IsSatisfiedBy</span>(T1&nbsp;<span style="color:#1f377f;">candidate</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;source.IsSatisfiedBy(selector(candidate)); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Notice that, as explained in the overview article, in order to map from an <code>ISpecification&lt;T&gt;</code> to an <code>ISpecification&lt;T1&gt;</code>, the <code>selector</code> has to go the other way: from <code>T1</code> to <code>T</code>. How this is possible will become more apparent with an example, which will follow later in the article. </p> <h3 id="f3211a80973c4d85b63a564704e67028"> Identity law <a href="#f3211a80973c4d85b63a564704e67028" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for the <code>ISpecification&lt;T&gt;</code> interface. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the identity law: </p> <p> <pre>[Theory] [InlineData(-102)] [InlineData(&nbsp;&nbsp;-3)] [InlineData(&nbsp;&nbsp;-1)] [InlineData(&nbsp;&nbsp;&nbsp;0)] [InlineData(&nbsp;&nbsp;&nbsp;1)] [InlineData(&nbsp;&nbsp;32)] [InlineData(&nbsp;283)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityLaw</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;ISpecification&lt;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap&lt;<span style="color:blue;">int</span>,&nbsp;<span style="color:blue;">int</span>&gt;(id); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.IsSatisfiedBy(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;projection.IsSatisfiedBy(input)); }</pre> </p> <p> In order to observe that the two Specifications have identical behaviours, the test has to invoke <code>IsSatisfiedBy</code> on both of them to verify that the return values are the same. </p> <p> All test cases pass. </p> <h3 id="84d4761adecd427fbd9e463a05e8cc67"> Composition law <a href="#84d4761adecd427fbd9e463a05e8cc67" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;0:05&quot;</span>)] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;1:20&quot;</span>)] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;0:12:10&quot;</span>)] [InlineData(&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;1:00:12&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;1.13:14:34&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">CompositionLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">string</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;TimeSpan.Parse; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;TimeSpan,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;(<span style="color:blue;">int</span>)ts.TotalMinutes; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))).IsSatisfiedBy(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap(g).ContraMap(f).IsSatisfiedBy(input)); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to call <code>IsSatisfiedBy</code> on both compositions to verify that they return the same Boolean value. </p> <p> They do. </p> <h3 id="94ecc00ea3064f86b48c45d0e9627cc8"> Product inventory specification <a href="#94ecc00ea3064f86b48c45d0e9627cc8" title="permalink">#</a> </h3> <p> You can now produce the desired <code>ISpecification&lt;ProductInventory&gt;</code> from the <code>NaturalNumber</code> Specification without having to add a new class: </p> <p> <pre>ISpecification&lt;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">specification</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;NaturalNumber.Specification.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt;&nbsp;inv.Quantity);</pre> </p> <p> Granted, it is, once more, a silly example, but the purpose of this article isn't to convince you that this is better (it probably isn't). The purpose of the article is to show an example of a contravariant functor, and how it can be used. </p> <h3 id="376573ff36c64561b5fc231589f6922f"> Predicates <a href="#376573ff36c64561b5fc231589f6922f" title="permalink">#</a> </h3> <p> For good measure, any predicate forms a contravariant functor. You don't need the <code>ISpecification</code> interface. Here are <code>ContraMap</code> overloads for <code>Predicate&lt;T&gt;</code> and <code>Func&lt;T, bool&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Predicate&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;(<span style="color:blue;">this</span>&nbsp;Predicate&lt;T&gt;&nbsp;<span style="color:#1f377f;">predicate</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;predicate(selector(x)); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;T1,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;T,&nbsp;<span style="color:blue;">bool</span>&gt;&nbsp;<span style="color:#1f377f;">predicate</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;predicate(selector(x)); }</pre> </p> <p> Notice that the lambda expressions are identical in both implementations. </p> <h3 id="4c2e7471713547d5a24a20dacce49806"> Conclusion <a href="#4c2e7471713547d5a24a20dacce49806" title="permalink">#</a> </h3> <p> Like Command Handlers and Event Handlers, generic predicates give rise to a contravariant functor. This includes both the Specification pattern, <code>Predicate&lt;T&gt;</code>, and <code>Func&lt;T, bool&gt;</code>. </p> <p> Are you noticing a pattern? </p> <p> <strong>Next:</strong> <a href="/2021/09/27/the-equivalence-contravariant-functor">The Equivalence contravariant 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>. The Command Handler contravariant functor https://blog.ploeh.dk/2021/09/06/the-command-handler-contravariant-functor 2021-09-06T05:46:00+00:00 Mark Seemann <div id="post"> <p> <em>An introduction to the Command Handler contravariant functor for object-oriented programmers.</em> </p> <p> This article is an instalment in <a href="/2021/09/02/contravariant-functors">an article series about contravariant functors</a>. It assumes that you've read the introduction. </p> <p> Asynchronous software architectures, such as those described in <a href="http://bit.ly/eipatterns">Enterprise Integration Patterns</a>, often make good use of a pattern where <em>Commands</em> are (preferably immutable) <a href="https://en.wikipedia.org/wiki/Data_transfer_object">Data Transfer Objects</a> (DTOs) that are often placed on a persistent queue and later handled by a background process. </p> <p> Even if you don't use asynchronous processing, separating command data from command handling can be beneficial for your software's granular architecture. In perhaps his most remarkable contribution to <a href="/dippp">our book</a>, <a href="https://blogs.cuttingedge.it/steven">Steven van Deursen</a> describes how this pattern can greatly simplify how you deal with cross-cutting concerns. </p> <h3 id="3d338bea6fa74d149b239067a283967c"> Interface <a href="#3d338bea6fa74d149b239067a283967c" title="permalink">#</a> </h3> <p> In <a href="/dippp">DIPPP</a> the interface is called <code>ICommandService</code>, but in this article I'll instead call it <code>ICommandHandler</code>. It's a generic interface with a single method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">ICommandHandler</span>&lt;<span style="color:#2b91af;">TCommand</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(TCommand&nbsp;<span style="color:#1f377f;">command</span>); }</pre> </p> <p> The book explains how this interface enables you to gracefully handle cross-cutting concerns without any reflection magic. You can also peruse <a href="https://github.com/DependencyInjection-2nd-edition/codesamples">its example code base on GitHub</a>. In this article, however, I'm using <a href="https://github.com/ploeh/codesamples">a fork of that code</a> because I wanted to make the properties of contravariant functors stand out more clearly. </p> <p> In the sample code base, an ASP.NET Controller delegates work to an injected <code>ICommandHandler&lt;AdjustInventory&gt;</code> called <code>inventoryAdjuster</code>. </p> <p> <pre>[Route(<span style="color:#a31515;">&quot;inventory/adjustinventory&quot;</span>)] <span style="color:blue;">public</span>&nbsp;ActionResult&nbsp;<span style="color:#74531f;">AdjustInventory</span>(AdjustInventoryViewModel&nbsp;<span style="color:#1f377f;">viewModel</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!<span style="color:blue;">this</span>.ModelState.IsValid) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">this</span>.View(nameof(Index),&nbsp;<span style="color:blue;">this</span>.Populate(viewModel)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>&nbsp;=&nbsp;viewModel.Command; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.inventoryAdjuster.Execute(command); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.TempData[<span style="color:#a31515;">&quot;SuccessMessage&quot;</span>]&nbsp;=&nbsp;<span style="color:#a31515;">&quot;Inventory&nbsp;successfully&nbsp;adjusted.&quot;</span>; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">this</span>.RedirectToAction(nameof(HomeController.Index),&nbsp;<span style="color:#a31515;">&quot;Home&quot;</span>); }</pre> </p> <p> There's a single implementation of <code>ICommandHandler&lt;AdjustInventory&gt;</code>, which is a class called <code>AdjustInventoryService</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">AdjustInventoryService</span>&nbsp;:&nbsp;ICommandHandler&lt;AdjustInventory&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IInventoryRepository&nbsp;repository; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">AdjustInventoryService</span>(IInventoryRepository&nbsp;<span style="color:#1f377f;">repository</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(repository&nbsp;==&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(repository)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository&nbsp;=&nbsp;repository; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantityAdjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.AdjustQuantity(quantityAdjustment); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InvalidOperationException(<span style="color:#a31515;">&quot;Can&#39;t&nbsp;decrease&nbsp;below&nbsp;0.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The <code>Execute</code> method first loads the inventory data from the database, calculates how to adjust it, and saves it. This is all fine and good object-oriented design, and my intent with the present article isn't to point fingers at it. My intent is only to demonstrate how the <code>ICommandHandler</code> interface gives rise to a contravariant functor. </p> <p> I'm using this particular code base because it provides a good setting for a realistic example. </p> <h3 id="24bc8cde80ca4234b4eea11c7617a784"> Towards Domain-Driven Design <a href="#24bc8cde80ca4234b4eea11c7617a784" title="permalink">#</a> </h3> <p> Consider these two lines of code from <code>AdjustInventoryService</code>: </p> <p> <pre><span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantityAdjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); productInventory&nbsp;=&nbsp;productInventory.AdjustQuantity(quantityAdjustment);</pre> </p> <p> Doesn't that look like a case of <a href="https://wiki.c2.com/?FeatureEnvySmell">Feature Envy</a>? Doesn't this calculation belong better on another class? Which one? The <code>AdjustInventory</code> Command? That's one option, but in this style of architecture Commands are supposed to be dumb DTOs, so that may not be the best fit. <code>ProductInventory</code>? That may be more promising. </p> <p> Before making that change, however, let's consider the current state of the class. </p> <p> One of the changes I made in my fork of the code was to turn the <code>ProductInventory</code> class into an immutable <a href="https://martinfowler.com/bliki/ValueObject.html">Value Object</a>, as recommended in <a href="http://amzn.to/WBCwx7">DDD</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>)&nbsp;:&nbsp;<span style="color:blue;">this</span>(id,&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;quantity; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Guid&nbsp;Id&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">int</span>&nbsp;Quantity&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;ProductInventory&nbsp;<span style="color:#74531f;">WithQuantity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">newQuantity</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(Id,&nbsp;newQuantity); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;ProductInventory&nbsp;<span style="color:#74531f;">AdjustQuantity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">adjustment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;WithQuantity(Quantity&nbsp;+&nbsp;adjustment); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;ProductInventory&nbsp;<span style="color:#1f377f;">inventory</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Id.Equals(inventory.Id)&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;==&nbsp;inventory.Quantity; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(Id,&nbsp;Quantity); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> That looks like a lot of code, but keep in mind that <a href="/2018/09/17/typing-is-not-a-programming-bottleneck">typing isn't the bottleneck</a> - and besides, most of that code was written by various Visual Studio <em>Quick Actions</em>. </p> <p> Let's try to add a <code>Handle</code> method to <code>ProductInventory</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;ProductInventory&nbsp;<span style="color:#74531f;">Handle</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">adjustment</span>&nbsp;=&nbsp;command.Quantity&nbsp;*&nbsp;(command.Decrease&nbsp;?&nbsp;-1&nbsp;:&nbsp;1); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;AdjustQuantity(adjustment); }</pre> </p> <p> While <code>AdjustInventoryService</code> isn't too difficult to unit test, it still does require setting up and configuring some <a href="https://martinfowler.com/bliki/TestDouble.html">Test Doubles</a>. The new method, on the other hand, is actually a <a href="https://en.wikipedia.org/wiki/Pure_function">pure function</a>, which means that <a href="/2015/05/07/functional-design-is-intrinsically-testable">it's trivial to unit test</a>: </p> <p> <pre>[Theory] [InlineData(0,&nbsp;<span style="color:blue;">false</span>,&nbsp;0,&nbsp;0)] [InlineData(0,&nbsp;&nbsp;<span style="color:blue;">true</span>,&nbsp;0,&nbsp;0)] [InlineData(0,&nbsp;<span style="color:blue;">false</span>,&nbsp;1,&nbsp;1)] [InlineData(0,&nbsp;<span style="color:blue;">false</span>,&nbsp;2,&nbsp;2)] [InlineData(1,&nbsp;<span style="color:blue;">false</span>,&nbsp;1,&nbsp;2)] [InlineData(2,&nbsp;<span style="color:blue;">false</span>,&nbsp;3,&nbsp;5)] [InlineData(5,&nbsp;&nbsp;<span style="color:blue;">true</span>,&nbsp;2,&nbsp;3)] [InlineData(5,&nbsp;&nbsp;<span style="color:blue;">true</span>,&nbsp;5,&nbsp;0)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Handle</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">initial</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#1f377f;">decrease</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">adjustment</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">expected</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;ProductInventory(Guid.NewGuid(),&nbsp;initial); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">command</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;AdjustInventory &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProductId&nbsp;=&nbsp;sut.Id, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Decrease&nbsp;=&nbsp;decrease, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;adjustment &nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.Handle(command); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(sut.WithQuantity(expected),&nbsp;actual); }</pre> </p> <p> Now that the new function is available on <code>ProductInventory</code>, you can use it in <code>AdjustInventoryService</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.Handle(command); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(productInventory.Quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;InvalidOperationException(<span style="color:#a31515;">&quot;Can&#39;t&nbsp;decrease&nbsp;below&nbsp;0.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); }</pre> </p> <p> The <code>Execute</code> method now delegates its central logic to <code>ProductInventory.Handle</code>. </p> <h3 id="ee1b47388e1340a9ac8ced8eb3d7a181"> Encapsulation <a href="#ee1b47388e1340a9ac8ced8eb3d7a181" title="permalink">#</a> </h3> <p> If you consider the <code>Execute</code> method in its current incarnation, you may wonder why it checks whether the <code>Quantity</code> is negative. Shouldn't that be the responsibility of <code>ProductInventory</code>? Why do we even allow <code>ProductInventory</code> to enter an invalid state? </p> <p> This breaks encapsulation. Encapsulation is one of the most misunderstood concepts in programming, but as <a href="/encapsulation-and-solid">I explain in my PluralSight course</a>, as a minimum requirement, an object should not allow itself to be put into an invalid state. </p> <p> How to better encapsulate <code>ProductInventory</code>? Add a Guard Clause to the constructor: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ProductInventory</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>,&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">quantity</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(quantity&nbsp;&lt;&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentOutOfRangeException( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nameof(quantity), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;Negative&nbsp;quantity&nbsp;not&nbsp;allowed.&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Id&nbsp;=&nbsp;id; &nbsp;&nbsp;&nbsp;&nbsp;Quantity&nbsp;=&nbsp;quantity; }</pre> </p> <p> Again, such behaviour is trivial to drive with a unit test: </p> <p> <pre>[Theory] [InlineData(&nbsp;-1)] [InlineData(&nbsp;-2)] [InlineData(-19)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">SetNegativeQuantity</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">negative</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">id</span>&nbsp;=&nbsp;Guid.NewGuid(); &nbsp;&nbsp;&nbsp;&nbsp;Action&nbsp;<span style="color:#1f377f;">action</span>&nbsp;=&nbsp;()&nbsp;=&gt;&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(id,&nbsp;negative); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Throws&lt;ArgumentOutOfRangeException&gt;(action); }</pre> </p> <p> With those changes in place, <code>AdjustInventoryService</code> becomes even simpler: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.Handle(command); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory); }</pre> </p> <p> Perhaps even so simple that the class begins to seem unwarranted. </p> <h3 id="6f41a860c47741d7b2eb3b4b720d1d7f"> Sandwich <a href="#6f41a860c47741d7b2eb3b4b720d1d7f" title="permalink">#</a> </h3> <p> It's just a database Query, a single pure function call, and another database Command. In fact, it looks a lot like an <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId)</span> <span style="background-color: palegreen;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId); &nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;=&nbsp;productInventory.Handle(command);</span> <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory);</span> }</pre> </p> <p> In fact, it'd probably be more appropriate to move the null-handling closer to the other <a href="https://en.wikipedia.org/wiki/Referential_transparency">referentially transparent</a> code: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(AdjustInventory&nbsp;<span style="color:#1f377f;">command</span>) { <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">productInventory</span>&nbsp;=&nbsp;<span style="color:blue;">this</span>.repository.GetByIdOrNull(command.ProductId);</span> <span style="background-color: palegreen;">&nbsp;&nbsp;&nbsp;&nbsp;productInventory&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(productInventory&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command);</span> <span style="background-color: lightsalmon;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.repository.Save(productInventory);</span> }</pre> </p> <p> Why do we need the <code>AdjustInventoryService</code> class, again? </p> <p> Can't we move those three lines of code to the Controller? We could, but that might make testing the above <code>AdjustInventory</code> Controller action more difficult. After all, at the moment, the Controller has an injected <code>ICommandHandler&lt;AdjustInventory&gt;</code>, which is easy to replace with a Test Double. </p> <p> If only we could somehow <em>compose</em> an <code>ICommandHandler&lt;AdjustInventory&gt;</code> from the above sandwich <em>without having to define a class</em>... </p> <h3 id="535cefbfe8564f888f92fa4edd1fe7c8"> Contravariant functor <a href="#535cefbfe8564f888f92fa4edd1fe7c8" title="permalink">#</a> </h3> <p> Fortunately, an interface like <code>ICommandHandler&lt;T&gt;</code> gives rise to a contravariant functor. This will enable you to compose an <code>ICommandHandler&lt;AdjustInventory&gt;</code> object from the above constituent parts. </p> <p> In order to enable contravariant mapping, you must add a <code>ContraMap</code> method: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;ICommandHandler&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<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;ICommandHandler&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>, &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;Action&lt;T1&gt;&nbsp;<span style="color:#1f377f;">action</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;source.Execute(selector(x)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;T1&gt;(action); }</pre> </p> <p> Notice that, as explained in the overview article, in order to map from an <code>ICommandHandler&lt;T&gt;</code> to an <code>ICommandHandler&lt;T1&gt;</code>, the <code>selector</code> has to go the other way: from <code>T1</code> to <code>T</code>. How this is possible will become more apparent with an example, which will follow later in the article. </p> <p> The <code>ContraMap</code> method uses a <code>DelegatingCommandHandler</code> that wraps any <code>Action&lt;T&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">DelegatingCommandHandler</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;ICommandHandler&lt;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Action&lt;T&gt;&nbsp;action; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DelegatingCommandHandler</span>(Action&lt;T&gt;&nbsp;<span style="color:#1f377f;">action</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.action&nbsp;=&nbsp;action; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Execute</span>(T&nbsp;<span style="color:#1f377f;">command</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action(command); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> If you're now wondering whether <code>Action&lt;T&gt;</code> itself gives rise to a contravariant functor, then yes it does. </p> <h3 id="cab26cece052462890c8e04363a907ec"> Identity law <a href="#cab26cece052462890c8e04363a907ec" title="permalink">#</a> </h3> <p> A <code>ContraMap</code> method with the right signature isn't enough to be a contravariant functor. It must also obey the contravariant functor laws. As usual, it's proper computer-science work to actually prove this, but you can write some tests to demonstrate the identity law for the <code>ICommandHandler&lt;T&gt;</code> interface. In this article, you'll see parametrised tests written with <a href="https://xunit.net">xUnit.net</a>. First, the identity law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;baz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;qux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quuz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;grault&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;garply&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">IdentityLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">observations</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;List&lt;<span style="color:blue;">string</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;<span style="color:blue;">string</span>&gt;(observations.Add); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection</span>&nbsp;=&nbsp;sut.ContraMap&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>&gt;(id); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Run&nbsp;both&nbsp;handlers</span> &nbsp;&nbsp;&nbsp;&nbsp;sut.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;projection.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(2,&nbsp;observations.Count); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Single(observations.Distinct()); }</pre> </p> <p> In order to observe that the two handlers have identical behaviours, the test has to <code>Execute</code> both of them to verify that both observations are the same. </p> <p> All test cases pass. </p> <h3 id="b4000e7978f949d8817590b0779d0afe"> Composition law <a href="#b4000e7978f949d8817590b0779d0afe" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that <code>ContraMap</code> obeys the composition law for contravariant functors: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;baz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;qux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quux&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;quuz&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;grault&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;garply&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">CompositionLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">observations</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;List&lt;TimeSpan&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;TimeSpan&gt;(observations.Add); &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;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;TimeSpan.FromDays(i); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection1</span>&nbsp;=&nbsp;sut.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))); &nbsp;&nbsp;&nbsp;&nbsp;ICommandHandler&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">projection2</span>&nbsp;=&nbsp;sut.ContraMap(g).ContraMap(f); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Run&nbsp;both&nbsp;handlers</span> &nbsp;&nbsp;&nbsp;&nbsp;projection1.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;projection2.Execute(input); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(2,&nbsp;observations.Count); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Single(observations.Distinct()); }</pre> </p> <p> This test defines two local functions, <code>f</code> and <code>g</code>. Once more, you can't directly compare methods for equality, so instead you have to <code>Execute</code> them to verify that they produce the same observable effect. </p> <p> They do. </p> <h3 id="a068d2c54eda4315a4c592aa30b998f4"> Composed inventory adjustment handler <a href="#a068d2c54eda4315a4c592aa30b998f4" title="permalink">#</a> </h3> <p> We can now return to the inventory adjustment example. You may recall that the Controller would <code>Execute</code> a <code>command</code> on an injected <code>ICommandHandler&lt;AdjustInventory&gt;</code>: </p> <p> <pre><span style="color:blue;">this</span>.inventoryAdjuster.Execute(command);</pre> </p> <p> As a first step, we can attempt to compose <code>inventoryAdjuster</code> on the fly: </p> <p> <pre>ICommandHandler&lt;AdjustInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((AdjustInventory&nbsp;<span style="color:#1f377f;">cmd</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repository.GetByIdOrNull(cmd.ProductId)); inventoryAdjuster.Execute(command);</pre> </p> <p> Contra-mapping is hard to get one's head around, and to make matters worse, you have to read it from the bottom towards the top to understand what it does. It really is contrarian. </p> <p> How do you arrive at something like this? </p> <p> You start by looking at what you have. The Controller may already have an injected <code>repository</code> with various methods. <code>repository.Save</code>, for example, has this signature: </p> <p> <pre><span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Save</span>(ProductInventory&nbsp;<span style="color:#1f377f;">productInventory</span>);</pre> </p> <p> Since it has a <code>void</code> return type, you can treat <code>repository.Save</code> as an <code>Action&lt;ProductInventory&gt;</code>. Wrap it in a <code>DelegatingCommandHandler</code> and you have an <code>ICommandHandler&lt;ProductInventory&gt;</code>: </p> <p> <pre>ICommandHandler&lt;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save);</pre> </p> <p> That's not what you need, though. You need an <code>ICommandHandler&lt;AdjustInventory&gt;</code>. How do you get closer to that? </p> <p> You already know from the <code>AdjustInventoryService</code> class that you can use a pure function as the core of the impureim sandwich. Try that and see what it gives you: </p> <p> <pre>ICommandHandler&lt;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command));</pre> </p> <p> That doesn't change the type of the handler, but implements the desired functionality. </p> <p> You have an <code>ICommandHandler&lt;ProductInventory&gt;</code> that you need to somehow map to an <code>ICommandHandler&lt;AdjustInventory&gt;</code>. How do you do that? </p> <p> By supplying a function that goes the other way: from <code>AdjustInventory</code> to <code>ProductInventory</code>. Does such a method exist? Yes, it does, on the repository: </p> <p> <pre>ProductInventory&nbsp;<span style="color:#74531f;">GetByIdOrNull</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>);</pre> </p> <p> Or, close enough. While <code>AdjustInventory</code> is not a <code>Guid</code>, it <em>comes with</em> a <code>Guid</code>: </p> <p> <pre>ICommandHandler&lt;AdjustInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ProductInventory&nbsp;<span style="color:#1f377f;">inv</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((AdjustInventory&nbsp;<span style="color:#1f377f;">cmd</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repository.GetByIdOrNull(cmd.ProductId));</pre> </p> <p> That's cool, but unfortunately, this composition cheats. It closes over <code>command</code>, which is a run-time variable only available inside the <code>AdjustInventory</code> Controller action. </p> <p> If we're allowed to compose the Command Handler <em>inside</em> the <code>AdjustInventory</code> method, we might as well just have written: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">inv</span>&nbsp;=&nbsp;repository.GetByIdOrNull(command.ProductId); inv&nbsp;=&nbsp;(inv&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(command.ProductId)).Handle(command); repository.Save(inv);</pre> </p> <p> This is clearly much simpler, so why don't we do that? </p> <p> In this particular example, that's probably a better idea overall, but I'm trying to explain what is possible with contravariant functors. The goal here is to decouple the caller (the Controller) from the handler. We want to be able to define the handler outside of the Controller action. </p> <p> That's what the <code>AdjustInventory</code> class does, but can we leverage the contravariant functor to compose an <code>ICommandHandler&lt;AdjustInventory&gt;</code> <em>without</em> adding a new class? </p> <h3 id="01c3971cdf1d43ca8fd5db6005477304"> Composition without closures <a href="#01c3971cdf1d43ca8fd5db6005477304" title="permalink">#</a> </h3> <p> The use of a closure in the above composition is what disqualifies it. Is it possible to compose an <code>ICommandHandler&lt;AdjustInventory&gt;</code> when the <code>command</code> object is unavailable to close over? </p> <p> Yes, but it isn't pretty: </p> <p> <pre>ICommandHandler&lt;AdjustInventory&gt;&nbsp;<span style="color:#1f377f;">inventoryAdjuster</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;DelegatingCommandHandler&lt;ProductInventory&gt;(repository.Save) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((ValueTuple&lt;AdjustInventory,&nbsp;ProductInventory&gt;&nbsp;<span style="color:#1f377f;">t</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(t.Item2&nbsp;??&nbsp;<span style="color:blue;">new</span>&nbsp;ProductInventory(t.Item1.ProductId)).Handle(t.Item1)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ContraMap((AdjustInventory&nbsp;<span style="color:#1f377f;">cmd</span>)&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cmd,&nbsp;repository.GetByIdOrNull(cmd.ProductId)));</pre> </p> <p> You can let the composing function return a tuple of the original input value <em>and</em> the projected value. That's what the lowest <code>ContraMap</code> does. This means that the upper <code>ContraMap</code> receives this tuple to map. Not pretty, but possible. </p> <p> I never said that this was the <em>best</em> way to address some of the concerns I've hinted at in this article. The purpose of the article was mainly to give you a sense of what a contravariant functor can do. </p> <h3 id="0a960dd6e8f24121a5b9229b9cca1e7a"> Action as a contravariant functor <a href="#0a960dd6e8f24121a5b9229b9cca1e7a" title="permalink">#</a> </h3> <p> Wrapping an <code>Action&lt;T&gt;</code> in a <code>DelegatingCommandHandler</code> isn't necessary in order to form the contravariant functor. I only used the <code>ICommandHandler</code> interface as an object-oriented-friendly introduction to the example. In fact, any <code>Action&lt;T&gt;</code> gives rise to a contravariant functor with this <code>ContraMap</code> function: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Action&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">T1</span>&gt;(<span style="color:blue;">this</span>&nbsp;Action&lt;T&gt;&nbsp;<span style="color:#1f377f;">source</span>,&nbsp;Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;source(selector(x)); }</pre> </p> <p> As you can tell, the function being returned is similar to the lambda expression used to implement <code>ContraMap</code> for <code>ICommandHandler&lt;T&gt;</code>. </p> <p> This turns out to make little difference in the context of the examples shown here, so I'm not going to tire you with more example code. </p> <h3 id="9c7dc6d88a164a0b8bd7ac06eea22dc4"> Conclusion <a href="#9c7dc6d88a164a0b8bd7ac06eea22dc4" title="permalink">#</a> </h3> <p> Any generic polymorphic interface or abstract method with a <code>void</code> return type gives rise to a contravariant functor. This includes the <code>ICommandHandler&lt;T&gt;</code> (originally <code>ICommandService&lt;T&gt;</code>) interface, but also another interface discussed in <a href="/dippp">DIPPP</a>: <code>IEventHandler&lt;TEvent&gt;</code>. </p> <p> The utility of this insight may not be immediately apparent. Contrary to its built-in support for functors, C# doesn't have any language features that light up if you implement a <code>ContraMap</code> function. Even in <a href="https://www.haskell.org">Haskell</a> where <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">the Contravariant functor is available in the <em>base</em> library</a>, I can't recall having ever used it. </p> <p> Still, even if not a <em>practical</em> insight, the ubiquitous presence of contravariant functors in everyday programming 'building blocks' tells us something profound about the fabric of programming abstraction and polymorphism. </p> <p> <strong>Next:</strong> <a href="/2021/09/09/the-specification-contravariant-functor">The Specification contravariant 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>. Contravariant functors https://blog.ploeh.dk/2021/09/02/contravariant-functors 2021-09-02T06:49:00+00:00 Mark Seemann <div id="post"> <p> <em>A more exotic kind of universal abstraction.</em> </p> <p> This article series is part of <a href="/2018/03/19/functors-applicatives-and-friends">a larger series of articles about functors, applicatives, and other mappable containers</a>. </p> <p> So far in the article series, you've seen examples of mappable containers that map in the same direction of projections, so to speak. Let's unpack that. </p> <h3 id="272009219c12482cba296186e0e0a645"> Covariance recap <a href="#272009219c12482cba296186e0e0a645" title="permalink">#</a> </h3> <p> <a href="/2018/03/22/functors">Functors</a>, <a href="/2018/10/01/applicative-functors">applicative functors</a>, and <a href="/2018/12/24/bifunctors">bifunctors</a> all follow the direction of projections. Consider the illustration from <a href="/2018/03/22/functors">the article about functors</a>: </p> <p> <img src="/content/binary/functor-diagram.png" alt="Functor diagram."> </p> <p> The function <code>f</code> maps from <code>a</code> to <code>b</code>. You can think of <code>a</code> and <code>b</code> as two types, or two sets. For example, if <code>a</code> is the set of all strings, it might correspond to the type <code>String</code>. Likewise, if <code>b</code> is the set of all integers, then it corresponds to a type called <code>Int</code>. The function <code>f</code> would, in that case, have the type <code>String -&gt; Int</code>; that is: it maps strings to integers. The most natural such function seems to be one that counts the number of characters in a string: </p> <p> <pre>&gt; f = length &gt; f "foo" 3 &gt; f "ploeh" 5</pre> </p> <p> This little interactive session uses <a href="https://www.haskell.org">Haskell</a>, but even if you've never heard about Haskell before, you should still be able to understand what's going on. </p> <p> A functor is a <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers">container</a> of values, for example a collection, a <a href="/2018/03/26/the-maybe-functor">Maybe</a>, a <a href="/2018/09/10/the-lazy-functor">lazy computation</a>, or many other things. If <code>f</code> maps from <code>a</code> to <code>b</code>, then lifting it to the functor <code>F</code> retains the direction. That's what the above figure illustrates. Not only does the functor project <code>a</code> to <code>F a</code> and <code>b</code> to <code>F b</code>, it also maps <code>f</code> to <code>F f</code>, which is <code>F a -&gt; F b</code>. </p> <p> For lists it might look like this: </p> <p> <pre>&gt; fmap f ["bar", "fnaah", "Gauguin"] [3,5,7]</pre> </p> <p> Here <code>fmap</code> lifts the function <code>String -&gt; Int</code> to <code>[String] -&gt; [Int]</code>. Notice that the types 'go in the same direction' when you lift a function to the functor. The types vary <em>with</em> the function - they <em>co</em>-vary; hence <em>covariance</em>. </p> <p> While applicative functors and bifunctors are more complex, they are still covariant. Consult, for example, the diagrams in my <a href="/2018/12/24/bifunctors">bifunctor article</a> to get an intuitive sense that this still holds. </p> <h3 id="187c2160ddf94c119c341534189d3eab"> Contravariance <a href="#187c2160ddf94c119c341534189d3eab" title="permalink">#</a> </h3> <p> What happens if we change the direction of <em>only one</em> arrow? For example, we could change the direction of the <code>f</code> arrow, so that the function is now a function from <code>b</code> to <code>a</code>: <code>b -&gt; a</code>. The figure would look like this: </p> <p> <img src="/content/binary/contravariant-functor-diagram.png" alt="Contravariant functor diagram."> </p> <p> This looks <em>almost</em> like the first figure, with one crucial difference: The lower arrow now goes from right to left. Notice that the upper arrow still goes from left to right: <code>F a -&gt; F b</code>. In other words, the functor varies in the contrary direction than the projected function. It's <em>contravariant</em>. </p> <p> This seems really odd. Why would anyone do that? </p> <p> As is so often the case with universal abstractions, it's not so much a question of coming up with an odd concept and see what comes of it. It's actually an abstract description of some common programming constructs. In this series of articles, you'll see examples of some contravariant functors: </p> <ul> <li><a href="/2021/09/06/the-command-handler-contravariant-functor">The Command Handler contravariant functor</a></li> <li><a href="/2021/09/09/the-specification-contravariant-functor">The Specification contravariant functor</a></li> <li><a href="/2021/09/27/the-equivalence-contravariant-functor">The Equivalence contravariant functor</a></li> <li><a href="/2021/10/04/reader-as-a-contravariant-functor">Reader as a contravariant functor</a></li> <li>Functor variance compared to C#'s notion of variance</li> </ul> <p> These aren't the only examples, but they should be enough to get the point across. Other examples include equivalence and comparison. </p> <h3 id="b7b1780cc7a74ffaace2a42f06301561"> Lifting <a href="#b7b1780cc7a74ffaace2a42f06301561" title="permalink">#</a> </h3> <p> How do you lift a function <code>f</code> to a contravariant functor? For covariant functors (normally just called <em>functors</em>), Haskell has the <code>fmap</code> function, while in C# you'd be writing a family of <code>Select</code> methods. Let's compare. In Haskell, <code>fmap</code> has this type: </p> <p> <pre>fmap :: Functor f =&gt; (a -&gt; b) -&gt; f a -&gt; f b</pre> </p> <p> You can read it like this: For any <code>Functor f</code>, <code>fmap</code> lifts a function of the type <code>a -&gt; b</code> to a function of the type <code>f a -&gt; f b</code>. Another way to read this is that given a function <code>a -&gt; b</code> and a container of type <code>f a</code>, you can produce a container of type <code>f b</code>. Due to <a href="https://en.wikipedia.org/wiki/Currying">currying</a>, these two interpretations are both correct. </p> <p> In C#, you'd be writing a <a href="/2018/03/22/functors">method on <code>Functor&lt;T&gt;</code> that looks like this</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Functor</span>&lt;<span style="color:#2b91af;">TResult</span>&gt;&nbsp;Select&lt;<span style="color:#2b91af;">TResult</span>&gt;(<span style="color:#2b91af;">Func</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;&nbsp;selector)</pre> </p> <p> This fits the later interpretation of <code>fmap</code>: Given an instance of <code>Functor&lt;T&gt;</code>, you can call <code>Select</code> with a <code>Func&lt;T, TResult&gt;</code> to produce a <code>Functor&lt;TResult&gt;</code>. </p> <p> What does the equivalent function look like for contravariant functors? Haskell <a href="https://hackage.haskell.org/package/base/docs/Data-Functor-Contravariant.html">defines it</a> as: </p> <p> <pre>contramap :: Contravariant f =&gt; (b -&gt; a) -&gt; f a -&gt; f b</pre> </p> <p> You can read it like this: For any <code>Contravariant</code> functor <code>f</code>, <code>contramap</code> lifts a function <code>(b -&gt; a)</code> to a function from <code>f a</code> to <code>f b</code>. Or, in the alternative (but equally valid) interpretation that matches C# better, given a function <code>(b -&gt; a)</code> and an <code>f a</code>, you can produce an <code>f b</code>. </p> <p> In C#, you'd be writing a method on <code>Contravariant&lt;T&gt;</code> that looks like this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Contravariant&lt;T1&gt;&nbsp;<span style="color:#74531f;">ContraMap</span>&lt;<span style="color:#2b91af;">T1</span>&gt;(Func&lt;T1,&nbsp;T&gt;&nbsp;<span style="color:#1f377f;">selector</span>)</pre> </p> <p> The actual generic type (here exemplified by <code>Contravariant&lt;T&gt;</code>) will differ, but the shape of the method will be the same. In order to map from <code>Contravariant&lt;T&gt;</code> to <code>Contravariant&lt;T1&gt;</code>, you need a function that <em>goes the other way</em>: <code>Func&lt;T1, T&gt;</code> goes from <code>T1</code> to <code>T</code>. </p> <p> In C#, the function name doesn't have to be <code>ContraMap</code>, since C# doesn't have any built-in understanding of contravariant functors - as opposed to functors, where a method called <code>Select</code> will light up some language features. In this article series I'll stick with <code>ContraMap</code> since I couldn't think of a better name. </p> <h3 id="72905e6e48a343e1bf78deae36be0abf"> Laws <a href="#72905e6e48a343e1bf78deae36be0abf" title="permalink">#</a> </h3> <p> Like functors, applicative functors, <a href="/2017/10/06/monoids">monoids</a>, and other universal abstractions, contravariant functors are characterised by simple laws. The contravariant functor laws are equivalent to the (covariant) <a href="/2018/03/22/functors">functor laws</a>: <em>identity</em> and <em>composition</em>. </p> <p> In pseudo-Haskell, we can express the <em>identity</em> law as: </p> <p> <pre>contramap id = id</pre> </p> <p> and the <em>composition</em> law as: </p> <p> <pre>contramap (g . f) = contramap f . contramap g</pre> </p> <p> The <em>identity</em> law is equivalent to the first functor law. It states that mapping a contravariant functor with the identity function is equivalent to a no-op. The <em>identity function</em> is a function that returns all input unchanged. (It's called the <em>identity function</em> because it's the <em>identity</em> for the <a href="/2017/11/13/endomorphism-monoid">endomorphism monoid</a>.) In <a href="https://fsharp.org">F#</a> and Haskell, this is simply a built-in function called <code>id</code>. </p> <p> In C#, you can write a demonstration of the law as a unit test. Here's the essential part of such a test: </p> <p> <pre>Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">id</span>&nbsp;=&nbsp;<span style="color:#1f377f;">x</span>&nbsp;=&gt;&nbsp;x; Contravariant&lt;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;createContravariant(); Assert.Equal(sut,&nbsp;sut.ContraMap(id),&nbsp;comparer);</pre> </p> <p> The <code>ContraMap</code> method <em>does</em> return a new object, so a custom <code>comparer</code> is required to evaluate whether <code>sut</code> is equal to <code>sut.ContraMap(id)</code>. </p> <p> The <em>composition</em> law governs how composition works. Again, notice how lifting reverses the order of functions. In C#, the relevant unit test code might look like this: </p> <p> <pre>Func&lt;<span style="color:blue;">string</span>,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; Func&lt;<span style="color:blue;">int</span>,&nbsp;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;TimeSpan.FromDays(i); Contravariant&lt;TimeSpan&gt;&nbsp;<span style="color:#1f377f;">sut</span>&nbsp;=&nbsp;createContravariant(); Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;sut.ContraMap((<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">s</span>)&nbsp;=&gt;&nbsp;g(f(s))), &nbsp;&nbsp;&nbsp;&nbsp;sut.ContraMap(g).ContraMap(f), &nbsp;&nbsp;&nbsp;&nbsp;comparer);</pre> </p> <p> This may actually look less surprising in C# than it does in Haskell. Here the lifted composition doesn't look reversed, but that's because C# doesn't have a composition operator for raw functions, so I instead wrote it as a lambda expression: <code>(string&nbsp;s)&nbsp;=&gt;&nbsp;g(f(s))</code>. If you contrast this C# example with the equivalent assertion of the (covariant) second functor law, you can see that the function order is flipped: <code>f(g(i))</code>. </p> <p> <pre><span style="color:#2b91af;">Assert</span>.Equal(sut.Select(g).Select(f),&nbsp;sut.Select(i&nbsp;=&gt;&nbsp;f(g(i))));</pre> </p> <p> It can be difficult to get your head around the order of contravariant composition without some examples. I'll provide examples in the following articles, but I wanted to leave the definition of the two contravariant functor laws here for reference. </p> <h3 id="68b342bda0ff41f5aec6fb7c08b299d3"> Conclusion <a href="#68b342bda0ff41f5aec6fb7c08b299d3" title="permalink">#</a> </h3> <p> Contravariant functors are functors that map in the opposite direction of an underlying function. This seems counter-intuitive but describes the actual behaviour of quite normal functions. </p> <p> This is hardly illuminating without some examples, so without further ado, let's proceed to the first one. </p> <p> <strong>Next:</strong> <a href="/2021/09/06/the-command-handler-contravariant-functor">The Command Handler contravariant 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>. The Reader functor https://blog.ploeh.dk/2021/08/30/the-reader-functor 2021-08-30T05:42:00+00:00 Mark Seemann <div id="post"> <p> <em>Normal functions form functors. An article 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, for example, how to implement the Maybe functor in C#. In this article, you'll see another functor example: <em>Reader</em>. </p> <p> The Reader functor is similar to the <a href="/2018/09/03/the-identity-functor">Identity functor</a> in the sense that it seems practically useless. If that's the case, then why care about it? </p> <p> As I wrote about the Identity functor: </p> <blockquote> "The inutility of Identity doesn't mean that it doesn't exist. The Identity functor exists, whether it's useful or not. You can ignore it, but it still exists. In C# or <a href="https://fsharp.org">F#</a> I've never had any use for it (although I've <a href="/2017/09/04/builder-as-identity">described it before</a>), while it turns out to be occasionally useful in <a href="https://www.haskell.org">Haskell</a>, where it's built-in. The value of Identity is language-dependent." </blockquote> <p> The same holds for Reader. It exists. Furthermore, it teaches us something important about ordinary functions. </p> <h3 id="1539ecc9bc504aa1a0cc090255777b1d"> Reader interface <a href="#1539ecc9bc504aa1a0cc090255777b1d" title="permalink">#</a> </h3> <p> Imagine the following interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReader</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;<span style="color:#74531f;">Run</span>(R&nbsp;<span style="color:#1f377f;">environment</span>); }</pre> </p> <p> An <code>IReader</code> object can produce a value of the type <code>A</code> when given a value of the type <code>R</code>. The input is typically called the <code>environment</code>. A Reader reads the environment and produces a value. A possible (although not particularly useful) implementation might be: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">GuidToStringReader</span>&nbsp;:&nbsp;IReader&lt;Guid,&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;format; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">GuidToStringReader</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">format</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.format&nbsp;=&nbsp;format; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#74531f;">Run</span>(Guid&nbsp;<span style="color:#1f377f;">environment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;environment.ToString(format); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This may be a silly example, but it illustrates that a a simple class can implement a constructed version of the interface: <code>IReader&lt;Guid,&nbsp;string&gt;</code>. It also demonstrates that a class can take further arguments via its constructor. </p> <p> While the <code>IReader</code> interface only takes a single input argument, <a href="/2018/01/29/argument-list-isomorphisms">we know that an argument list is isomorphic to a parameter object or tuple</a>. Thus, <code>IReader</code> is equivalent to <em>every</em> possible function type - up to isomorphism, assuming that <a href="/2018/01/15/unit-isomorphisms">unit is also a value</a>. </p> <p> While the practical utility of the Reader functor may not be immediately apparent, it's hard to argue that it isn't ubiquitous. Every method is (with a bit of hand-waving) a Reader. </p> <h3 id="23b5c83bffef42a0ab0c95919fef0166"> Functor <a href="#23b5c83bffef42a0ab0c95919fef0166" title="permalink">#</a> </h3> <p> You can turn the <code>IReader</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;IReader&lt;R,&nbsp;B&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>,&nbsp;<span style="color:#2b91af;">R</span>&gt;(<span style="color:blue;">this</span>&nbsp;IReader&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">reader</span>,&nbsp;Func&lt;A,&nbsp;B&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;FuncReader&lt;R,&nbsp;B&gt;(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;selector(reader.Run(r))); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">FuncReader</span>&lt;<span style="color:#2b91af;">R</span>,&nbsp;<span style="color:#2b91af;">A</span>&gt;&nbsp;:&nbsp;IReader&lt;R,&nbsp;A&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;Func&lt;R,&nbsp;A&gt;&nbsp;func; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">FuncReader</span>(Func&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">func</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.func&nbsp;=&nbsp;func; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;A&nbsp;<span style="color:#74531f;">Run</span>(R&nbsp;<span style="color:#1f377f;">environment</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;func(environment); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The implementation of <code>Select</code> requires a private class to capture the projected function. <code>FuncReader</code> is, however, an implementation detail. </p> <p> When you <code>Run</code> a Reader, the output is a value of the type <code>A</code>, and since <code>selector</code> is a function that takes an <code>A</code> value as input, you can use the output of <code>Run</code> as input to <code>selector</code>. Thus, the return type of the lambda expression <code>r =&gt; selector(reader.Run(r))</code> is <code>B</code>. Therefore, <code>Select</code> returns an <code>IReader&lt;R, B&gt;</code>. </p> <p> Here's an example of using the <code>Select</code> method to project an <code>IReader&lt;Guid, string&gt;</code> to <code>IReader&lt;Guid, 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;">WrappedFunctorExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;Guid,&nbsp;<span style="color:blue;">string</span>&gt;&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;GuidToStringReader(<span style="color:#a31515;">&quot;N&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;IReader&lt;Guid,&nbsp;<span style="color:blue;">int</span>&gt;&nbsp;<span style="color:#1f377f;">projected</span>&nbsp;=&nbsp;r.Select(<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Count(<span style="color:#1f377f;">c</span>&nbsp;=&gt;&nbsp;c.IsDigit())); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">input</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Guid(<span style="color:#a31515;">&quot;{CAB5397D-3CF9-40BB-8CBD-B3243B7FDC23}&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(16,&nbsp;projected.Run(input)); }</pre> </p> <p> The expected result is <code>16</code> because the <code>input</code> <code>Guid</code> contains 16 digits (the numbers from 0 to 9). Count them if you don't believe me. </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;">QuerySyntaxFunctorExample</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">projected</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:blue;">new</span>&nbsp;GuidToStringReader(<span style="color:#a31515;">&quot;N&quot;</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;TimeSpan.FromMinutes(s.Length); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">input</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Guid(<span style="color:#a31515;">&quot;{FE2AB9C6-DDB1-466C-8AAA-C70E02F964B9}&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(32,&nbsp;projected.Run(input).TotalMinutes); }</pre> </p> <p> The actual computation shown here makes little sense, since the result will always be <code>32</code>, but it illustrates that arbitrary projections are possible. </p> <h3 id="ad9b3abef16c4ec8a70a1263c17eecd6"> Raw functions <a href="#ad9b3abef16c4ec8a70a1263c17eecd6" title="permalink">#</a> </h3> <p> The <code>IReader&lt;R, A&gt;</code> interface isn't really necessary. It was just meant as an introduction to make things a bit easier for object-oriented programmers. You can write a similar <code>Select</code> extension method for any <code>Func&lt;R, A&gt;</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;Func&lt;R,&nbsp;B&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">A</span>,&nbsp;<span style="color:#2b91af;">B</span>,&nbsp;<span style="color:#2b91af;">R</span>&gt;(<span style="color:blue;">this</span>&nbsp;Func&lt;R,&nbsp;A&gt;&nbsp;<span style="color:#1f377f;">func</span>,&nbsp;Func&lt;A,&nbsp;B&gt;&nbsp;<span style="color:#1f377f;">selector</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;selector(func(r)); }</pre> </p> <p> Compare this implementation to the one above. It's essentially the same lambda expression, but now <code>Select</code> returns the raw function instead of wrapping it in a class. </p> <p> In the following, I'll use raw functions instead of the <code>IReader</code> interface. </p> <h3 id="de5e5a6801ab49d4ae993181a05f7bab"> First functor law <a href="#de5e5a6801ab49d4ae993181a05f7bab" 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>IReader&lt;R, A&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(<span style="color:#a31515;">&quot;&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;antidisestablishmentarianism&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">FirstFunctorLaw</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">input</span>) { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">id</span>&lt;<span style="color:#2b91af;">T</span>&gt;(T&nbsp;<span style="color:#1f377f;">x</span>)&nbsp;=&gt;&nbsp;x; &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;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.Length; &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;">actual</span>&nbsp;=&nbsp;f.Select(id); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(f(input),&nbsp;actual(input)); }</pre> </p> <p> The 'original' Reader <code>f</code> (for <em>function</em>) takes a <code>string</code> as input and returns its length. The <code>id</code> function (which isn't built-in in C#) is implemented as a <a href="https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/local-functions">local function</a>. It returns whichever input it's given. </p> <p> Since <code>id</code> returns any input without modifying it, it'll also return any number produced by <code>f</code> without modification. </p> <p> To evaluate whether <code>f</code> is equal to <code>f.Select(id)</code>, the assertion calls both functions with the same input. If the functions have equal behaviour, they ought to return the same output. </p> <p> The above test cases all pass. </p> <h3 id="1dc17b41888b420d8b8161f9ef9fb84c"> Second functor law <a href="#1dc17b41888b420d8b8161f9ef9fb84c" title="permalink">#</a> </h3> <p> Like the above example, you can also write a parametrised test that demonstrates that a function (Reader) obeys the second functor law: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;foo&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;bar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;corge&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;antidisestablishmentarianism&quot;</span>)] <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;">input</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;">h</span>&nbsp;=&nbsp;<span style="color:#1f377f;">s</span>&nbsp;=&gt;&nbsp;s.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;">g</span>&nbsp;=&nbsp;<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;i&nbsp;%&nbsp;2&nbsp;==&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;Func&lt;<span style="color:blue;">bool</span>,&nbsp;<span style="color:blue;">char</span>&gt;&nbsp;<span style="color:#1f377f;">f</span>&nbsp;=&nbsp;<span style="color:#1f377f;">b</span>&nbsp;=&gt;&nbsp;b&nbsp;?&nbsp;<span style="color:#a31515;">&#39;t&#39;</span>&nbsp;:&nbsp;<span style="color:#a31515;">&#39;f&#39;</span>; &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.Select(g).Select(f)(input), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h.Select(<span style="color:#1f377f;">i</span>&nbsp;=&gt;&nbsp;f(g(i)))(input)); }</pre> </p> <p> You can't easily compare two different functions for equality, so, like above, this test defines equality as the functions producing the same result when you invoke them. </p> <p> Again, while the test doesn't <em>prove</em> anything, it demonstrates that for the five test cases, it doesn't matter if you project the 'original' Reader <code>h</code> in one or two steps. </p> <h3 id="76a34d3dfde1438abd080f02499bc344"> Haskell <a href="#76a34d3dfde1438abd080f02499bc344" title="permalink">#</a> </h3> <p> In Haskell, normal functions <code>a -&gt; b</code> are already <code>Functor</code> instances, which means that you can easily replicate the functions from the <code>SecondFunctorLaw</code> test: </p> <p> <pre>&gt; h = length &gt; g i = i `mod` 2 == 0 &gt; f b = if b then 't' else 'f' &gt; (fmap f $ fmap g $ h) "ploeh" 'f'</pre> </p> <p> Here <code>f</code>, <code>g</code>, and <code>h</code> are equivalent to their above C# namesakes, while the last line composes the functions stepwise and calls the composition with the input string <code>"ploeh"</code>. In Haskell you generally read code from right to left, so this composition corresponds to <code>h.Select(g).Select(f)</code>. </p> <h3 id="9d3006be0e904994b2285ae791fd287a"> Conclusion <a href="#9d3006be0e904994b2285ae791fd287a" title="permalink">#</a> </h3> <p> Functions give rise to functors, usually known collectively as the Reader functor. Even in Haskell where this fact is ingrained into the fabric of the language, I rarely make use of it. It just is. In C#, it's likely to be even less useful for practical programming purposes. </p> <p> That a function <code>a -&gt; b</code> forms a functor, however, is an important insight into just what a function actually is. It describes an essential property of functions. In itself this may still seem underwhelming, but mixed with some other properties (that I'll describe in <a href="/2021/10/04/reader-as-a-contravariant-functor">a future article</a>) it can produce some profound insights. So stay tuned. </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>. Am I stuck in a local maximum? https://blog.ploeh.dk/2021/08/09/am-i-stuck-in-a-local-maximum 2021-08-09T05:56:00+00:00 Mark Seemann <div id="post"> <p> <em>On long-standing controversies, biases, and failures of communication.</em> </p> <p> If you can stay out of politics, Twitter can be a great place to engage in robust discussions. I mostly follow and engage with people in the programming community, and every so often find myself involved in a discussion about one of several long-standing controversies. No, not the tabs-versus-spaces debate, but other debates such as functional versus object-oriented programming, dynamic versus static typing, or <a href="/2020/03/16/conways-law-latency-versus-throughput">oral versus written collaboration</a>. </p> <p> It happened again the past week, but while this article is a reaction, it's not about the specific debacle. Thus, I'm not going to link to the tweets in question. </p> <p> These discussion usually leave me wondering why people with decades of industry experience seem to have such profound disagreements. </p> <h3 id="13c8dc8fbc9b4e26ba08bfeef9b61fd9"> I might be wrong <a href="#13c8dc8fbc9b4e26ba08bfeef9b61fd9" title="permalink">#</a> </h3> <p> Increasingly, I find myself disagreeing with my heroes. This isn't a comfortable position. Could I be wrong? </p> <p> I've definitely been wrong before. For example, in my article <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a>, I wrote about type systems: </p> <blockquote> <p>"To the far right, we have a hypothetical language with such a strong type system that, indeed, <em>if it compiles, it works.</em>"</p> </blockquote> <p> <em>To the right</em>, in this context, means <em>more statically typed</em>. While the notion is natural, the sentence is uninformed. When I wrote the article, I <a href="https://www.goodreads.com/review/show/1731926050">hadn't yet read</a> Charles Petzold's excellent <a href="http://amzn.to/2n9MFGh">Annotated Turing</a>. Although I had heard about the <a href="https://en.wikipedia.org/wiki/Halting_problem">halting problem</a> before reading the book, I hadn't internalised it. I wasn't able to draw inferences based on that labelled concept. </p> <p> After I read the book, I've come to understand that general-purpose static type system can never prove unequivocally that a generic program works. That's what <a href="https://en.wikipedia.org/wiki/Alonzo_Church">Church</a>, <a href="https://en.wikipedia.org/wiki/Alan_Turing">Turing</a>, and <a href="https://en.wikipedia.org/wiki/Kurt_Gödel">Gödel</a> proved. </p> <p> I've been writing articles on this blog <a href="/2009/01/28/LivingInInterestingTimes">since January 2009</a>. To date, I've published 582 posts. Some are bound to be misinformed, outdated, or just plain wrong. Due to the sheer volume, I make no consistent effort to retroactively monitor and correct my past self. (I'm happy to engage with specific posts. If you feel that an old post is misleading, erroneous, or the like, please <a href="https://github.com/ploeh/ploeh.github.com#comments">leave a comment</a>.) </p> <p> For good measure, despite my failure to understand the implications of the halting problem, I'm otherwise happy with the article series <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a>. You shouldn't consider this particular example a general condemnation of it. It's just an example of a mistake I made. This time, I'm aware of it, but there are bound to be plenty of other examples where I don't even realise it. </p> <h3 id="d7843f0140164eaf97a7724413d70d76"> Heroes <a href="#d7843f0140164eaf97a7724413d70d76" title="permalink">#</a> </h3> <p> I don't have a formal degree in computer science. As so many others of my age, I began my software career by tinkering with computers and (later) programming. The first five years of my professional career, there wasn't much methodology to the way I approached software development. Self-taught often means that you have to learn everything the hard way. </p> <p> This changed when I first heard about test-driven development (TDD). I credit <a href="https://martinfowler.com">Martin Fowler</a> with that. Around the same time I also read <a href="http://amzn.to/XBYukB">Design Patterns</a>. Armed with those two techniques, I was able to rescue a failed software project and bring it to successful completion. I even received an (internal) award for it. </p> <p> While there's more to skilled programming than test-driven development and patterns, it wasn't a bad place to start. Where, before, I had nothing that even resembled a methodology, now I had a set of practices I could use. This gave me an opportunity to experiment and observe. A few years later, <a href="/2010/12/03/Towardsbetterabstractions">I'd already started to notice some recurring beneficial patterns</a> in the code that I wrote, as well as <a href="/2010/12/22/TheTDDApostate">some limits of TDD</a>. </p> <p> Still, that was a decade where I voraciously read, attended conferences, and tried to learn from my heroes. I hope that they won't mind that I list them here: <ul> <li><a href="https://martinfowler.com">Martin Fowler</a></li> <li><a href="https://en.wikipedia.org/wiki/Kent_Beck">Kent Beck</a></li> <li><a href="https://en.wikipedia.org/wiki/Robert_C._Martin">Robert C. Martin</a></li> <li><a href="https://michaelfeathers.silvrback.com">Michael Feathers</a></li> <li><a href="https://dannorth.net">Dan North</a></li> </ul> Surely, there were others. I remember being a big fan of <a href="https://en.wikipedia.org/wiki/Don_Box">Don Box</a>, but he seems to have withdrawn from the public long time ago. There were also .NET trailblazers that I admired and tried to emulate. Later, I learned much from the early luminaries of <a href="https://fsharp.org">F#</a>. I'm not going to list all the people I admire here, because the list could never be complete, and I don't wish to leave anyone feeling left out. Related to the point I'm trying to make, all these other wonderful people give me less pause. </p> <p> There's a reason I list those particular heroes. I should include a few more of whom I wasn't aware in my formative years, but whom I've since come to highly respect: <a href="https://twitter.com/marick">Brian Marick</a> and <a href="https://jessitron.com">Jessica Kerr</a>. </p> <p> Why do I mention these heroes of mine? </p> <h3 id="ae81dde11de94f9fb223cf06377a22c4"> Bias <a href="#ae81dde11de94f9fb223cf06377a22c4" title="permalink">#</a> </h3> <p> Humans aren't as rational as we'd like to think. We all have plenty of <a href="https://en.wikipedia.org/wiki/Cognitive_bias">cognitive biases</a>. I'm aware of a few of mine, but I expect most of them to be hidden from me. Sometimes, it's easier to spot the bias in others. Perhaps, by spotting the bias in others, it reveals something about oneself? </p> <p> I increasingly find myself disagreeing with my heroes. One example is the long-standing controversy about static versus dynamic typing. </p> <p> I hope I'm not misrepresenting anyone, but the heroes I enumerate above seem to favour dynamic typing over static typing - some more strongly than others. This worries me. </p> <p> These are people who've taught me a lot; whose opinion I deeply respect, and yet I fail to grasp the benefit of dynamic typing. What are the benefits they gain from their preferred languages that I'm blind to? What am I missing? </p> <p> Whenever I find myself disagreeing with my heroes, I can't help question my own judgment. Am I biased? Yes, obviously, but in which way? What bias prohibits me from seeing the benefits that are so obvious to them? </p> <p> It's too easy to jump to conclusions - to erect a dichotomy: <ul> <li>My heroes are right, and I'm wrong</li> <li>My heroes are <em>all</em> wrong, and I'm right</li> </ul> The evidence doesn't seem to support the latter conclusion, but if the first is true, I still fail to understand <em>why</em> I'm wrong. </p> <p> I'm hoping that there's a more nuanced position to take - that the above is a <a href="https://en.wikipedia.org/wiki/False_dilemma">false dichotomy</a>. </p> <h3 id="1dc21ee0532e4555ab621dfd32f31f12"> What's the problem? <a href="#1dc21ee0532e4555ab621dfd32f31f12" title="permalink">#</a> </h3> <p> Perhaps we're really talking past each other. Perhaps we're trying to solve different problems, and thereby arrive at different solutions. </p> <p> I can only guess at the kinds of problems that my heroes think of when they prefer dynamic languages, and I don't want to misrepresent them. What I <em>can</em> do, however, is outline the kind of problem that I typically have in mind. </p> <p> I've spent much of my career trying to balance <a href="/2019/03/04/code-quality-is-not-software-quality">sustainability</a> with correctness. I consider correctness as a prerequisite for all code. As <a href="http://amzn.to/1jos26M">Gerald Weinberg implies</a>, if a program doesn't have to work, anything goes. Thus, sustainability is a major focus for me: how do we develop software that can sustain our organisation now <em>and</em> in the future? How do we structure and organise code so that future change is possible? </p> <p> Whenever I get into debates, that's implicitly the problem on my mind. It'd probably improve communication if I stated this explicitly going into every debate, but sometimes, I get dragged sideways into a debacle... I do, however, speculate that much disagreement may stem from such implicit assumptions. I bring my biases and implicit problem statements into any discussion. I consider it only human if my interlocutors do the same, but their biases and implicit problem understanding may easily be different than mine. What are they, I wonder? </p> <p> This seems to happen not only in the debate about dynamic versus static types. I get a similar sense when I discuss collaboration. Most of my heroes seem to advocate for high-band face-to-face collaboration, while <a href="/2020/03/16/conways-law-latency-versus-throughput">I favour asynchronous, written communication</a>. Indeed, I admit that my bias is speaking. I self-identify as a contrarian introvert (although, again, we should be careful not turning introversion versus extroversion into binary classification). </p> <p> Still, even when I try to account for my bias, I get the sense that my opponents and I may actually try to accomplish a common goal, but by addressing two contrasting problems. </p> <p> <img src="/content/binary/same-goal-different-starting-points.png" alt="Two arrows pointing to the same problem from different directions."> </p> <p> I think and hope that, ultimately, we're trying to accomplish the same goal: to deliver and sustain business capability. </p> <p> I do get the sense that the proponents of more team co-location, more face-to-face collaboration are coming at the problem from a different direction than I am. Perhaps the problem they're trying to solve is micro-management, red tape, overly bureaucratic processes, and a lack of developer autonomy. I can certainly see that if that's the problem, talking to each other is likely to improve the situation. I'd recommend that too, in such a situation. </p> <p> Perhaps it's a local Danish (or perhaps Northern European) phenomenon, but that's not the kind of problem I normally encounter. Most organisations who ask for my help essentially have <em>no</em> process. Everything is ad hoc, nothing is written down, deployment is a manual process, and there are meetings and interruptions all the time. Since nothing is written down, decisions aren't recorded, so team members and stakeholders keep having the same meetings over and over. Again, little gets done, but for an entirely different reason than too much bureaucracy. I see this more frequently than too much red tape, so I tend to recommend that people start leaving behind some sort of written trail of what they've been doing. Pull request reviews, for example, are great for that, and I see <a href="/2021/06/21/agile-pull-requests">no incongruity between agile and pull requests</a>. </p> <h3 id="37232ffbc5cf48e58ec773ca83046807"> Shaped by scars <a href="#37232ffbc5cf48e58ec773ca83046807" title="permalink">#</a> </h3> <p> The inimitable <a href="https://twitter.com/richcampbell">Richard Campbell</a> has phrased our biases as the scars we collect during our careers. If you've deleted the production database one too many times, you develop routines and practices to avoid doing that in the future. If you've mostly worked in an organisation that stifled progress by subjecting you to <a href="https://en.wikipedia.org/wiki/Brazil_(1985_film)">Brazil</a>-levels of bureaucracy, it's understandable if you develop a preference for less formal methods. And if, like me, you've mostly seen dysfunction manifest as a <em>lack</em> of beneficial practices, you develop a taste for written over oral communication. </p> <p> Does it go further than that? Are we also shaped by our successes, just like we are shaped by our scars? </p> <p> The first time I had professional success <em>with a methodology</em> was when I discovered TDD. This made me a true believer in TDD. I'm still a big proponent of TDD, but since I learned what <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data types</a> <a href="/2016/11/28/easy-domain-modelling-with-types">can do</a> in terms of modelling, I see <a href="/2011/04/29/Feedbackmechanismsandtradeoffs">no reason to write a run-time test if I instead can get the compiler to enforce a rule</a>. </p> <p> In a recent discussion, some of my heroes expressed the opinion that they don't need <a href="/2021/06/07/abstruse-nomenclature">fancy</a> functional-programming concepts and features to write good code. I'm sure that they don't. </p> <p> My heroes have written code for decades. While I <em>have</em> met bad programmers with decades of experience, most programmers who last that long ultimately become good programmers. I'm not so worried about them. </p> <p> The people who need my help are typically younger teams. Statistically, there just aren't that many <a href="/2020/09/14/we-need-young-programmers-we-need-old-programmers">older programmers</a> around. </p> <p> When I recommend certain practices or programming techniques, those recommendations are aimed at anyone who care to listen. Usually, I find that the audience who engage with me is predominantly programmers with five to ten years of professional experience. </p> <h3 id="0d6d6bee68644d158deb5fa8cf478be7"> Anecdotal evidence <a href="#0d6d6bee68644d158deb5fa8cf478be7" title="permalink">#</a> </h3> <p> This is a difficult discussion to have. I think that another reason that we keep returning to the same controversies is that we mostly rely on <a href="https://martinfowler.com/bliki/AnecdotalEvidence.html">anecdotal evidence</a>. As we progress through our careers, we observe what works and what doesn't, but it's likely that <a href="https://en.wikipedia.org/wiki/Confirmation_bias">confirmation bias</a> makes us remember the results that we already favour, whereas we conveniently forget about the outcomes that don't fit our preferred narrative. </p> <p> Could we settle these discussions with more science? Alas, <a href="/2020/05/25/wheres-the-science">that's difficult</a>. </p> <p> I can't think of anything better, then, than keep having the same discussions over and over. I try hard to overcome my biases to understand the other side, and now and then, I learn something that I find illuminating. It doesn't seem to be a particularly efficient way to address these difficult questions, but I don't know what else to do. What's the alternative to discussion? To <em>not</em> discuss? To <em>not</em> exchange ideas? </p> <p> That seems worse. </p> <h3 id="ea7ed446c9094c1985f585223fbddb26"> Conclusion <a href="#ea7ed446c9094c1985f585223fbddb26" title="permalink">#</a> </h3> <p> In this essay, I've tried to come to grips with an increasing cognitive incongruity that I'm experiencing. I find myself disagreeing with my heroes on a regular basis, and that makes me uncomfortable. Could it be that I'm erecting an echo chamber for myself? </p> <p> The practices that I follow and endorse work well for me, but could I be stuck in a local maximum? </p> <p> This essay has been difficult to write. I'm not sure that I've managed to convey my doubts and motivations. Should I have named my heroes, only to describe how I disagree with them? Will it be seen as aggressive? </p> <p> I hope not. I'm writing about my heroes with reverence and gratitude for all that they've taught me. I mean no harm. </p> <p> At the same time, I'm struggling with reconciling that they rarely seem to agree with me these days. Perhaps they never did. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="0de8cf1ba14ad74a440eb0b29f2e437b"> <div class="comment-author"><a href="https://news.ycombinator.com/tylerhou">tylerhou</a></div> <div class="comment-content"> <p> Re: type systems. I think you are wrong about being wrong. You *can* create languages with type systems that are strong enough to guarantee that if a program compiles, it "works." Languages like this exist. The most well known is <a href="https://en.wikipedia.org/wiki/Coq">Coq</a>, a programming language/proof-assistant which provides tools for proving that properties of your program hold. So literally, if it compiles, your properties are proven true (assuming the proof assistant does not have bugs). </p> <p> Why doesn't halting problem apply here? The halting problem does not conclude that "all programs cannot be determined to halt [for a given input]." It says something much weaker -- there is no algorithm to determine whether an *arbitrary program* will halt given an arbitrary input. But there are still (large) subsets of programs where there *does* exist such a halting algorithm, and practically, these programs are common. In particular, if a language disallows certain types of recursion (or iteration), you can easily prove that programs written in that language will halt. </p> <p> For example, if you used a subset of C that did not allow recursion, goto, or loops, clearly every program written in that subset would terminate. If you expanded your subset to allow loops with a statically-known iteration bound you would know that any program in that new subset would also terminate. Then, instead of only statically bounded loops, you could choose to allow any loop with a finite bound (e.g. iterating over a finite list), and termination would still be guaranteed. </p> <p> I am not as familiar with Coq, so I will discuss a similar language (<a href="https://www.idris-lang.org/">Idris</a>) that implements "substructual recursion," a generalization of the above intuition. In functional languages, the main barrier to proving termination is unbounded recusion. (In imperative languages, loops are also an issue, but loops are equivalent to recursion.) So <a href="https://docs.idris-lang.org/en/latest/tutorial/theorems.html#totality-checking">Idris provides a language subset</a> that only allows substructural recursion -- i.e. if a function <code>f</code> eventually calls itself, it must only call itself with arguments that are "smaller" than the first call. (E.g. for natural numbers smaller means less than, and for lists smaller means a list with a smaller size.) This property is checked at compile time. Since all function cases must be covered the recursive calls must eventually terminate. </p> <p> In practice, most programs don't need unbounded recursion. Most useful algorithms<sup>[citation needed]</sup> have some bound on the number of iterations needed. To modify any arbitrary algorithm to fit a language like Idris it is simple to introduce another natural number parameter <code>N</code> that always decreases by one on recursive calls. When that parameter reaches zero, the function should return an error. Now it is simple for Idris to prove that any call to that function must terminate within <code>N</code> recursions. On the initial call you can set this number to be the upper bound on your algorithm, and since you know that your algorithm will never need that many iterations you know you will always get an answer (the error is just there to satisfy the totality checker). </p> </div> <div class="comment-date">2021-08-11 05:40 UTC</div> </div> <div class="comment" id="02f4fd84d77c4006adc696457fe407dd"> <div class="comment-author"><a href="https://twitter.com/_rchaves_">_rchaves_</a></div> <div class="comment-content"> <p> Hello there! </p> <p> That is a very nice write up, impeccable choice of words. I could see myself a lot in it, except that at some point I was not in disagreement with the dynamic or static types approach, but that somehow I enjoyed both, and couldn’t reconcile this contradiction until some months ago, so I hope my experience can help you too. </p> <p> Going through a recent experience of moving from a consulting company (the one Martin Fowler works on) with good practices and TDD all the way, strong types and no runtime exceptions (Elm) to a Perl shop with no tests, no pull requests, nothing, I can tell you it felt like a roller coaster. </p> <p> At first I thought everything was wrong, and wanted to change it all, to play the consultant. But I decided not to stress out too much about work, and with time I actually started seeing the beauty in all that too, and the advantages this "move fast and break things" culture brought. Meanwhile, on the side, I was still having fun building Elm apps, learning about Haskell, curious about TLA+, writing tests for everything, etc. I felt conflicted, how is it that one can see beauty in both approaches? Which one do I think is the best? </p> <p> Luckily for me, I was also very interested in data, statistics, causality, etc, and somehow I think that lead me to read all the books by Nassim Taleb (one of my heroes now), but it was finally Kent Back (on top of Nassim's insights) that made it all click in place, from a similar experience at Facebook, with his 3X theory, which I really recommend you to watch if you haven't already: <a href="https://www.youtube.com/watch?v=FlJN6_4yI2A">https://www.youtube.com/watch?v=FlJN6_4yI2A</a>. </p> <p> I realised then that my views were actually not in contradiction at all, it was an obvious case of Consulting 101: "it depends". None of the approaches is the best one alone, they are conditional on the environment you are, the risks you face, what are you trying to achieve. You said "we are shaped by our scars", but I think we can (with a lot of effort) actually take a step back and acknowledge our scars as you did, and be mindful of what environments our experiences are conditional too, to try to see different paths that different people went, so you can experience that too and find other "local maxima". Having the two (or more) local maxima in your toolbelt in a way gets you closer to the global maxima :) </p> <p> I also wrote a blogpost, and happy to talk more about it if you are interested: <a href="https://rchavesferna.medium.com/designed-v-evolutionary-code-d52a54408c8f">https://rchavesferna.medium.com/designed-v-evolutionary-code-d52a54408c8f</a> </p> <p> Good luck on your journey <br /> Cheers! </p> </div> <div class="comment-date">2021-08-11 09:44 UTC</div> </div> <div class="comment" id="51a93388e4fe499e9d953afb494ee43a"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> tylerhou, thank you for writing. Yes, you're correct. I should have more explicitly stated that there's no algorithm to determine whether an arbitrary program in a Turing-complete language halts. This does highlight the importance of explicitly stating assumptions and preconditions, which I failed to fully do here. </p> </div> <div class="comment-date">2021-08-12 7:33 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>. The Tennis kata revisited https://blog.ploeh.dk/2021/08/03/the-tennis-kata-revisited 2021-08-03T10:45:00+00:00 Mark Seemann <div id="post"> <p> <em>When you need discriminated unions, but all you have are objects.</em> </p> <p> After I learned that <a href="/2018/06/25/visitor-as-a-sum-type">the Visitor design pattern is isomorphic to sum types</a> (AKA <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/discriminated-unions">discriminated unions</a>), I wanted to try how easy it is to carry out a translation in practice. For that reason, I decided to translate my go-to <a href="https://fsharp.org">F#</a> implementation of the <a href="https://codingdojo.org/kata/Tennis">Tennis kata</a> to C#, using the <a href="https://en.wikipedia.org/wiki/Visitor_pattern">Visitor design pattern</a> everywhere I'd use a discriminated union in F#. </p> <p> The resulting C# code shows that it is, indeed, possible to 'mechanically' translate discriminated unions to the Visitor design pattern. Given that the Visitor pattern requires multiple interfaces and classes to model just a single discriminated union, it's no surprise that the resulting code is much more complex. As a solution to the Tennis kata itself, all this complexity is unwarranted. On the other hand, as an exercise in getting by with the available tools, it's quite illustrative. If all you have is C# (or a similar language), but you really need discriminated unions, the solution is ready at hand. It'll be complex, but not complicated. </p> <p> The main insight of this exercise is that translating any discriminated union to a Visitor is, indeed, possible. You can best internalise such insights, however, if you actually do the work yourself. Thus, in this article, I'll only show a few highlights from my own exercise. I highly recommend that you try it yourself. </p> <h3 id="5667e0a2df95411da703aab3df3ddcb3"> Typical F# solution <a href="#5667e0a2df95411da703aab3df3ddcb3" title="permalink">#</a> </h3> <p> You can see my typical F# solution in great detail in my article series <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a>. To be clear, there are many ways to implement the Tennis kata, even in F#, and the one shown in the articles is neither overly clever nor <a href="/2021/03/29/table-driven-tennis-scoring">too boring</a>. As implementations go, this one is quite pedestrian. </p> <p> My emphasis with that kind of solution to the Tennis kata is on readability, correctness, and testability. Going for <a href="/2018/11/19/functional-architecture-a-definition">a functional architecture</a> automatically <a href="/2015/05/07/functional-design-is-intrinsically-testable">addresses the testability concern</a>. In F#, I endeavour to use the excellent type system to <a href="https://blog.janestreet.com/effective-ml-video">make illegal states unrepresentable</a>. Discriminated unions are essential ingredients in that kind of design. </p> <p> In F#, I'd typically <a href="/2016/02/10/types-properties-software-designing-with-types">model a Tennis game score as a discriminated union</a> like this: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;<span style="color:#4ec9b0;">Score</span>&nbsp;= |&nbsp;<span style="color:navy;">Points</span>&nbsp;<span style="color:blue;">of</span>&nbsp;<span style="color:#4ec9b0;">PointsData</span> |&nbsp;<span style="color:navy;">Forty</span>&nbsp;<span style="color:blue;">of</span>&nbsp;<span style="color:#4ec9b0;">FortyData</span> |&nbsp;<span style="color:navy;">Deuce</span> |&nbsp;<span style="color:navy;">Advantage</span>&nbsp;<span style="color:blue;">of</span>&nbsp;<span style="color:#4ec9b0;">Player</span> |&nbsp;<span style="color:navy;">Game</span>&nbsp;<span style="color:blue;">of</span>&nbsp;<span style="color:#4ec9b0;">Player</span></pre> </p> <p> That's not the only discriminated union involved in the implementation. <code>Player</code> is also a discriminated union, and both <code>PointsData</code> and <code>FortyData</code> compose a third discriminated union called <code>Point</code>: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;<span style="color:#4ec9b0;">Point</span>&nbsp;=&nbsp;<span style="color:navy;">Love</span>&nbsp;|&nbsp;<span style="color:navy;">Fifteen</span>&nbsp;|&nbsp;<span style="color:navy;">Thirty</span></pre> </p> <p> Please refer to <a href="/2016/02/10/types-properties-software-designing-with-types">the older article</a> for full details of the F# 'domain model'. </p> <p> This was the sort of design I wanted to try to translate to C#, using the Visitor design pattern in place of discriminated unions. </p> <h3 id="90107f78b2a64ad288c62905aca58011"> Player <a href="#90107f78b2a64ad288c62905aca58011" title="permalink">#</a> </h3> <p> In F# you must declare all types and functions before you can use them. To newcomers, this often looks like a constraint, but is <a href="/2015/04/15/c-will-eventually-get-all-f-features-right">actually one of F#'s greatest strengths</a>. Since other types transitively use the <code>Player</code> discriminated union, this is the first type you have to define in an F# code file: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;<span style="color:#4ec9b0;">Player</span>&nbsp;=&nbsp;<span style="color:navy;">PlayerOne</span>&nbsp;|&nbsp;<span style="color:navy;">PlayerTwo</span></pre> </p> <p> This one is fairly straightforward to translate to C#. You might reach for an <code>enum</code>, but those aren't really type-safe in C#, since they're little more than glorified integers. Using a discriminated union is safer, so define a Visitor: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IPlayerVisitor</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">VisitPlayerOne</span>(); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">VisitPlayerTwo</span>(); }</pre> </p> <p> A Visitor interface is where you enumerate the cases of the discriminated union - in this example <em>player one</em> and <em>player two</em>. You can <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiomatically</a> prefix each method with <code>Visit</code> as I've done here, but that's optional. </p> <p> Once you've defined the Visitor, you can declare the 'actual' type you're modelling: the player: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IPlayer</span> { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">Accept</span>&lt;<span style="color:#2b91af;">T</span>&gt;(IPlayerVisitor&lt;T&gt;&nbsp;<span style="color:#1f377f;">visitor</span>); }</pre> </p> <p> Those are only the polymorphic types required to model the discriminated union. You also need to add concrete classes for each of the cases. Here's <code>PlayerOne</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">struct</span>&nbsp;<span style="color:#2b91af;">PlayerOne</span>&nbsp;:&nbsp;IPlayer { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;<span style="color:#74531f;">Accept</span>&lt;<span style="color:#2b91af;">T</span>&gt;(IPlayerVisitor&lt;T&gt;&nbsp;<span style="color:#1f377f;">visitor</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;visitor.VisitPlayerOne(); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This is an example of the Visitor pattern's central <em>double dispatch</em> mechanism. Clients of the <code>IPlayer</code> interface will dispatch execution to the <code>Accept</code> method, which again dispatches execution to the <code>visitor</code>. </p> <p> I decided to make <code>PlayerOne</code> a <code>struct</code> because it holds no data. Perhaps I <a href="/2021/03/08/pendulum-swing-sealed-by-default">also ought to have sealed it</a>, or, as <a href="http://amzn.to/XBYukB">Design Patterns</a> likes to suggest, make it a <a href="https://en.wikipedia.org/wiki/Singleton_pattern">Singleton</a>. </p> <p> Hardly surprising, <code>PlayerTwo</code> looks almost identical to <code>PlayerOne</code>. </p> <p> Apart from a <a href="https://fsharpforfunandprofit.com/posts/designing-with-types-single-case-dus">single-case discriminated union</a> (which is degenerate), a discriminated union doesn't get any simpler than <code>Player</code>. It has only two cases and carries no data. Even so, it takes <em>four</em> types to translate it to a Visitor: two interfaces and two concrete classes. This highlights how the Visitor pattern adds significant complexity. </p> <p> And it only gets worse with more complex discriminated unions. </p> <h3 id="1ce1c4cb87894ae183799a140a9001fe"> Score <a href="#1ce1c4cb87894ae183799a140a9001fe" title="permalink">#</a> </h3> <p> I'm going to leave the translation of <code>Point</code> as an exercise. It's similar to the translation of <code>Player</code>, but instead of two cases, it enumerates three cases. Instead, consider how to enumerate the cases of <code>Score</code>. First, add a Visitor: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IScoreVisitor</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">VisitPoints</span>(IPoint&nbsp;<span style="color:#1f377f;">playerOnePoint</span>,&nbsp;IPoint&nbsp;<span style="color:#1f377f;">playerTwoPoint</span>); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">VisitForty</span>(IPlayer&nbsp;<span style="color:#1f377f;">player</span>,&nbsp;IPoint&nbsp;<span style="color:#1f377f;">otherPlayerPoint</span>); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">VisitDeuce</span>(); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">VisitAdvantage</span>(IPlayer&nbsp;<span style="color:#1f377f;">advantagedPlayer</span>); &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#74531f;">VisitGame</span>(IPlayer&nbsp;<span style="color:#1f377f;">playerWhoWonGame</span>); }</pre> </p> <p> Notice that these methods take arguments, apart from <code>VisitDeuce</code>. I could have made that member a read-only property instead, but for consistency's sake, I kept it as a method. </p> <p> All the other methods take arguments that are, in their own right, Visitors. </p> <p> In addition to the Visitor interface, you also need an interface to model the score itself: </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;T&nbsp;<span style="color:#74531f;">Accept</span>&lt;<span style="color:#2b91af;">T</span>&gt;(IScoreVisitor&lt;T&gt;&nbsp;<span style="color:#1f377f;">visitor</span>); }</pre> </p> <p> This one defines, as usual, just a single <code>Accept</code> method. </p> <p> Since <code>IScoreVisitor</code> enumerates five distinct cases, you must also add five concrete implementations of <code>IScore</code>. Here's <code>Forty</code>: </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;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IPlayer&nbsp;player; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IPoint&nbsp;otherPlayerPoint; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Forty</span>(IPlayer&nbsp;<span style="color:#1f377f;">player</span>,&nbsp;IPoint&nbsp;<span style="color:#1f377f;">otherPlayerPoint</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.player&nbsp;=&nbsp;player; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.otherPlayerPoint&nbsp;=&nbsp;otherPlayerPoint; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;<span style="color:#74531f;">Accept</span>&lt;<span style="color:#2b91af;">T</span>&gt;(IScoreVisitor&lt;T&gt;&nbsp;<span style="color:#1f377f;">visitor</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;visitor.VisitForty(player,&nbsp;otherPlayerPoint); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> I'm leaving other concrete classes as an exercise to the reader. All of them are similar, though, in that they all implement <code>IScore</code> and unconditionally dispatch to 'their' method on <code>IScoreVisitor</code> - <code>Forty</code> calls <code>VisitForty</code>, <code>Points</code> calls <code>VisitPoints</code>, and so on. Each concrete implementation has a distinct constructor, though, since what they need to dispatch to the Visitor differs. </p> <p> <code>Deuce</code>, being degenerate, doesn't have to explicitly define a constructor: </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;T&nbsp;<span style="color:#74531f;">Accept</span>&lt;<span style="color:#2b91af;">T</span>&gt;(IScoreVisitor&lt;T&gt;&nbsp;<span style="color:#1f377f;">visitor</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;visitor.VisitDeuce(); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The C# compiler automatically adds a parameterless constructor when none is defined. An alternative implementation would, again, be to make <code>Deuce</code> a Singleton. </p> <p> In all, it takes seven types (two interfaces and five concrete classes) to model <code>Score</code> - a type that requires only a few lines of code in F# (six lines in my code, but you could format it more densely if you want to compromise readability). </p> <h3 id="6ac8c03643eb454f9dfcc76365d7ef2e"> Keeping score <a href="#6ac8c03643eb454f9dfcc76365d7ef2e" title="permalink">#</a> </h3> <p> In order to calculate the score of a game, I also translated the <code>score</code> function. I put that in an <a href="https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods">extension method</a> so as to not 'pollute' the <code>IScore</code> interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IScore&nbsp;<span style="color:#74531f;">BallTo</span>(<span style="color:blue;">this</span>&nbsp;IScore&nbsp;<span style="color:#1f377f;">score</span>,&nbsp;IPlayer&nbsp;<span style="color:#1f377f;">playerWhoWinsBall</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;score.Accept(<span style="color:blue;">new</span>&nbsp;ScoreVisitor(playerWhoWinsBall)); }</pre> </p> <p> Given an <code>IScore</code> value, there's little you can do with it, apart from calling its <code>Accept</code> method. In order to do that, you'll need an <code>IScoreVisitor</code>, which I defined as a private nested class: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ScoreVisitor</span>&nbsp;:&nbsp;IScoreVisitor&lt;IScore&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;IPlayer&nbsp;playerWhoWinsBall; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ScoreVisitor</span>(IPlayer&nbsp;<span style="color:#1f377f;">playerWhoWinsBall</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.playerWhoWinsBall&nbsp;=&nbsp;playerWhoWinsBall; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Implementation&nbsp;goes&nbsp;here...</span></pre> </p> <p> Some of the methods are trivial to implement, like <code>VisitDeuce</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;IScore&nbsp;<span style="color:#74531f;">VisitDeuce</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;Advantage(playerWhoWinsBall); }</pre> </p> <p> Most others are more complicated. Keep in mind that the method arguments (<code>IPlayer</code>, <code>IPoint</code>) are Visitors in their own right, so in order to do anything useful with them, you'll have to call their <code>Accept</code> methods with a corresponding, specialised Visitor. </p> <h3 id="054ae9485c294ba2a9b9029271f540fa"> Pattern matching <a href="#054ae9485c294ba2a9b9029271f540fa" title="permalink">#</a> </h3> <p> I quickly realised that this would become too tedious, even for an exercise, so I leveraged my knowledge that the Visitor pattern is isomorphic to a <a href="/2018/05/22/church-encoding">Church encoding</a>. Instead of defining umpteen specialised Visitors, I just defined a generic <code>Match</code> method for each Visitor-based object. I put those in extension methods as well. Here's the <code>Match</code> method for <code>IPlayer</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;T&nbsp;<span style="color:#74531f;">Match</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;IPlayer&nbsp;<span style="color:#1f377f;">player</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">playerOne</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">playerTwo</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;player.Accept(<span style="color:blue;">new</span>&nbsp;MatchVisitor&lt;T&gt;(playerOne,&nbsp;playerTwo)); }</pre> </p> <p> The implementation is based on a private nested <code>MatchVisitor</code>: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">MatchVisitor</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;:&nbsp;IPlayerVisitor&lt;T&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;T&nbsp;playerOneValue; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;T&nbsp;playerTwoValue; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">MatchVisitor</span>(T&nbsp;<span style="color:#1f377f;">playerOneValue</span>,&nbsp;T&nbsp;<span style="color:#1f377f;">playerTwoValue</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.playerOneValue&nbsp;=&nbsp;playerOneValue; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.playerTwoValue&nbsp;=&nbsp;playerTwoValue; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;<span style="color:#74531f;">VisitPlayerOne</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;playerOneValue; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;T&nbsp;<span style="color:#74531f;">VisitPlayerTwo</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;playerTwoValue; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This enables pattern matching, upon which you can implement other reusable methods, such as <code>Other</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IPlayer&nbsp;<span style="color:#74531f;">Other</span>(<span style="color:blue;">this</span>&nbsp;IPlayer&nbsp;<span style="color:#1f377f;">player</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;player.Match&lt;IPlayer&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerOne:&nbsp;<span style="color:blue;">new</span>&nbsp;PlayerTwo(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerTwo:&nbsp;<span style="color:blue;">new</span>&nbsp;PlayerOne()); }</pre> </p> <p> It's also useful to be able to compare two players and return two alternative values depending on the result: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;T&nbsp;<span style="color:#74531f;">Equals</span>&lt;<span style="color:#2b91af;">T</span>&gt;( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>&nbsp;IPlayer&nbsp;<span style="color:#1f377f;">p1</span>, &nbsp;&nbsp;&nbsp;&nbsp;IPlayer&nbsp;<span style="color:#1f377f;">p2</span>, &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#1f377f;">same</span>, &nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;<span style="color:#1f377f;">different</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;p1.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerOne:&nbsp;p2.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerOne:&nbsp;same, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerTwo:&nbsp;different), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerTwo:&nbsp;p2.Match( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerOne:&nbsp;different, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;playerTwo:&nbsp;same)); }</pre> </p> <p> You can add similar <code>Match</code> and <code>Equals</code> extension methods for <code>IPoint</code>, which enables you to implement all the methods of the <code>ScoreVisitor</code> class. Here's <code>VisitForty</code> as an example: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;IScore&nbsp;<span style="color:#74531f;">VisitForty</span>(IPlayer&nbsp;<span style="color:#1f377f;">player</span>,&nbsp;IPoint&nbsp;<span style="color:#1f377f;">otherPlayerPoint</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;playerWhoWinsBall.Equals(player, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;same:&nbsp;<span style="color:blue;">new</span>&nbsp;Game(player), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;different:&nbsp;otherPlayerPoint.Match&lt;IScore&gt;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;love:&nbsp;<span style="color:blue;">new</span>&nbsp;Forty(player,&nbsp;<span style="color:blue;">new</span>&nbsp;Fifteen()), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fifteen:&nbsp;<span style="color:blue;">new</span>&nbsp;Forty(player,&nbsp;<span style="color:blue;">new</span>&nbsp;Thirty()), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thirty:&nbsp;<span style="color:blue;">new</span>&nbsp;Deuce())); }</pre> </p> <p> If <code>playerWhoWinsBall.Equals(player</code> the implementation matches on <code>same</code>, and returns <code>new Game(player)</code>. Otherwise, it matches on <code>different</code>, in which case it then has to <code>Match</code> on <code>otherPlayerPoint</code> to figure out what to return. </p> <p> Again, I'll leave the remaining code as an exercise to the reader. </p> <h3 id="f476c043ca9548b58f874fb0b87aaf70"> Tests <a href="#f476c043ca9548b58f874fb0b87aaf70" title="permalink">#</a> </h3> <p> While all this code is written in C#, it's all <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. Thus, <a href="/2015/05/07/functional-design-is-intrinsically-testable">it's intrinsically testable</a>. Knowing that, I could have added tests after writing the 'production code', but that's so boring, so I still developed this code base using test-driven development. Here's an example of a test: </p> <p> <pre>[Theory,&nbsp;MemberData(nameof(Player))] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">TransitionFromDeuce</span>(IPlayer&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;Deuce(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.BallTo(player); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;Advantage(player); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual); }</pre> </p> <p> I wrote all tests as <a href="/2020/08/31/properties-for-all">properties for all</a>. The above test uses <a href="https://xunit.net">xUnit.net</a> 2.4.0. The <code>Player</code> data source is a private <code>MemberData</code> defined as a read-only property: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;IEnumerable&lt;<span style="color:blue;">object</span>[]&gt;&nbsp;Player { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">get</span> &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">object</span>[]&nbsp;{&nbsp;<span style="color:blue;">new</span>&nbsp;PlayerOne()&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:blue;">object</span>[]&nbsp;{&nbsp;<span style="color:blue;">new</span>&nbsp;PlayerTwo()&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> Other tests are defined in a likewise manner. </p> <h3 id="720181cad99a4cd79c41435d622a949b"> Conclusion <a href="#720181cad99a4cd79c41435d622a949b" title="permalink">#</a> </h3> <p> Once you've tried to solve problems with <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data types</a> it can be frustrating to return to languages that don't have <a href="https://en.wikipedia.org/wiki/Tagged_union">sum types</a> (discriminated unions). There's no need to despair, though. Sum types are isomorphic to the Visitor design pattern, so it <em>is</em> possible to solve problems in the same way. </p> <p> The resulting code can easily <em>seem</em> complex because a simple discriminated union translates to multiple C# files. Another option is to use Church encoding, but many developers who consider themselves object-oriented often balk at such constructs. When it comes to policy, the Visitor design pattern offers the advantage that it's described in <a href="http://amzn.to/XBYukB">Design Patterns</a>. While it may be a bit of an underhanded tactic, it effectively deals with some teams' resistance to ideas originating in functional programming. </p> <p> The exercise outlined in this article demonstrates that translating from algebraic data types to patterns-based object-oriented code is not only possible, but (once you get the hang of it) unthinking and routine. It's entirely automatable, so you could even imagine defining a <a href="https://en.wikipedia.org/wiki/Domain-specific_language">DSL</a> for defining sum types and transpiling them to C#. </p> <p> But really, you don't have to, because <a href="https://fsharp.org">such a DSL already exists</a>. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="efdd9051556447b8be4831a793c1bbbf"> <div class="comment-author"><a href="https://github.com/Joker-vD">Joker_vD</a></div> <div class="comment-content"> <p> The most annoying thing about the visitor pattern is that you can't get around declaring <code>interface IMyLovelyADT { R Accept&lt;R&gt;(IMyLovelyADTVisitor&lt;R&gt; visitor); }</code> and a separate class implementing this interface for each data variant. One may think that this interface is isomorphic to <code>Func&lt;IMyLovelyADTVisitor&lt;R&gt;, R&gt;</code> but it actually is not, look: </p> <p><pre>// type Bool = True | False interface IBoolVisitor&lt;R&gt; { R True(); R False(); } static class BoolUtils { public static Func&lt;IBoolVisitor&lt;R&gt;, R&gt; True&lt;R&gt;() =&gt; sym =&gt; sym.True(); public static Func&lt;IBoolVisitor&lt;R&gt;, R&gt; False&lt;R&gt;() =&gt; sym =&gt; sym.False(); private class BoolMatcher&lt;R&gt; : IBoolVisitor&lt;R&gt; { Func&lt;R&gt; OnTrue { get; } Func&lt;R&gt; OnFalse { get; } public BoolMatcher(Func&lt;R&gt; onTrue, Func&lt;R&gt; onFalse) { OnTrue = onTrue; OnFalse = onFalse; } public R True() =&gt; OnTrue(); public R False() =&gt; OnFalse(); } public static R Match&lt;R&gt;(this Func&lt;IBoolVisitor&lt;R&gt;, R&gt; value, Func&lt;R&gt; onTrue, Func&lt;R&gt; onFalse) =&gt; value(new BoolMatcher&lt;R&gt;(onTrue, onFalse)); }</pre></p> <p> Yes, all this typechecks and compiles, and you can even write <code>ShowBool</code> and <code>BoolToInt</code> methods, but! You can't combine them: </p> <p><pre>static class FunctionsAttempt1 { public static string ShowBool(Func&lt;IBoolVisitor&lt;string&gt;, string&gt; value) { return value.Match(() =&gt; "True", () =&gt; "False"); } public static int BoolToInt(Func&lt;IBoolVisitor&lt;int&gt;, int&gt; value) { return value.Match(() =&gt; 1, () =&gt; 0); } public static string CombineBoolFunctions&lt;R&gt;(Func&lt;IBoolVisitor&lt;R&gt;, R&gt; value) { return ShowBool(value) + ": " + BoolToInt(value).ToString(); } }</pre></p> <p> The first two methods are fine, but <code>CombineBoolFunctions</code> doesn't compile, because you can't pass <code>Func&lt;IBoolVisitor&lt;R&gt;, R&gt;</code> to a method that expects <code>Func&lt;IBoolVisitor&lt;string&gt;, string&gt;</code>. What if you try to make <code>ShowBool</code> and <code>BoolToInt</code> accept <code>Func&lt;IBoolVisitor&lt;R&gt;, R&gt;</code>? </p> <p><pre>static class FunctionsAttempt2 { public static string ShowBool<R>(Func<IBoolVisitor<R>, R> value) { return value.Match<string>(() => "True", () => "False"); } public static int BoolToInt<R>(Func<IBoolVisitor<R>, R> value) { return value.Match<int>(() => 1, () => 0); } public static string CombineBoolFunctions<R>(Func<IBoolVisitor<R>, R> value) { return ShowBool(value) + ": " + BoolToInt(value).ToString(); } }</pre></p> <p> That also doesn't work, for pretty much the same reason: <code>CombineBoolFunctions</code> compiles now, but not <code>ShowBool</code> or <code>BoolToInt</code>. That's why you need a <em>non-generic</em> wrapper interface <code>IMyLovelyADT</code>: it essentially does the same job as Haskell's <code>forall</code>, since generic types are not quite proper types in C#'s type system. Interestingly enough, upcoming Go 2's generics will <em>not</em> support this scenario: a method inside an interface will be able to use only the generic parameters that the interface itself declares. </p> </div> <div class="comment-date">2021-08-06 20:47 UTC</div> </div> <div class="comment" id="e9b335c980b649ccb18a015868b55763"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Joker_vD, thank you for writing; you explained that well. </p> </div> <div class="comment-date">2021-08-07 20:25 UTC</div> </div> <div class="comment" id="d385b2cd13834e19b587a5d80048794e"> <div class="comment-author">Tyrie Vella</div> <div class="comment-content"> <p> I've recently been using C# 9's <code>record</code> feature to implement ADTs. For example: </p> <p><pre> public abstract record Player { private Player() {} public sealed record One : Player; public sealed record Two : Player; } public abstract record Point { private Point() {} public sealed record Love: Point; public sealed record Fifteen: Point; public sealed record Thirty: Point; } public abstract record Score { private Score() {} public sealed record Points(Point PlayerOnePoints, Point PlayerTwoPoints); public sealed record Forty(Player Player, Point OtherPlayersPoint); public sealed record Deuce; public sealed record Advantage(Player Player); public sealed record Game(Player Player); } </pre></p> <p> It's not as good as F# ADTs, but it's more concise than Visitors, works with <code>switch</code> pattern matching, has structural equality semantics, and I haven't found the downside yet. </p> </div> <div class="comment-date">2021-08-17 00:16 UTC</div> </div> <div class="comment" id="33ae4341e1b44975b0171c0f99bbe263"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyrie, thank you for writing. I haven't tried that yet, but I agree that if this works, it's simpler. </p> <p> Does <code>switch</code> pattern matching check exhaustiveness? What I means is: With sum types/discriminated unions, as well as with the Visitor pattern, the compiler can tell you if you haven't covered all cases. Does the C# compiler also do that with <code>switch</code> pattern matching? </p> <p> And do you need to include a <code>default</code> label? </p> </div> <div class="comment-date">2021-08-17 5:39 UTC</div> </div> <div class="comment" id="9bd1ef73f41243f6bb02f0825ccc245b"> <div class="comment-author">Tyrie Vella</div> <div class="comment-content"> <p> Looks like you found the flaw. The C# compiler tries, and it will block invalid cases, but it always wants a default case (either <code>_</code> or both <code>"null"</code> and <code>"not null"</code>) when switching on one of these. It can't suggest the actually missing cases. </p> </p> It's also only a warning by default at compile time. </p> </div> <div class="comment-date">2021-08-17 15:43 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>. Referential transparency fits in your head https://blog.ploeh.dk/2021/07/28/referential-transparency-fits-in-your-head 2021-07-28T12:13:00+00:00 Mark Seemann <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> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="b02363b9e7e64f0db23d2459b57332f5"> <div class="comment-author">Gonzalo Waszczuk</div> <div class="comment-content"> <p>Absolutely agree. The problem of "Code that fits in your head" is not about code either, it's about <i>all human reasoning</i>. It particularly happens in math. In math, why do we prove "theorems", and then prove new theorems by referencing those previous theorems or lemmas? Why can't mathematicians just prove everything every single time? Because math can't fit in someone's head, so we also need these tools.</p> <p>Or rather, math <i>is</i> the tool for "X that fits in your head". Math is the language of human reasoning, anything that can be reasoned about can be modelled in math and talked about in math, which is a language we all know about and have used for thousands of years.</p> <p>It can help us developers a lot to make use of this shared language. There already exists a language to help us figure out how to Fit Code In Our Heads, it would be detrimental to ourselves to ignore it. You link to category theory, and there's also algebra. These are tools for such endeavor, I think developers should be more open towards them and not just deride them as "hard" or "ivory-tower-esque", they should be the opposite of that. And in fact, whne you properly understand algebra, there is nothing really hard about it, it's actually so simple and easy you can't understand why you didn't pay attention to it sooner.</p> </div> <div class="comment-date">2021-08-02 02:07 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>. The State functor https://blog.ploeh.dk/2021/07/19/the-state-functor 2021-07-19T15:00:00+00:00 Mark Seemann <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>. <del datetime="2021-08-27T20:01:10Z">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>.</del> </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="/2021/08/30/the-reader-functor">The Reader 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>. A reading of Extensibility for the Masses https://blog.ploeh.dk/2021/07/12/a-reading-of-extensibility-for-the-masses 2021-07-12T05:36:00+00:00 Mark Seemann <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>. Fractal hex flowers https://blog.ploeh.dk/2021/07/05/fractal-hex-flowers 2021-07-05T08:51:00+00:00 Mark Seemann <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>. 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 2021-06-28T06:45:00+00:00 Mark Seemann <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>. Agile pull requests https://blog.ploeh.dk/2021/06/21/agile-pull-requests 2021-06-21T05:44:00+00:00 Mark Seemann <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>. New book: Code That Fits in Your Head https://blog.ploeh.dk/2021/06/14/new-book-code-that-fits-in-your-head 2021-06-14T11:00:00+00:00 Mark Seemann <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> <li><a href="/2021/09/13/unit-testing-private-helper-methods">Unit testing private helper methods</a></li> <li><a href="/2021/09/20/keep-ids-internal-with-rest">Keep IDs internal with REST</a></li> <li><a href="/2021/09/27/the-equivalence-contravariant-functor">The Equivalence contravariant functor</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>. Abstruse nomenclature https://blog.ploeh.dk/2021/06/07/abstruse-nomenclature 2021-06-07T05:36:00+00:00 Mark Seemann <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>. From State tennis to endomorphism https://blog.ploeh.dk/2021/05/31/from-state-tennis-to-endomorphism 2021-05-31T06:29:00+00:00 Mark Seemann <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>. Tennis kata using the State pattern https://blog.ploeh.dk/2021/05/24/tennis-kata-using-the-state-pattern 2021-05-24T07:03:00+00:00 Mark Seemann <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>. Against consistency https://blog.ploeh.dk/2021/05/17/against-consistency 2021-05-17T06:34:00+00:00 Mark Seemann <div id="post"> <p> <em>A one-sided argument against imposing a uniform coding style.</em> </p> <p> I want to credit <a href="http://www.natpryce.com">Nat Pryce</a> for planting the seed for the following line of thinking <a href="https://www.infoq.com/presentations/Stop-Refactoring">at GOTO Copenhagen 2012</a>. I'd also like to relieve him of any responsibility for what follows. The blame is all mine. </p> <p> I'd also like to point out that I'm not categorically against consistency in code. There are plenty of good arguments <em>for</em> having a consistent coding style, but as regular readers may have observed, I have a contrarian streak to my personality. If you're only aware of one side of an argument, I believe that you're unequipped to make informed decisions. Thus, I make the following case <em>against</em> imposing coding styles, not because I'm dead-set opposed to consistent code, but because I believe you should be aware of the disadvantages. </p> <h3 id="ab42cf8b7ede4b00895acba034f9a7b1"> TL;DR <a href="#ab42cf8b7ede4b00895acba034f9a7b1" title="permalink">#</a> </h3> <p> In this essay, I use the term <em>coding style</em> to indicate a set of rules that governs how code should be formatted. This may include rules about where you put brackets, whether to use tabs or spaces, which <a href="https://en.wikipedia.org/wiki/Naming_convention_(programming)">naming conventions</a> to use, <a href="/2019/11/04/the-80-24-rule">maximum line width</a>, in C# whether you should use the <code>var</code> keyword or explicit variable declaration, and so on. </p> <p> As already stated, I can appreciate consistency in code as much as the next programmer. I've seen more than one code base, however, where a formal coding style contributed to ossification. </p> <p> I've consulted a few development organisations with an eye to improving processes and code quality. Sometimes my suggestions are met with hesitation. When I investigate what causes developers to resist, it turns out that my advice goes against 'how things are done around here.' It might even go against the company's formal coding style guidelines. </p> <p> Coding styles may impede progress. </p> <p> Below, I'll discuss a few examples. </p> <h3 id="682fe4a54ba44844889f03ca33fac209"> Class fields <a href="#682fe4a54ba44844889f03ca33fac209" title="permalink">#</a> </h3> <p> A typical example of a coding style regulates naming of class fields. While it seems to be on retreat now, at one time many C# developers would name class fields with a leading underscore: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;_action; <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;_controller; <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">object</span>?&nbsp;_values;</pre> </p> <p> I never liked that naming convention because it meant that I always had to type an underscore <em>and then at least one other letter</em> before I could make good use of my IDE. For example, in order to take advantage of auto-completion when using the <code>_action</code> field, I'd have to type <code>_a</code>, instead of just <code>a</code>. </p> <p> <img src="/content/binary/intellisense-upon-underscore.png" alt="Screen shot of Intellisense drop-down after typing a single underscore."> </p> <p> Yes, I know that <a href="/2018/09/17/typing-is-not-a-programming-bottleneck">typing isn't a bottleneck</a>, but it still annoyed me because it seemed redundant. </p> <p> A variation of this coding style is to mandate an <code>m_</code> prefix, which only exacerbates the problem. </p> <p> Many years ago, I came across a 'solution': Put the underscore <em>after</em> the field name, instead of in front of it: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;action_; <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">string</span>?&nbsp;controller_; <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">object</span>?&nbsp;values_;</pre> </p> <p> Problem solved - I thought for some years. </p> <p> Then someone pointed out to me that if distinguishing a class field from a local variable is the goal, you can use the <code>this</code> qualifier. That made sense to me. Why invent some controversial naming rule when you can use a language keyword instead? </p> <p> So, for years, I'd always interact with class fields like <code>this.action</code>, <code>this.controller</code>, and so on. </p> <p> Then someone else point out to me that this ostensible need to be able to distinguish class fields from local variables, or static from instance fields, was really a symptom of either poor naming or too big classes. While that hurt a bit, I couldn't really defend against the argument. </p> <p> This is all many years ago. These days, I name class fields like I name variables, and I don't qualify access. </p> <p> The point of this little story is to highlight how you can institute a naming convention with the best of intentions. As experience accumulates, however, you may realise that you've become wiser. Perhaps that naming convention wasn't such a good idea after all. </p> <p> When that happens, change the convention. Don't worry that this is going to make the code base inconsistent. An improvement is an improvement, while consistency might only imply that the code base is consistently bad. </p> <h3 id="0246a2c2c5754c48a008a613c91e6dab"> Explicit variable declaration versus var <a href="#0246a2c2c5754c48a008a613c91e6dab" title="permalink">#</a> </h3> <p> In late 2007, more than a decade ago, C# 3 introduced the <code>var</code> keyword to the language. This tells the compiler to automatically <a href="https://en.wikipedia.org/wiki/Type_inference">infer</a> the static type of a variable. Before that, you'd have to explicitly declare the type of all variables: </p> <p> <pre><span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">href</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;UrlBuilder() &nbsp;&nbsp;&nbsp;&nbsp;.WithAction(nameof(CalendarController.Get)) &nbsp;&nbsp;&nbsp;&nbsp;.WithController(nameof(CalendarController)) &nbsp;&nbsp;&nbsp;&nbsp;.WithValues(<span style="color:blue;">new</span>&nbsp;{&nbsp;year&nbsp;=&nbsp;DateTime.Now.Year&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;.BuildAbsolute(Url);</pre> </p> <p> In the above example, the variable <code>href</code> is explicitly declared as a <code>string</code>. With the <code>var</code> keyword you can alternatively write the expression like this: </p> <p> <pre><span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">href</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;UrlBuilder() &nbsp;&nbsp;&nbsp;&nbsp;.WithAction(nameof(CalendarController.Get)) &nbsp;&nbsp;&nbsp;&nbsp;.WithController(nameof(CalendarController)) &nbsp;&nbsp;&nbsp;&nbsp;.WithValues(<span style="color:blue;">new</span>&nbsp;{&nbsp;year&nbsp;=&nbsp;DateTime.Now.Year&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;.BuildAbsolute(Url);</pre> </p> <p> The <code>href</code> variable is still statically typed as a <code>string</code>. The compiler figures that out for you, in this case because the <code>BuildAbsolute</code> method returns a <code>string</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#74531f;">BuildAbsolute</span>(IUrlHelper&nbsp;<span style="color:#1f377f;">url</span>)</pre> </p> <p> These two alternatives are interchangeable. They compile to the same <a href="https://en.wikipedia.org/wiki/Common_Intermediate_Language">IL code</a>. </p> <p> When C# introduced this language feature, a year-long controversy erupted. Opponents felt that using <code>var</code> made code less readable. This isn't an entirely unreasonable argument, but most C# programmers subsequently figured that the advantages of using <code>var</code> outweigh the disadvantages. </p> <p> A major advantage is that using <code>var</code> better facilitates refactoring. Sometimes, for example, you decide to change the return type of a method. What happens if you change the return type of <a href="/2020/08/10/an-aspnet-core-url-builder">UrlBuilder</a>? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;Uri&nbsp;<span style="color:#74531f;">BuildAbsolute</span>(IUrlHelper&nbsp;<span style="color:#1f377f;">url</span>)</pre> </p> <p> If you've used the <code>var</code> keyword, the compiler just infers a different type. If, on the other hand, you've explicitly declared <code>href</code> as a <code>string</code>, that piece of code no longer compiles. </p> <p> Using the <code>var</code> keyword makes refactoring easier. You'll still need to edit some call sites when you make a change like this, because <code>Uri</code> affords a different API than <code>string</code>. The point, however, is that when you use <code>var</code>, the cost of making a change is lower. Less <a href="/2019/12/16/zone-of-ceremony">ceremony</a> means that you can spend your effort where it matters. </p> <p> In the context of coding styles, I still, more than a decade after the <code>var</code> keyword was introduced, encounter code bases that use explicit variable declaration. </p> <p> When I explain the advantages of using the <code>var</code> keyword to the team responsible for the code base, they may agree in principle, but still oppose using it in practice. The reason? Using <code>var</code> would make the code base inconsistent. </p> <p> Aiming for a consistent coding style is fine, but only as long as it doesn't prohibit improvements. Don't let it stand in the way of progress. </p> <h3 id="83bc13f15fe04b829b25002f39575bb2"> Habitability <a href="#83bc13f15fe04b829b25002f39575bb2" title="permalink">#</a> </h3> <p> I don't mind consistency; in fact, I find it quite attractive. It must not, however, become a barrier to improvement. </p> <p> I've met programmers who so strongly favour consistency that they feel that, in order to change coding style, they'd have to go through the entire code base and retroactively update it all to fit the new rule. This is obviously prohibitively expensive to do, so practically it prevents change. </p> <p> Consistency is fine, but learn to accept inconsistency. As Nat Pryce said, we should learn to love the mess, to adopt a philosophy akin to <a href="https://en.wikipedia.org/wiki/Wabi-sabi">wabi-sabi</a>. </p> <p> I think this view on inconsistent code helped me come to grips with my own desire for neatness. An inconsistent code base looks <em>inhabited</em>. I don't mind looking around in a code base and immediately being able to tell: <em>oh, Anna wrote this</em>, or <em>Nader is the author of this method</em>. </p> <p> What's more important is that the code is comprehensible. </p> <h3 id="8382ebd1ba1d4c60abb984f87dc9c317"> Conclusion <a href="#8382ebd1ba1d4c60abb984f87dc9c317" title="permalink">#</a> </h3> <p> Consistency in code isn't a bad thing. Coding styles can help encourage a degree of consistency. I think that's fine. </p> <p> On the other hand, consistency shouldn't be the highest goal of a code base. If improving the code makes a code base inconsistent, I think that the improvement should trump consistency every time. </p> <p> Let the old code be as it is, until you need to work with it. When you do, you can apply Robert C. Martin's boy scout rule: <em>Always leave the code cleaner than you found it</em>. Code perfection is like eventual consistency; it's something that you should constantly move towards, yet may never attain. </p> <p> Learn to appreciate the 'lived-in' quality of an active code base. </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>. Simplifying code with Decorated Commands https://blog.ploeh.dk/2021/05/10/simplifying-code-with-decorated-commands 2021-05-10T05:37:00+00:00 Mark Seemann <div id="post"> <p> <em>Consider modelling many side effects as a single Command.</em> </p> <p> In a <a href="/2021/04/26/leaky-abstraction-by-omission">previous article I discussed how an abstraction can sometimes be leaky by omission</a>. In this article, you'll see how removing the leak enables some beneficial refactoring. I'm going to assume that you've read the previous article. </p> <p> <ins datetime="2021-06-15T06:14Z">The code shown here is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> <h3 id="7d89e80085aa44edaf169962232a078a"> The relative cost of the four CRUD operations <a href="#7d89e80085aa44edaf169962232a078a" title="permalink">#</a> </h3> <p> In this article, you'll see code that implements an ASP.NET Controller action. It enables a <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> client to update an existing reservation via a <code>PUT</code> request. </p> <p> I chose to show you the <code>Put</code> method because it's the worst, and thereby the one where refactoring is most warranted. This seems to follow a pattern I've noticed over the years: data updates are always the worst. </p> <p> Before I show you the code, I'd like to take a little detour to discuss this observation. </p> <p> Consider the four <a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> operations. Which one is the easiest to implement and maintain, and which one gives you most grief? </p> <p> <em>Deletes</em> are typically straightforward: A unique identifier is all it takes. The only small complication you may have to consider is <a href="https://en.wikipedia.org/wiki/Idempotence">idempotence</a>. If you delete an entity once, it's gone. What should happen if you 'delete' it again? To be clear, I don't consider this a trick question. A delete operation should be idempotent, but sometimes, depending on the underlying storage technology, you may have to write a few lines of code to make that happen. </p> <p> <em>Reads</em> are a little more complicated. I'm actually not sure if reads are more or less involved than <em>create</em> operations. The complexity is probably about the same. Reading a single document from a document database is easy, as is reading a single row from a database. Relational databases can make this a bit harder when you have to join tables, but when you get the hang of it, it's not that hard. </p> <p> <em>Create</em> operations tend to be about as easy or difficult as reads. Adding a new document to a document database or BLOB storage is easy. Adding a complex entity with foreign key relationships in a relational database is a bit more complicated, but still doable. </p> <p> <em>Updates</em>, though, are evil. In a document database, it may be easy enough if you can just replace the document wholesale. Often, however, updates involves delta detection. Particularly in databases, when foreign keys are involved, you may have to recursively track down all the related rows and either update those as well, or delete and recreate them. </p> <p> As you'll see in the upcoming code example, an update typically also involves complicated auxiliary logic to determine what changed, and how to react to it. </p> <p> For that reason, if possible, I prefer modelling data without supporting updates. Create/read/delete is fine, but if you don't support updates, you may not need deletes either. There's a reason I like Event Sourcing. </p> <h3 id="530a01b1e4e24a5e9af0d8e87d8cacf6"> A complicated Put method <a href="#530a01b1e4e24a5e9af0d8e87d8cacf6" title="permalink">#</a> </h3> <p> My restaurant reservation API included this method that enabled REST clients to update reservations: </p> <p> <pre>[HttpPut(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/reservations/{id}&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&lt;ActionResult&gt;&nbsp;<span style="color:#74531f;">Put</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">id</span>, &nbsp;&nbsp;&nbsp;&nbsp;ReservationDto&nbsp;<span style="color:#1f377f;">dto</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(dto&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(dto)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!Guid.TryParse(id,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">rid</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;NotFoundResult(); &nbsp;&nbsp;&nbsp;&nbsp;Reservation?&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;=&nbsp;dto.Validate(rid); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(reservation&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;BadRequestResult(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">restaurant</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;RestaurantDatabase &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.GetRestaurant(restaurantId).ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(restaurant&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;NotFoundResult(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;TryUpdate(restaurant,&nbsp;reservation).ConfigureAwait(<span style="color:blue;">false</span>); }</pre> </p> <p> Had I written this code exclusively for myself, I'd written in a more functional style, as an <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a>. (Actually, had I written this code exclusively for myself, I'd written it in <a href="https://fsharp.org">F#</a> or <a href="https://www.haskell.org">Haskell</a>.) This code, however, is written for another audience, so I didn't want to assume that the reader knows about impureim sandwiches. </p> <p> I still wanted to decompose the functionality into <a href="/2019/11/04/the-80-24-rule">small blocks</a>. There's still an echo of the impureim sandwich architecture in the <code>Put</code> method, because it handles most of the impure preparation - the top of the sandwich, so to speak. </p> <p> The rest - any functional core there might be, as well as impure post-processing - it delegates to the <code>TryUpdate</code> method. </p> <h3 id="fbbac35a68604f0ca221b0d4cc0f6743"> TryUpdate <a href="#fbbac35a68604f0ca221b0d4cc0f6743" title="permalink">#</a> </h3> <p> Here's the <code>TryUpdate</code> method: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&lt;ActionResult&gt;&nbsp;<span style="color:#74531f;">TryUpdate</span>( &nbsp;&nbsp;&nbsp;&nbsp;Restaurant&nbsp;<span style="color:#1f377f;">restaurant</span>, &nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">scope</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TransactionScope( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TransactionScopeAsyncFlowOption.Enabled); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">existing</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.ReadReservation(reservation.Id) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existing&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;NotFoundResult(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">ok</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;WillAcceptUpdate(restaurant,&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!ok) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;NoTables500InternalServerError(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Update(restaurant,&nbsp;reservation,&nbsp;existing) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;scope.Complete(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;OkObjectResult(reservation.ToDto()); }</pre> </p> <p> To be honest, this is mostly just more impure pre-processing. The functional core is hidden away inside the (impure) <code>WillAcceptUpdate</code> method, but I'm not going to show you that one. It's not important in this context. </p> <p> If, however, the method decides that the update is possible, it'll make one more delegation, to the <code>Update</code> method. </p> <p> I admit it: This isn't the prettiest code I've ever written. I did warn you, though. I chose this method as an example because it could really do with some refactoring. One problem I have with it is the naming. You have a <code>Put</code> method, which calls a <code>TryUpdate</code> method, which again calls an <code>Update</code> method. </p> <p> Even though the <em>Try</em> prefix is a .NET <a href="/2015/08/03/idiomatic-or-idiosyncratic">idiom</a>, I still feel that a regular reader could be easily confused, having to choose between <code>TryUpdate</code> and <code>Update</code>. </p> <p> Still, let's soldier on and review the <code>Update</code> method as well. It's the last one, I promise. </p> <h3 id="4f28399e4ca64ab796446932136c5d7e"> Update <a href="#4f28399e4ca64ab796446932136c5d7e" title="permalink">#</a> </h3> <p> Here's the <code>Update</code> method: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">Update</span>( &nbsp;&nbsp;&nbsp;&nbsp;Restaurant&nbsp;<span style="color:#1f377f;">restaurant</span>, &nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>, &nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">existing</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existing.Email&nbsp;!=&nbsp;reservation.Email) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;PostOffice &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.EmailReservationUpdating(restaurant.Id,&nbsp;existing) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.Update(reservation).ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;PostOffice &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.EmailReservationUpdated(restaurant.Id,&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); }</pre> </p> <p> The method perfectly illustrates what I meant when I wrote that you often have to do various kinds of delta analysis when implementing an update - even if delta analysis isn't required by the data store. </p> <p> This method does two things: <ul> <li>It sends emails</li> <li>It updates the repository</li> </ul> Notice that if the email address changes, <code>Update</code> sends an email to the old address. This is an example of delta analysis. This only happens on a changing email address. It doesn't happen if the name or quantity changes. </p> <p> The motivation is that it may serve to warn the user if someone tries to change the reservation. Only when the email address changes is it necessary to send an email to the old address. </p> <p> In all cases, the method sends an email to the 'current' address. </p> <p> This seems ripe for refactoring. </p> <h3 id="7d446d5e2d1647a49a22b4be7953e1c7"> Plugging the leak <a href="#7d446d5e2d1647a49a22b4be7953e1c7" title="permalink">#</a> </h3> <p> The <code>Update</code> method is an asynchronous <a href="https://en.wikipedia.org/wiki/Command%E2%80%93query_separation">Command</a>. It exclusively produces side effects, but it doesn't return anything (we'll regard <code>Task</code> as 'asynchronous <a href="/2018/01/15/unit-isomorphisms">unit</a>'). </p> <p> I've <a href="/2011/03/22/CommandsareComposable">known since 2011 that Commands are composable</a>. Later, I also figured out <a href="/2019/01/28/better-abstractions-revisited">the fundamental reason for that</a>. </p> <p> The <code>Update</code> method composes three other Commands - one conditional and two unconditional. This seems to call for some sort of composition: <a href="https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern">Chain of Responsibility</a>, <a href="https://en.wikipedia.org/wiki/Decorator_pattern">Decorator</a>, or <a href="https://en.wikipedia.org/wiki/Composite_pattern">Composite</a>. Common to these patterns, however, is that the object that they compose must share an API. In a language like C# it means that they must share a polymorphic type. </p> <p> Which type might that be? Let's list the three method signatures in action, one after the other: <ul> <li> <code>Task&nbsp;<span style="color:#74531f;">EmailReservationUpdating</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>)</code> </li> <li> <code>Task&nbsp;<span style="color:#74531f;">Update</span>(Reservation&nbsp;<span style="color:#1f377f;">reservation</span>)</code> </li> <li> <code>Task&nbsp;<span style="color:#74531f;">EmailReservationUpdated</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>)</code> </li> </ul> Do these three methods have anything in common? </p> <p> The commonality might be easier to spot if we X out the names (<a href="/2020/11/23/good-names-are-skin-deep">which are only skin-deep</a>, anyway): <ul> <li> <code>Task&nbsp;<span style="color:#74531f;">Xxx</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>)</code> </li> <li> <code>Task&nbsp;<span style="color:#74531f;">Xxx</span>(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>)</code> </li> <li> <code>Task&nbsp;<span style="color:#74531f;">Xxx</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>)</code> </li> </ul> They <em>almost</em> look like each other! </p> <p> The only deviation is that the middle method (originally the <code>Update</code> method) lacks a <code>restaurantId</code> parameter. </p> <p> As the previous article explained, though, this is a <a href="/2021/04/26/leaky-abstraction-by-omission">leaky abstraction by omission</a>. Will plugging the leak enable a refactoring? </p> <p> Let's try. Make <code>restaurantId</code> a parameter for all methods defined by the interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReservationsRepository</span> { &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Create</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;Reservation?&gt;&nbsp;<span style="color:#74531f;">ReadReservation</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Guid&nbsp;<span style="color:#1f377f;">id</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Update</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Guid&nbsp;<span style="color:#1f377f;">id</span>); }</pre> </p> <p> This is the suggested remedy from the previous article, so I put it here solely as a reminder. </p> <h3 id="e5963702434c4674a39a99944d599522"> An emailing Decorator <a href="#e5963702434c4674a39a99944d599522" title="permalink">#</a> </h3> <p> There's a sequence to the actions in the <code>Update</code> method: <ol> <li>It emails the old address about a changing address</li> <li>It updates the reservation</li> <li>It emails the current address about the update</li> </ol> It's easiest to preserve this order of actions if you implement a <a href="https://en.wikipedia.org/wiki/Decorator_pattern">Decorator</a> around the new version of <code>IReservationsRepository</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">EmailingReservationsRepository</span>&nbsp;:&nbsp;IReservationsRepository { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">EmailingReservationsRepository</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPostOffice&nbsp;<span style="color:#1f377f;">postOffice</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IReservationsRepository&nbsp;<span style="color:#1f377f;">inner</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostOffice&nbsp;=&nbsp;postOffice; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Inner&nbsp;=&nbsp;inner; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IPostOffice&nbsp;PostOffice&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;IReservationsRepository&nbsp;Inner&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">Update</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(reservation&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;ArgumentNullException(nameof(reservation)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">existing</span>&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Inner.ReadReservation(restaurantId,&nbsp;reservation.Id) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existing&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}&nbsp;&amp;&amp;&nbsp;existing.Email&nbsp;!=&nbsp;reservation.Email) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;PostOffice &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.EmailReservationUpdating(restaurantId,&nbsp;existing) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Inner.Update(restaurantId,&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;PostOffice.EmailReservationUpdated(restaurantId,&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Other&nbsp;members&nbsp;go&nbsp;here...</span> }</pre> </p> <p> You may think that it seems odd to have a 'repository' that also sends emails. I think that this is mostly an artefact of unfortunate naming. Perhaps a follow-up change should be to rename both the interface and the Controller's <code>Repository</code> property. I'm open to suggestions, but for now, I'll leave the names as they are. </p> <p> If you're still not convinced, consider an alternative architecture based on asynchronous message passing (e.g. CQRS). In such architectures, you'd put Commands on a message bus and think no more of it. A background process would then asynchronously perform all the actions, including sending emails and updating the data store. I think that people used to that kind of architecture wouldn't bat an eyelid by <code>bus.Send(new UpdateReservation(/**/))</code>. </p> <p> This would also be close to the kind of design that <a href="https://blogs.cuttingedge.it/steven">Steven van Deursen</a> and I describe in chapter 10 of <a href="/dippp">our book</a>. </p> <h3 id="23ba3b2153ee43dabc4a0fa964627dc0"> Simplification <a href="#23ba3b2153ee43dabc4a0fa964627dc0" title="permalink">#</a> </h3> <p> This greatly simplifies things. The above <code>Update</code> method now becomes redundant and can be deleted. Instead, <code>TryUpdate</code> can now directly call <code>Repository.Update</code>: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&lt;ActionResult&gt;&nbsp;<span style="color:#74531f;">TryUpdate</span>( &nbsp;&nbsp;&nbsp;&nbsp;Restaurant&nbsp;<span style="color:#1f377f;">restaurant</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">scope</span>&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;TransactionScope( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TransactionScopeAsyncFlowOption.Enabled); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">existing</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;Repository &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ReadReservation(restaurant.Id,&nbsp;reservation.Id) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(existing&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;NotFoundResult(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">ok</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;WillAcceptUpdate(restaurant,&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(!ok) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;NoTables500InternalServerError(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.Update(restaurant.Id,&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;scope.Complete(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;OkObjectResult(reservation.ToDto()); }</pre> </p> <p> This also means that you can remove the <code>PostOffice</code> dependency from the Controller. Lots of things becomes simpler by this refactoring. It better separates concerns, so tests become simpler as well. </p> <h3 id="90227dd1059f432f9573cfe3c2553507"> Conclusion <a href="#90227dd1059f432f9573cfe3c2553507" title="permalink">#</a> </h3> <p> You can simplify code by composing Commands. Candidate patterns for this are Chain of Responsibility, Decorator, and Composite. These patterns, however, require a common polymorphic type. Key to refactoring to these patterns is to identify such a common interface. In this article, I used the refactored <code>IReservationsRepository</code> interface. </p> <p> Whenever a client calls a method on the repository, a change of state now automatically also sends emails. The client doesn't have to worry about that. </p> <p> Consider modelling many related side-effects as a single composed Command. </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>. Structural equality for better tests https://blog.ploeh.dk/2021/05/03/structural-equality-for-better-tests 2021-05-03T05:45:00+00:00 Mark Seemann <div id="post"> <p> <em>A Fluent Builder as a Value Object?</em> </p> <p> If you've read a bit about unit testing, test-driven development, or other kinds of developer testing, you've probably come across a phrase like this: <blockquote> Test behaviour, not implementation. </blockquote> It's often taken to mean something like <a href="https://en.wikipedia.org/wiki/Behavior-driven_development">behaviour-driven development</a> (BDD), and that's certainly one interpretation. I've no problem with that. My own Pluralsight course <a href="/outside-in-tdd">Outside-In Test-Driven Development</a> shows a similar technique. </p> <p> It'd be a logical fallacy, however, to thereby conclude that you can only apply that ideal in the large, but not in the small. That it's only possible to do it with coarse-grained tests at the boundary of the system, but not with unit testing. </p> <p> It may be harder to do at the unit level, since when writing unit tests, you're closer to the implementation, so to speak. Writing the test before the implementation may, however, help </p> <p> <ins datetime="2021-06-15T06:14Z">The code shown here is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> <h3 id="fc448a62f581457392f12bd1fe2d273d"> An example test <a href="#fc448a62f581457392f12bd1fe2d273d" title="permalink">#</a> </h3> <p> Here's a test (using <a href="https://xunit.net">xUnit.net</a> 2.4.1) I wrote before the implementation: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;Home&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Calendar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Reservations&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">WithControllerHandlesSuffix</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">name</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;UrlBuilder(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.WithController(name&nbsp;+&nbsp;<span style="color:#a31515;">&quot;Controller&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;sut.WithController(name); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected,&nbsp;actual); }</pre> </p> <p> It tests an <a href="/2020/08/10/an-aspnet-core-url-builder">ASP.NET Core URL Builder</a>; particular how it deals with the <code>Controller</code> <a href="/2020/08/03/using-the-nameof-c-keyword-with-aspnet-3-iurlhelper">suffix issue I ran into last year</a>. </p> <p> Do you notice something odd about this test? </p> <p> It describes an equality relation between two individual projections of an initial <code>UrlBuilder</code> object (<a href="https://docs.microsoft.com/en-us/archive/blogs/ploeh/naming-sut-test-variables">sut</a>). </p> <p> First of all, with a <a href="/2020/02/10/builder-isomorphisms">Mutable Fluent Builder</a> the test would produce a <a href="http://xunitpatterns.com/false%20negative.html">false negative</a> because <a href="https://en.wikipedia.org/wiki/Aliasing_(computing)">aliasing</a> would make the assertion a <a href="/2019/10/14/tautological-assertion">tautological assertion</a>. Using an <a href="/2020/02/10/builder-isomorphisms">Immutable Fluent Builder</a>, however, elegantly dodges that bullet: <code>expected</code> and <code>actual</code> are two separate objects. </p> <p> Yet, it's possible to compare them. How? </p> <h3 id="ef79a890e2c3494d88f0202b687a8633"> Assertions <a href="#ef79a890e2c3494d88f0202b687a8633" title="permalink">#</a> </h3> <p> I think that most people would have written the above test like this: </p> <p> <pre>[Theory] [InlineData(<span style="color:#a31515;">&quot;Home&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Calendar&quot;</span>)] [InlineData(<span style="color:#a31515;">&quot;Reservations&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">WithControllerHandlesSuffix</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">name</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;UrlBuilder(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;sut.WithController(name&nbsp;+&nbsp;<span style="color:#a31515;">&quot;Controller&quot;</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">expected</span>&nbsp;=&nbsp;sut.WithController(name); &nbsp;&nbsp;&nbsp;&nbsp;Assert.Equal(expected.Controller,&nbsp;actual.Controller); }</pre> </p> <p> Instead of comparing two whole objects, this variation compares the <code>Controller</code> property values from two objects. In order for this to compile, you have to expose an implementation detail: that the class has a class field (here exposed as an <a href="/2011/05/26/CodeSmellAutomaticProperty">automatic property</a>) that keeps track of the Controller name. </p> <p> I think that most object-oriented programmers' default habit is to write assertions that compare properties or class fields because in both C# and Java, objects by default only have reference equality. This leads to <a href="/2011/05/25/DesignSmellPrimitiveObsession">primitive obsession</a>, this time in the context of test assertions. </p> <p> Structural equality, on the other hand, makes it much easier to write concise and meaningful assertions. Just compare <code>expected</code> with <code>actual</code>. </p> <h3 id="b140911476e341dc83c421dc6eed70b3"> Structural equality on a Builder? <a href="#b140911476e341dc83c421dc6eed70b3" title="permalink">#</a> </h3> <p> The <code>UrlBuilder</code> class has structural equality by overriding <code>Equals</code> and <code>GetHashCode</code>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>?&nbsp;<span style="color:#1f377f;">obj</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;UrlBuilder&nbsp;<span style="color:#1f377f;">builder</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action&nbsp;==&nbsp;builder.action&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controller&nbsp;==&nbsp;builder.controller&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EqualityComparer&lt;<span style="color:blue;">object</span>?&gt;.Default.Equals(values,&nbsp;builder.values); } <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;HashCode.Combine(action,&nbsp;controller,&nbsp;values); }</pre> </p> <p> That's why the above <code>Assert.Equal</code> statement works. </p> <p> You may think that it's an odd choice to give a Fluent Builder structural equality, but why not? Since it's immutable, it's perfectly safe, and it makes things like testing much easier. </p> <p> I rarely see people do this. Even programmers experienced with functional programming often seem to categorise structural equality as something associated exclusively with <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">algebraic data types</a> (ADTs). The <code>UrlBuilder</code> class, on the other hand, doesn't look like an ADT. After all, its public API exposes only behaviour, but no data: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">UrlBuilder</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">UrlBuilder</span>() &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;UrlBuilder&nbsp;<span style="color:#74531f;">WithAction</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">newAction</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;UrlBuilder&nbsp;<span style="color:#74531f;">WithController</span>(<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">newController</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;UrlBuilder&nbsp;<span style="color:#74531f;">WithValues</span>(<span style="color:blue;">object</span>&nbsp;<span style="color:#1f377f;">newValues</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;Uri&nbsp;<span style="color:#74531f;">BuildAbsolute</span>(IUrlHelper&nbsp;<span style="color:#1f377f;">url</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>?&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() }</pre> </p> <p> On the other hand, my threshold for when I give an immutable class structural equality is <a href="https://en.wikipedia.org/wiki/Monotonic_function">monotonically decreasing</a>. Structural equality just makes things easier. The above test is just one example. Structural equality enables you to test behaviour instead of implementation details. In this example, the behaviour can be expressed as an equality relation between two different inputs. </p> <h3 id="3843708f89fe46769d7c49af2977bf19"> UrlBuilder as an algebraic data type <a href="#3843708f89fe46769d7c49af2977bf19" title="permalink">#</a> </h3> <p> While it may seem odd or surprising to give a Fluent Builder structural equality, it's really isomorphic to a simple record type equipped with a few <a href="https://en.wikipedia.org/wiki/Endomorphism">endomorphisms</a>. (After all, we already know that <a href="/2020/02/17/builder-as-a-monoid">the Builder pattern is isomorphic to the endomorphism monoid</a>.) Let's make this explicit with <a href="https://fsharp.org">F#</a>. </p> <p> Start by declaring a record type with a <code>private</code> definition: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;UrlBuilder&nbsp;=&nbsp;<span style="color:blue;">private</span>&nbsp;{&nbsp;Action&nbsp;:&nbsp;string&nbsp;option;&nbsp;Controller&nbsp;:&nbsp;string&nbsp;option;&nbsp;Values&nbsp;:&nbsp;obj&nbsp;option&nbsp;}</pre> </p> <p> While its definition is <code>private</code>, it's still an algebraic data type. Records in F# automatically have structural equality, and so does this one. </p> <p> Since it's <code>private</code>, client code can't use the normal language constructs to create instances. Instead, the module that defines the type must supply an API that client code can use: </p> <p> <pre><span style="color:blue;">let</span>&nbsp;emptyUrlBuilder&nbsp;=&nbsp;{&nbsp;Action&nbsp;=&nbsp;None;&nbsp;Controller&nbsp;=&nbsp;None;&nbsp;Values&nbsp;=&nbsp;None&nbsp;} <span style="color:blue;">let</span>&nbsp;withAction&nbsp;action&nbsp;ub&nbsp;=&nbsp;{&nbsp;ub&nbsp;<span style="color:blue;">with</span>&nbsp;Action&nbsp;=&nbsp;Some&nbsp;action&nbsp;} <span style="color:blue;">let</span>&nbsp;withController&nbsp;(controller&nbsp;:&nbsp;string)&nbsp;ub&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;index&nbsp;=&nbsp;controller.LastIndexOf&nbsp;(<span style="color:#a31515;">&quot;controller&quot;</span>,&nbsp;StringComparison.OrdinalIgnoreCase) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;newController&nbsp;=&nbsp;<span style="color:blue;">if</span>&nbsp;0&nbsp;&lt;=&nbsp;index&nbsp;<span style="color:blue;">then</span>&nbsp;controller.Remove(index)&nbsp;<span style="color:blue;">else</span>&nbsp;controller &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;ub&nbsp;<span style="color:blue;">with</span>&nbsp;Controller&nbsp;=&nbsp;Some&nbsp;newController&nbsp;} <span style="color:blue;">let</span>&nbsp;withValues&nbsp;values&nbsp;ub&nbsp;=&nbsp;{&nbsp;ub&nbsp;<span style="color:blue;">with</span>&nbsp;Values&nbsp;=&nbsp;Some&nbsp;values&nbsp;}</pre> </p> <p> Without further <a href="/2019/12/16/zone-of-ceremony">ceremony</a> you can port the initial test to F# as well: </p> <p> <pre>[&lt;Theory&gt;] [&lt;InlineData(<span style="color:#a31515;">&quot;Home&quot;</span>)&gt;] [&lt;InlineData(<span style="color:#a31515;">&quot;Calendar&quot;</span>)&gt;] [&lt;InlineData(<span style="color:#a31515;">&quot;Reservations&quot;</span>)&gt;] <span style="color:blue;">let</span>&nbsp;``withController&nbsp;handles&nbsp;suffix``&nbsp;name&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;sut&nbsp;=&nbsp;emptyUrlBuilder &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;actual&nbsp;=&nbsp;sut&nbsp;|&gt;&nbsp;withController&nbsp;(name&nbsp;+&nbsp;<span style="color:#a31515;">&quot;Controller&quot;</span>) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;expected&nbsp;=&nbsp;sut&nbsp;|&gt;&nbsp;withController&nbsp;name &nbsp;&nbsp;&nbsp;&nbsp;expected&nbsp;=!&nbsp;actual</pre> </p> <p> In addition to xUnit.net this test also uses <a href="https://github.com/SwensenSoftware/unquote">Unquote</a> 6.0.0. </p> <p> Even though <code>UrlBuilder</code> has no externally visible data, it automatically has structural equality. <a href="/2015/05/07/functional-design-is-intrinsically-testable">Functional programming is, indeed, more test-friendly</a> than object-oriented programming. </p> <p> This F# implementation is equivalent to the <a href="/2020/08/10/an-aspnet-core-url-builder">C# UrlBuilder class</a>. </p> <h3 id="a59f8b304431456d94ef47e4a4481542"> Conclusion <a href="#a59f8b304431456d94ef47e4a4481542" title="permalink">#</a> </h3> <p> You can safely give immutable objects structural equality. Besides other advantages, it makes it easier to write tests. With structural equality, you can express a relationship between the expected and actual outcome using high-level language. </p> <p> These days, I don't really care if the type in question is a 'proper' algebraic data type. If it's immutable, I don't have to think much about it before giving it structural equality. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="f71a94b456de4458bf99690bdf3c7376"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <blockquote> Records in F# automatically have structural equality, and so does this one. </blockquote> <p> That is mostly true but not compeltely so. Consider the type </p> <p> <code>type MyRecord = { MyField: int -> bool }</code> </p> <p> If you try to compare two instances with F#'s <code>=</code> operator, then you will get this compilier error. </p> <blockquote> Error FS0001: The type 'MyRecord' does not support the 'equality' constraint because it is a record, union or struct with one or more structural element types which do not support the 'equality' constraint. Either avoid the use of equality with this type, or add the 'StructuralEquality' attribute to the type to determine which field type does not support equality. </blockquote> <p> Adding the <code>StructuralEquality</code> attribute results in this compiler error. </p> <blockquote> Error FS1180: The struct, record or union type 'MyRecord' has the 'StructuralEquality' attribute but the component type '(int -> bool)' does not satisfy the 'equality' constraint. </blockquote> <p> I learned all this the hard way. I had added some F# functions to some of my models in my MVU architecture. Later when I tried to test my root model for structual equality, I ran into this issue. Taking the suggestion in the compiler error, I fixed the problem by adding the <code>StructuralEquality</code> attribute (as well as the <code>NoComparison</code> attribute) to my root model and refactored the code to fix the resulting compiler errors. </p> <p> During this time, I also realized that F#'s structual equality delegates to <code>object.Equals(object)</code> for types that extend <code>object</code>, which of course defaults to reference equality. For example, the following code compiles. </p> <p> <code>[&lt;StructuralEquality&gt;] [&lt;NoComparison&gt;] type MyRecord = { MyField: IDisposable }</code> </p> </div> <div class="comment-date">2021-05-04 11:49 UTC</div> </div> <div class="comment" id="ffedaf2b35744c439311d04f2adc0631"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tyson, thank you for writing. Yes, you're right. Language is imprecise. F# records automatically have structural equality, when possible. </p> </div> <div class="comment-date">2021-05-05 4:48 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>. Leaky abstraction by omission https://blog.ploeh.dk/2021/04/26/leaky-abstraction-by-omission 2021-04-26T15:10:00+00:00 Mark Seemann <div id="post"> <p> <em>Sometimes, an abstraction can be leaky because it leaves something out.</em> </p> <p> Consider the following interface definition. What's wrong with it? </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReservationsRepository</span> { &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Create</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;Reservation?&gt;&nbsp;<span style="color:#74531f;">ReadReservation</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Update</span>(Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>); }</pre> </p> <p> Perhaps you think that the name is incorrect; that this really isn't an example of the Repository design pattern, as it's described in <a href="http://bit.ly/patternsofeaa">Patterns of Enterprise Application Architecture</a>. Ironically, of all patterns, it may be the one most affected by <a href="https://martinfowler.com/bliki/SemanticDiffusion.html">semantic diffusion</a>. </p> <p> That's not what I have in mind, though. There's something else with that interface. </p> <p> It's not its <a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> design, either. You could consider that a leaky abstraction, since it strongly implies a sort of persistent data store. That's a worthwhile discussion, but not what I have in mind today. There's something else wrong with the interface. </p> <h3 id="998668fec2d9488db5a31a99c0c81774"> Consistency <a href="#998668fec2d9488db5a31a99c0c81774" title="permalink">#</a> </h3> <p> Look closer at the parameters for the various methods. The <code>Create</code> and <code>ReadReservations</code> methods take a <code>restaurantId</code> parameter, but the other three don't. </p> <p> Why does the <code>ReadReservations</code> method take a <code>restaurantId</code> while <code>ReadReservation</code> doesn't? Why is that parameter required for <code>Create</code>, but not for <code>Update</code>? That doesn't seem consistent. </p> <p> The reason is that each reservation has an ID (a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">GUID</a>). Once the reservation exists, you can uniquely identify it to read, update, or delete it. </p> <p> As the <code>restaurantId</code> parameter suggests, however, this interface is part of a multi-tenant code base. This code base implements an online restaurant reservation system as a <a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> API. It's an online service where each restaurant is a separate tenant. </p> <p> While each reservation has a unique ID, the system still needs to associate it with a restaurant. Thus, the <code>Create</code> method must take a <code>restaurantId</code> parameter in order to associate the reservation with a restaurant. </p> <p> Once the reservation is stored, however, it's possible to uniquely identify it with the ID. The <code>ReadReservation</code>, <code>Update</code>, and <code>Delete</code> methods need only the <code>id</code> to work. </p> <p> On the other hand, when you're <em>not</em> querying on reservation ID, you'll need to identify the restaurant, as with the <code>ReadReservations</code> methods. If you didn't identify the restaurant in that method, you'd get all reservations in the requested range, from all tenants. That's not what you want. Therefore, you must supply the <code>restaurantId</code> to limit the query. </p> <p> The interface is inconsistent, but also allows the underlying implementation to leak through. </p> <h3 id="d270b5a98c7644389bc662287d8aa37e"> Implied implementation detail <a href="#d270b5a98c7644389bc662287d8aa37e" title="permalink">#</a> </h3> <p> If I told you that the implementation of <code>IReservationsRepository</code> is based on a relational database, can you imagine the design? You may want to stop reading and see if you can predict what the database looks like. </p> <p> The interface strongly implies a design like this: </p> <p> <pre><span style="color:blue;">CREATE</span>&nbsp;<span style="color:blue;">TABLE</span>&nbsp;[dbo]<span style="color:gray;">.</span>[Reservations]<span style="color:blue;">&nbsp;</span><span style="color:gray;">(</span> &nbsp;&nbsp;&nbsp;&nbsp;[Id]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">INT</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">IDENTITY&nbsp;</span><span style="color:gray;">(</span>1<span style="color:gray;">,</span>&nbsp;1<span style="color:gray;">)</span>&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL,</span> &nbsp;&nbsp;&nbsp;&nbsp;[At]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">DATETIME2&nbsp;</span><span style="color:gray;">(</span>7<span style="color:gray;">)</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL,</span> &nbsp;&nbsp;&nbsp;&nbsp;[Name]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">NVARCHAR&nbsp;</span><span style="color:gray;">(</span>50<span style="color:gray;">)</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL,</span> &nbsp;&nbsp;&nbsp;&nbsp;[Email]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">NVARCHAR&nbsp;</span><span style="color:gray;">(</span>50<span style="color:gray;">)</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL,</span> &nbsp;&nbsp;&nbsp;&nbsp;[Quantity]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">INT</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL,</span> &nbsp;&nbsp;&nbsp;&nbsp;[PublicId]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">UNIQUEIDENTIFIER</span>&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL,</span> &nbsp;&nbsp;&nbsp;&nbsp;[RestaurantId]&nbsp;<span style="color:blue;">INT</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray;">NOT</span>&nbsp;<span style="color:gray;">NULL,</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">PRIMARY</span>&nbsp;<span style="color:blue;">KEY</span>&nbsp;<span style="color:blue;">CLUSTERED&nbsp;</span><span style="color:gray;">(</span>[Id]&nbsp;<span style="color:blue;">ASC</span><span style="color:gray;">),</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">CONSTRAINT</span>&nbsp;[AK_PublicId]&nbsp;<span style="color:blue;">UNIQUE</span>&nbsp;<span style="color:blue;">NONCLUSTERED&nbsp;</span><span style="color:gray;">(</span>[PublicId]&nbsp;<span style="color:blue;">ASC</span><span style="color:gray;">)</span> <span style="color:gray;">);</span></pre> </p> <p> What I wrote above is even clearer now. You can't create a row in that table without supplying a <code>RestaurantId</code>, since that column has a <code>NOT NULL</code> constraint. </p> <p> The <code>PublicId</code> column has a <code>UNIQUE</code> constraint, which means that you can uniquely read and manipulate a single row when you have an ID. </p> <p> Since all reservations are in a single table, any query <em>not</em> based on <code>PublicId</code> should also filter on <code>RestaurantId</code>. If it doesn't, the result set could include reservations from all restaurants. </p> <h3 id="646f0fb2adf147c6bca42d9aada6cf43"> Other interpretations <a href="#646f0fb2adf147c6bca42d9aada6cf43" title="permalink">#</a> </h3> <p> Is the above relational database design the only possible implementation? Perhaps not. You could implement the interface based on a document database as well. It'd be natural to store each reservation as a separate document with a unique ID. Again, once you have the ID, you can directly retrieve and manipulate the document. </p> <p> Other implementations become harder, though. Imagine, for example, that you want to <a href="https://en.wikipedia.org/wiki/Shard_(database_architecture)">shard</a> the database design: Each restaurant gets a separate database. Or perhaps, more realistically, you distribute tenants over a handful of databases, perhaps partitioned on physical location, or some other criterion. </p> <p> With such a design, the <code>ReadReservation</code>, <code>Update</code>, and <code>Delete</code> methods become more inefficient. While you should be able to identify the correct shard if you have a restaurant ID, <em>you don't have that information.</em> Instead, you'll have to attempt the operation on all databases, thereby eliminating most sharding benefits. </p> <p> In other words, the <em>absence</em> of the <code>restaurantId</code> parameter from some of the methods suggests certain implementation details. </p> <h3 id="5edc25ddf2c8439096577e8eaf45806c"> Leak by omission <a href="#5edc25ddf2c8439096577e8eaf45806c" title="permalink">#</a> </h3> <p> I admit that I rarely run into this sort of problem. Usually, a leaky abstraction manifests by a language construct that contains <em>too much</em> information. This is typically an interface or base class that exposes implementation details by either requiring too specific inputs, or by returning data that reveals implementation details. </p> <p> For a data access abstraction like the above 'repository', this most frequently happens when people design such an interface around an <a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping">object-relational mapper</a> (ORM). A class like <code>Reservation</code> would then typically carry ORM details around. Perhaps it inherits from an ORM base class, or perhaps (this is very common) it has a parameterless constructor or getters and setters that model the relationships of the database (these are often called <em>navigation properties</em>). </p> <p> Another common examples of a leaky abstraction might be the presence of <code>Connect</code> and <code>Disconnect</code> methods. The <code>Connect</code> method may even take a <code>connectionString</code> parameter, clearly leaking that some sort of database is involved. </p> <p> Yet another example is <a href="/2014/08/11/cqs-versus-server-generated-ids">CQS-violating designs where a <code>Create</code> method returns a database ID</a>. </p> <p> All such leaky abstractions are leaky because they expose or require too much information. </p> <p> The example in this article, on the contrary, is leaky because of a lack of detail. </p> <h3 id="d6391eb7487d4b3ca38e4e5b1e868bd5"> Dependency Inversion Principle <a href="#d6391eb7487d4b3ca38e4e5b1e868bd5" title="permalink">#</a> </h3> <p> Ironically, I originally arrived at the above design because I followed the <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Dependency Inversion Principle</a> (DIP). The clients of <code>IReservationsRepository</code> are ASP.NET Controller actions, like this <code>Delete</code> method: </p> <p> <pre>[HttpDelete(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/reservations/{id}&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">id</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Guid.TryParse(id,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">rid</span>)) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.ReadReservation(rid) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.Delete(rid).ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(r&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;PostOffice.EmailReservationDeleted(restaurantId,&nbsp;r) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> As Robert C. Martin explains about the Dependency Inversion Principle: <blockquote> <p> "clients [...] own the abstract interfaces" </p> <footer><cite>Robert C. Martin, <a href="http://amzn.to/19W4JHk">APPP</a>, chapter 11</cite></footer> </blockquote> From that principle, it follows that the <code>Delete</code> method decides what <code>IReservationsRepository.Delete</code> looks like. It seems that the Controller action doesn't <em>need</em> to tell the <code>Repository</code> about the <code>restaurantId</code> when calling its <code>Delete</code> method. Supplying the reservation ID (<code>rid</code>) is enough. </p> <p> There are, however, various problems with the above code. If the DIP suggests that the <code>restaurantId</code> is redundant when calling <code>Repository.Delete</code>, then why is it required when calling <code>PostOffice.EmailReservationDeleted</code>? This seems inconsistent. </p> <p> Indeed it is. </p> <p> As I often do, I arrived at the above <code>Delete</code> method via <a href="/outside-in-tdd">outside-in TDD</a>, but as I observed a decade ago, <a href="/2010/12/22/TheTDDApostate">TDD alone doesn't guarantee good design</a>. Even when following the <a href="/2019/10/21/a-red-green-refactor-checklist">red-green-refactor checklist</a>, I often fail to spot problems right away. </p> <p> That's okay. TDD doesn't guarantee perfection, but done well it should set you up so that you can easily make changes. </p> <h3 id="b19d4f16b2ee48759c0e4d698a83cfdc"> Possible remedies <a href="#b19d4f16b2ee48759c0e4d698a83cfdc" title="permalink">#</a> </h3> <p> I can think of two ways to address the problem. The simplest solution is to make the interface consistent by adding a <code>restaurantId</code> parameter to all methods: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReservationsRepository</span> { &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Create</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;Reservation?&gt;&nbsp;<span style="color:#74531f;">ReadReservation</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Guid&nbsp;<span style="color:#1f377f;">id</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Update</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;Guid&nbsp;<span style="color:#1f377f;">id</span>); }</pre> </p> <p> This is the simplest solution, and the one that I prefer. In a future article, I'll show how it enabled me to significantly simplify the code base. </p> <p> For good measure, though, I should also mention the opposite solution. Completely drain the interface of <code>restaurantId</code> parameters: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReservationsRepository</span> { &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Create</span>(Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;Reservation?&gt;&nbsp;<span style="color:#74531f;">ReadReservation</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Update</span>(Reservation&nbsp;<span style="color:#1f377f;">reservation</span>); &nbsp;&nbsp;&nbsp;&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(Guid&nbsp;<span style="color:#1f377f;">id</span>); }</pre> </p> <p> How can that work in practice? After all, an implementation <em>must</em> have a restaurant ID in order to create a new row in the database. </p> <p> It's possible to solve that problem by making the <code>restaurantId</code> an implementation detail. You could make it a constructor parameter for the concrete class, but this gives you another problem. Your <a href="/2011/07/28/CompositionRoot">Composition Root</a> doesn't know the restaurant ID - after all, it's a run-time argument. </p> <p> In a method like the above <code>Delete</code> Controller action, you'd have to translate the <code>restaurantId</code> run-time argument to an <code>IReservationsRepository</code> instance. There are various ways around that kind of problem, but they typically involve some kind of <em>factory</em>. That'd be yet another interface: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReservationsRepositoryFactory</span> { &nbsp;&nbsp;&nbsp;&nbsp;IReservationsRepository&nbsp;<span style="color:#74531f;">Create</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>); }</pre> </p> <p> That just makes the API more complicated. Factories give <a href="/dippp">Dependency Injection</a> a bad reputation. For that reason, I don't like this second alternative. </p> <h3 id="ae975d7eff014d31b26ec78fa055f343"> Conclusion <a href="#ae975d7eff014d31b26ec78fa055f343" title="permalink">#</a> </h3> <p> Leaky abstractions usually express themselves as APIs that expose too many details; the implementation details leak through. </p> <p> In this example, however, a leaky abstraction manifested as a lack of consistency. Some methods require a <code>restaurantId</code> argument, while others don't - because one particular implementation doesn't need that information. </p> <p> It turned out, though, that when I was trying to simplify the overall code, this API design held me back. Consistently adding <code>restaurantId</code> parameters to all repository methods solved the problem. <a href="/2021/05/10/simplifying-code-with-decorated-commands">A future article tells that tale</a>. </p> <p> <ins datetime="2021-06-15T06:14Z">The code shown here is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="c081a58ac3ea4c63a481f07c1933f325"> <div class="comment-author"><a href="https://tobias.rocks">Tobias</a></div> <div class="comment-content"> <p>Thank you for the article Mark.</p> <p>I was wondering whether another solution would be including restaurantId as a member of Reservation? That way it’s not needed by the Create method. </p> <p>That just leaves ReadReservations as the last method that requires a restaurant ID, but one could argue a specialized read method such as this one doesn’t belong on a repository anyway. I personally tend to interpret these kinds of methods on a repository as a code smell on projects of a certain size. </p> <p>I might just be missing the point of your article, but I would love to hear your thoughts. :)</p> </div> <div class="comment-date">2021-05-01 8:59 UTC</div> </div> <div class="comment" id="c30f63e0ba234d15acecb40800efc0ec"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Tobias, thank you for writing. You raise a good point, and it might be an appropriate way to model the problem. While the thought had already crossed my mind, I must admit that I hadn't given it much thought. </p> <p> For the individual CRUD operations, I admit that it might be an appropriate design option. You do, however, also point to the <code>ReadReservations</code> method as the odd man out. I applaud the intellectual honesty you exhibit by bring this up yourself, and I don't intend to misuse it by shooting down your idea. The fact that this method is somehow different might be an indication that it doesn't belong as a member of the same interface as the other four methods. </p> <p> If that's the case, though, then where does it belong? One option would be to <a href="/2014/03/10/solid-the-next-step-is-functional">define all interfaces with only a single method</a>: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IReservationsDateRangeQuery</span> { &nbsp;&nbsp;&nbsp;&nbsp;Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">min</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>); }</pre> </p> <p> How should we deal with the <code>restaurantId</code> parameter in such an interface? Should it be included, as is the case here, or should we exclude it from the interface definition, like the following? </p> <p> <pre> Task&lt;IReadOnlyCollection&lt;Reservation&gt;&gt;&nbsp;<span style="color:#74531f;">ReadReservations</span>(DateTime&nbsp;<span style="color:#1f377f;">min</span>,&nbsp;DateTime&nbsp;<span style="color:#1f377f;">max</span>);</pre> </p> <p> If we choose to exclude the <code>restaurantId</code> parameter from the interface, it'd be consistent with the CRUD interface that you imply. On the other hand, wouldn't it require some sort of factory, as <a href="#b19d4f16b2ee48759c0e4d698a83cfdc">I outlined above</a>? </p> <p> Conversely, if we decide to keep the <code>restaurantId</code> parameter as part of the interface definition, it seems inconsistent with the design your suggestion implies. </p> <p> I'm not writing this to shoot down your suggestion. I find it a real conundrum. </p> <p> I do think, though, that this might be an indication that there's some kind of abstraction that I've failed to make explicit. Some kind of <em>Restaurant</em> or <em>Tenant</em> type seems most likely. </p> <p> My problem is that <a href="/2020/10/19/monomorphic-functors">I actually do have a <code>Restaurant</code> class</a> in my code base. That one, however, is a <a href="https://en.wikipedia.org/wiki/Value_object">Value Object</a>, so I'm loath to add impure methods to it. </p> <p> For what it's worth, it's deliberation like this that makes software design interesting. You need to balance opposing forces. A good design is one that does so in a stable way. I'm not claiming that the code shown here does that. You've clearly put your finger on a sore spot, which suggests to me that there's more work to be done. Thank you for the inspiring input! </p> </div> <div class="comment-date">2021-05-02 11:04 UTC</div> </div> <div class="comment" id="d4ed2be3914e46b0a1cc3e2f986854d2"> <div class="comment-author">Thibaut</a></div> <div class="comment-content"> <p> Hi Mark, thank you for another great article! </p> <p> I have worked on several small multi-tenant systems and I faced the same problem as you with the repository interface methods and the "tenant id" being mixed. </p> <p> After several attempts and API iteration, my final design was to use what <em>Steven van Deursen</em> calls <a href="https://blogs.cuttingedge.it/steven/posts/2019/ambient-composition-model/">The Ambient Composition Model</a>. </p> <p> The idea is to inject an <code>ITenantContext</code> in the <code>IReservationsRepository</code> implementation and to use it as needed : </p> <p> <pre> public class ReservationsRepository : IReservationsRepository { private readonly ITenantContext _tenantContext; public ReservationRepository(ITenantContext tenantContext) { _tenantContext = tenantContex; } public Task Create(Reservation reservation) { var restaurantId = _tenantContext.RestaurantId; // ... } } </pre> </p> <p> In my case the implementation of the <code>ITenantContext</code> was retrieving the tenant from the route of the method. I think it could be the same for resolving the <code>restaurantId</code>. </p> <p> This solution seems similar to your Factory solution but I'm not totally sure. In any case, like the Factory solution, this solution is heavier that the first you proposed. </p> <p> Nonetheless I find some elegance in this solution with the tenant being injected by request in the implementation. What do you think? Did you have the same idea with the Factory solution? </p> </div> <div class="comment-date">2021-05-02 19:20 UTC</div> </div> <div class="comment" id="3104d83e33524adc9f4d349fa4df20ed"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Thibaut, thank you for writing. Yes, that's another option. I've done something similar to that in the past. </p> <p> In a sense, the concept of a <em>tenant</em> seems almost like a cross-cutting concern, so it makes sense to let it fade into the background, so to speak. </p> <p> The reason I'm not too keen on that any longer is that it seems a bit too 'clever' in most settings. Consider the <code>Delete</code> Controller action <a href="#d6391eb7487d4b3ca38e4e5b1e868bd5">shown above</a>. Imagine that we inject <code>restaurantId</code> into all services - not only <code>IReservationsRepository </code>, but also into <code>IPostOffice</code>. The <code>Delete</code> method might look like this, then: </p> <p> <pre>[HttpDelete(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/reservations/{id}&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">id</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Guid.TryParse(id,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">rid</span>)) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.ReadReservation(rid) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.Delete(rid).ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(r&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;PostOffice.EmailReservationDeleted(r) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The <code>restaurantId</code> parameter still has to be present, even though it's unused. This is likely to be puzzling to any developer not intimately familiar with the code base. </p> <p> It's possible that you can pull some trick with the ASP.NET framework so that the parameter doesn't have to be there, but it'll still be present in the URL, and again, I'm concerned that most developers would be confused about this. </p> <p> There's also another thing that bothers me about design like this: You can pull the restaurant ID out of the method's routing data, but this implies that you can do the same with the reservation ID. What makes the restaurant ID special, that it ought to be an injected dependency, while the reservation ID isn't? </p> <p> I'm concerned that the answer to that question might be 'hand-wavy'. And if we can't defend making one ID a dependency and the other not, then we might take this to the logical conclusion and inject all routing values into services. If we do that, the <code>Delete</code> method might now look like this: </p> <pre>[HttpDelete(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/reservations/{id}&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;Task&nbsp;<span style="color:#74531f;">Delete</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>,&nbsp;<span style="color:blue;">string</span>&nbsp;<span style="color:#1f377f;">id</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(Repository.IsIdValid) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.ReadReservation() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;Repository.Delete().ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(r&nbsp;<span style="color:blue;">is</span>&nbsp;{&nbsp;}) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">await</span>&nbsp;PostOffice.EmailReservationDeleted(r) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ConfigureAwait(<span style="color:blue;">false</span>); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> <p> (I haven't tried to compile this, so there may be syntax errors.) </p> <p> This seems really odd, although it's possible that we can salvage it by calling the dependency something else than <code>Repository</code>. It's not really a Unit of Work, but seems closer to that sort of design. </p> <p> I agree that a tenant feels like something that ought to be 'automatically handled', but I wonder whether it's possible to do that without making the code 'too clever'. </p> </div> <div class="comment-date">2021-05-04 8:26 UTC</div> </div> <div class="comment" id="76478b77b62e436aa2cbc96de85a5ff6"> <div class="comment-author"><a href="https://github.com/gonzaw">Gonzalo Waszczuk</a></div> <div class="comment-content"> <p> How would YAGNI come into play here? For instance, imagine your "client" code wasn't the Delete endpoint, but it was another app or endpoint that only had a "Guid reservationId", but <i>not</i> an "int restaurantId". In such case, wouldn't you be forced to add the restaurantId to the client code? What if this client code doesn't have an easy way to obtain such restaurantId? The reservation id is a global identifier, thus it makes sense that some application (be it a service, console, etc) would just get hold of the guid and nothing else, it's universally identifiable after all, it <i>should</i> be able to identify the reservation uniquely. This may require more roundtrips to the database, or forcing another client one-level above to provide the restaurantId (and this may even require politics and management to get in). </p> <p> Wouldn't YAGNI say that you shouldn't add the restaurantId to the API, since you ain't gonna need it? I.e, you likely won't change your data access implementation or shard the database in a way that would require that additional restaurantId, and even if you did, perhaps the development effort to add the restaurantId would be the same in that future timeline as it would be right now, so it would be the same to make this change now or afterwards (and in such case, wouldn't it make much sense to make the change afterwards, when you actually need it?). </p> </div> <div class="comment-date">2021-05-09 23:54 UTC</div> </div> <div class="comment" id="ccd61a106c8646dc950cf08bb5ad0b27"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Gonzalo, thank you for writing. The short answer is that I only 'discovered' the leaky abstraction because I did, in fact, need the restaurant ID. As part of creating, modifying, or deleting reservations, I <a href="/2021/05/10/simplifying-code-with-decorated-commands">also wanted to send email updates</a>. For example, when updating a reservation, the system should send an email with a subject line like "Your reservation for Nono changed." </p> <p> This meant that I had to figure out which name to put in the subject line. Given the restaurant ID, this is trivial, but without it, the system would first have to make a 'reverse lookup' to find the restaurant associated with the reservation ID. While it's technically possible, it seems overly complicated given that the <code>restaurantId</code> was already available at the entry point. </p> <p> It's true that since the reservation ID is a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">GUID</a>, it's globally unique. This, however, is an implementation detail. The system <a href="/2020/10/26/fit-urls">doesn't allow external client to refer to a reservation exclusively by a GUID</a>. Rather, from the perspective of an external client, the ID of a reservation looks like <code>https://api.example.com/restaurants/90125/reservations/667fd3ca5d6943b993860809adc99ad5?sig=aqwnNXj28J547upBELNf5I6yPIrQ%2BG9DG2QIAlOpgOE%3D</code>. While both restaurant and reservation IDs are <em>visible</em> within that string, a client can't use those IDs. The external reservation ID is the full (conceptually opaque) string. </p> <p> I agree, though, that YAGNI is relevant in this context, too. If it's any consolation, I didn't change the code 'just in case' - I did, in fact, change it because I realised that I needed the modified design. But I admit that I didn't explicitly state that in this article. </p> <p> You may also find the <a href="#3104d83e33524adc9f4d349fa4df20ed">above discussion</a> relevant. </p> </div> <div class="comment-date">2021-05-11 6:56 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>. Consider including identity in URLs https://blog.ploeh.dk/2021/04/19/consider-including-identity-in-urls 2021-04-19T06:29:00+00:00 Mark Seemann <div id="post"> <p> <em>Automatically enable act-on-behalf-of capabilities to REST APIs.</em> </p> <p> In 2013 I published a series of API design tips called <a href="/2013/04/29/rest-lessons-learned">REST lessons learned</a>. Eight years have passed, but why not add another entry? </p> <p> This one I've known about for years, but never written down. I often use it when I consult teams, and each time I'm reminded that since this seems like a recurring piece of advice, I ought to write it down. </p> <h3 id="923c9c41ad0a40e7a76f1909a4aae8cc"> Nutshell <a href="#923c9c41ad0a40e7a76f1909a4aae8cc" title="permalink">#</a> </h3> <p> The problem, in a nutshell, relates to secured resources in a REST API. This could be any resource where the client must be authenticated before being able to access it. This design tip, however, seems to be mostly applicable when the resource in question itself represents an 'identity'. </p> <p> To scope the problem, API designers rarely falter when modelling resources that seems unrelated to security or identity. For example, if you're modelling a product catalogue and you want to enable some clients to edit the catalogue, it's clear to most people that a product is unrelated to the identity of the client. Thus, people naturally design URL schemes like <code>products/1234</code>, and that's fine. You can make a <code>PUT</code> request against <code>products/1234</code> to edit the resource, but you must supply credentials in order to do so. </p> <p> What if, however, you want to edit your own profile information? There might be a REST resource that exposes your user name, address, bio, avatar, etc. You want to make profile information editable. How do you design the API? </p> <p> API designers often design such an API based on a URL like <code>profile</code>, without any identifer in the URL. After all, a client must be authenticated in order to edit the resource, so the user ID will somehow be in the HTTP header (e.g. as a <a href="https://en.wikipedia.org/wiki/JSON_Web_Token">JSON Web Token</a> (JWT)). </p> <p> Consider, nonetheless, to include the identity in the URL. </p> <p> A profile resource, then, would follow a scheme like <code>profiles/1234</code>. Consider identifying tenant IDs in a multi-tenant system in the same way: <code>tenants/2345</code>. Do this even when other IDs follow: <code>tenants/2345/products/9876</code>. </p> <h3 id="211d2bcb8aea4f718df724e191afd92d"> Typical approach, not recommended <a href="#211d2bcb8aea4f718df724e191afd92d" title="permalink">#</a> </h3> <p> As outlined above, a typical design is to design an 'identity' resource without including the identification in the URL. If, for example, a client wants to change the avatar via a REST API, it might have to do it like this: </p> <p> <pre>PUT /users HTTP/1.1 Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5c[...] { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;bio&quot;</span>:&nbsp;&nbsp;<span style="color:#a31515;">&quot;Danish&nbsp;software&nbsp;design&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;avatar&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;ploeh.png&quot;</span> }</pre> </p> <p> The server-side code can extract the user ID and other authentication information from the <code>Bearer</code> token in the HTTP header. It can use this information to find the user ID and update its database. Technically, this gets the job done. </p> <p> I'll outline some potential problems with such a design in a moment, but first I'll show a second example. This one is more subtle. </p> <p> Imagine an online restaurant reservation system. The system enables guests to make reservations, edit them, and so on. When a potential guest attempts to make a reservation, the API should check if it can accept it. See <a href="/2020/01/27/the-maitre-d-kata">The Maître d' kata</a> for various conditions that may cause the restaurant to reject the reservation. One case might be that the reservation attempt is outside of the restaurant's opening hours. </p> <p> Perhaps the API should expose a management API that enables the restaurant's <a href="https://en.wikipedia.org/wiki/Ma%C3%AEtre_d%27h%C3%B4tel">maître d'hôtel</a> to change the opening hours. Perhaps you decide to design the API to look like this: </p> <p> <pre>PUT /restaurant HTTP/1.1 Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5c[...] { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;opensAt&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;18:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;lastSeating&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;21:00&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;seatingDuration&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;6:00&quot;</span> } </pre> </p> <p> Again, the <code>Bearer</code> token is supposed to contain enough information about the user to enable authentication and authorisation. This also gets the job done, but might paint you into a corner. </p> <h3 id="d57b7b148c824427b99ea26437425fd2"> Separation of concerns <a href="#d57b7b148c824427b99ea26437425fd2" title="permalink">#</a> </h3> <p> The problem with the above approach is that it fails to separate concerns. When modelling identity, it's easy to conflate the identity of the resource with the identity of the client interacting with it. Those are two separate concerns. </p> <p> What happens, for example, if you have so much success with the above restaurant reservation system that you decide to offer it as a multi-tenant service? </p> <p> I often see a 'solution' to such a requirement where API designers now require clients to supply a 'tenant ID' in the HTTP header. To make it secure, you should probably make it a claim in the JWT supplied via the <code>Authorization</code> header, or something to that effect. </p> <p> What's wrong with that? It conflates the identity of the client with the identity of the resource. This means that you can't easily enable capabilities where a client can act on behalf of someone else. </p> <p> Imagine, for example, that you have three restaurants, each a tenant: <em>Hipgnosta</em>, <em>Nono</em>, and <em>The Vatican Cellar</em>. It turns out, however, that <em>Hipgnosta</em> and <em>Nono</em> have the same owners, and share a single administrative employee. These restaurants wish to let that employee manage both restaurants. </p> <p> With the design outlined above, the employee would have to authenticate twice in order to make changes to both restaurants. That may not be a big deal for occasional edits to two restaurants, but imagine an employee who has to manage hundreds of franchises, and the situation becomes untenable. </p> <p> You should enable act-on-behalf-of capabilities. This may sound like speculative generality, but it's such a low-hanging fruit that I think you should enable it even if you don't need it right now. Just put the resource identity in the URL: <code>restaurants/456</code> and <code>users/1234</code>. </p> <p> Even for user profiles, putting the user ID in the URL enables one client to <em>view</em> (if not edit) other user profiles, which may or may not be desirable. </p> <p> The API should still demand that clients authenticate, but now you can distinguish the resource from the client making the request. This makes it possible for a client to act on behalf of others, given the right credentials. </p> <h3 id="4a51078a9a4745f8aef02993ebe52599"> Restaurant schedule example <a href="#4a51078a9a4745f8aef02993ebe52599" title="permalink">#</a> </h3> <p> I'll show you a slightly different example. Instead of editing a restaurant's opening or closing hours, I'll show you how the maître d' can view the schedule for a day. A <a href="/2020/10/05/fortunately-i-dont-squash-my-commits">previous article</a> already suggested that such a resource might exist in a code base I've recently written. A request and its response might look like this: </p> <p> <pre>GET /restaurants/1/schedule/2022/8/21 HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZXN0YXVyYW5[...] HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Hipgnosta&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;year&quot;</span>:&nbsp;2022, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;month&quot;</span>:&nbsp;8, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;day&quot;</span>:&nbsp;21, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;days&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;date&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-08-21&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;entries&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;time&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;19:45:00&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;reservations&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;0cced578fa21489bb0e3b5eb6be6825a&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-08-21T19:45:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;annekoicchamber@example.com&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Anne&nbsp;Kowics&nbsp;Chambers&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;5 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;] }</pre> </p> <p> I've simplified the example response by removing all links to make it more readable. After all, the shape of the response is irrelevant for this discussion. The point is the interaction between the request URL and the JWT. </p> <p> The request is against a URL that identifies the restaurant in question. The <code>1</code> after <code>restaurants</code> in <code>/restaurants/1/schedule/2022/8/21</code> identifies the restaurant as <em>Hipgnosta</em> to the API. (In reality, clients are expected to <a href="/2020/10/26/fit-urls">follow links. URLs are signed with HMACs</a>, but I've trimmed those off as well to simplify the example.) </p> <p> In this multi-tenant API, each restaurant is a separate tenant. Thus, the restaurant ID is really a tenant ID. The resource is fully identified via the URL. </p> <p> What about the client identity? It's supplied via the JWT, which decoded contains these claims: </p> <p> <pre>{ &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;restaurant&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;1&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;2112&quot;</span> &nbsp;&nbsp;], &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;role&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;MaitreD&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;nbf&quot;</span>:&nbsp;1618301674, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;exp&quot;</span>:&nbsp;1618906474, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;iat&quot;</span>:&nbsp;1618301674 }</pre> </p> <p> Notice that the <code>restaurant</code> array contains a list of IDs that identify the tenants that the JWT can access. This particular JWT can access both restaurants <code>1</code> and <code>2112</code>, which correspond to <em>Hipgnosta</em> and <em>Nono</em>. This represents the shared employee who can act on behalf of both restaurants. </p> <h3 id="94a738f65941431a92072ee5d5f3af1f"> Access control <a href="#94a738f65941431a92072ee5d5f3af1f" title="permalink">#</a> </h3> <p> The API checks the that the incoming JWT has a <code>restaurant</code> claim that matches the incoming restaurant ID. Only if that's the case will it let the request through. </p> <p> <pre>[<span style="color:#2b91af;">HttpGet</span>(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/schedule/{year}/{month}/{day}&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;<span style="color:#2b91af;">Task</span>&lt;<span style="color:#2b91af;">ActionResult</span>&gt;&nbsp;Get(<span style="color:blue;">int</span>&nbsp;restaurantId,&nbsp;<span style="color:blue;">int</span>&nbsp;year,&nbsp;<span style="color:blue;">int</span>&nbsp;month,&nbsp;<span style="color:blue;">int</span>&nbsp;day) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(!AccessControlList.Authorize(restaurantId)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">ForbidResult</span>(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Do&nbsp;the&nbsp;real&nbsp;work&nbsp;here...</span></pre> </p> <p> The above code fragment is a copy from <a href="/2021/02/01/aspnet-poco-controllers-an-experience-report">another article</a> where I already shared some of the server-side authorisation code. Here I'll show some of the code that I didn't show in the other article. <ins datetime="2021-06-15T06:14Z">The code is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> <p> In the other article, you can see how the <code>AccessControlList</code> is populated from <code>HttpContext.User</code>, but I didn't show the implementation of the <code>FromUser</code> function. Here it is: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">static</span>&nbsp;AccessControlList&nbsp;<span style="color:#74531f;">FromUser</span>(ClaimsPrincipal&nbsp;<span style="color:#1f377f;">user</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">restaurantIds</span>&nbsp;=&nbsp;user &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.FindAll(<span style="color:#a31515;">&quot;restaurant&quot;</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.SelectMany(<span style="color:#1f377f;">c</span>&nbsp;=&gt;&nbsp;ClaimToRestaurantId(c)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ToList(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;AccessControlList(restaurantIds); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">int</span>[]&nbsp;<span style="color:#74531f;">ClaimToRestaurantId</span>(Claim&nbsp;<span style="color:#1f377f;">claim</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(<span style="color:blue;">int</span>.TryParse(claim.Value,&nbsp;<span style="color:blue;">out</span>&nbsp;var&nbsp;<span style="color:#1f377f;">i</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;i&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;Array.Empty&lt;<span style="color:blue;">int</span>&gt;(); }</pre> </p> <p> What you need to notice is just that the <code>FromUser</code> function finds and parses all the <code>"restaurant"</code> claims it can find. The <code>Authorize</code> method, subsequently, just looks for the incoming <code>restaurantId</code> among them: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Authorize</span>(<span style="color:blue;">int</span>&nbsp;<span style="color:#1f377f;">restaurantId</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;restaurantIds.Contains(restaurantId); }</pre> </p> <p> Thus, the identity of the resource is decoupled from the identity of the client. In this example, the client acts on behalf of two tenants, but since an array can hold an arbitrary number of values, there's no hard limit to how many tenants a single client could act on behalf of. </p> <h3 id="e753a5ee92e142ac8acfe096d1381b7f"> Conclusion <a href="#e753a5ee92e142ac8acfe096d1381b7f" title="permalink">#</a> </h3> <p> You don't always need act-on-behalf-of security features, but you never know if such a need might emerge in the future. You're going to need to check client credentials anyway, so the only extra step to avoid painting yourself into a corner is to put the resource identity in the URL - even if you believe that the resource identity and the client identity is the same. Such assumptions have a tendency to be proven wrong over time. </p> <p> I'm not usually a proponent of speculative generality, but I also think that it's prudent to consider overall return of investment. The cost of adding the resource identity to the URL is low, while having to change URL schemes later may carry a higher cost (even if you <a href="/2020/10/26/fit-urls">force clients to follow links</a>). </p> <p> This fits one view on software architecture: Make it as easy to make reactive changes to the system, but identify the areas where change will be hard; make good ex-ante decisions about those. </p> <p> Finally, I think that there's something fundamentally correct and consistent in putting user or tenant IDs in the URLs. After all, you put all other resource IDs (such as product IDs or customer IDs) in URLs. </p> <p> Notice, in the above schedule example, how the restaurant ID isn't the only ID. The URL also carries information about year, month, and date. These further identify the schedule resource. </p> <p> Putting user or tenant IDs in the URL effectively separates concerns. It enables you to discern the tenant or user from the client making the request. </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>. Threading context through a catamorphism https://blog.ploeh.dk/2021/04/12/threading-context-through-a-catamorphism 2021-04-12T11:09:00+00:00 Mark Seemann <div id="post"> <p> <em>A problem solved after 1½ years.</em> </p> <p> You've probably noticed that it's easier to learn something new if it looks or sounds like something you already know. As a native Dane, I've found it easier to learn English and German than Russian and Japanese. If you originally were a Java or C# developer, you probably find <a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a> more approachable than <a href="https://clojure.org">Clojure</a> or <a href="https://en.wikipedia.org/wiki/APL_(programming_language)">APL</a>. </p> <p> I believe that this extends to <a href="/2017/10/04/from-design-patterns-to-category-theory">design patterns and universal abstractions</a> as well. If code new to you follows well-known abstractions, it may be easier to learn than if it's structured in an entirely ad-hoc manner. This is my motivation for learning such universal abstractions as <a href="/2017/10/06/monoids">monoids</a>, <a href="/2018/03/22/functors">functors</a>, and <a href="/2019/04/29/catamorphisms">catamorphisms</a>. </p> <p> I particularly enjoy when it's possible to apply such abstractions to a proper problem. This occasionally happens. One example is my small article series on a <a href="/2019/08/26/functional-file-system">functional file system</a>. </p> <h3 id="2aa7c4b2f26840e7bfed2a42064853a7"> A fly in the ointment <a href="#2aa7c4b2f26840e7bfed2a42064853a7" title="permalink">#</a> </h3> <p> In those articles, I described how you could base most of the code on the <a href="/2019/08/05/rose-tree-catamorphism">rose tree catamorphism</a>. There was just one snag. There was one function, <code>calculateMoves</code>, that I was unable to implement with the catamorphism. In the article, I acknowledged my failure: <blockquote> "Earlier, I wrote that you can implement desired <code>Tree</code> functionality with the <code>foldTree</code> function, but that was a simplification. If you can implement the functionality of <code>calculateMoves</code> with <code>foldTree</code>, I don't know how." </blockquote> This was true for both <a href="/2019/09/09/picture-archivist-in-haskell">the Haskell proof of concept</a> as well as <a href="/2019/09/16/picture-archivist-in-f">the F# port</a>. </p> <p> <a href="https://about.me/tysonwilliams">Tyson Williams</a> and I <a href="/2019/09/16/picture-archivist-in-f#68b26807cc424856b8f762f214389826">discussed this wart</a> without getting closer to a solution. </p> <p> As the idiom goes, perfect is the enemy of good, so I decided to move on, although it nagged me. </p> <h3 id="641a9df4d9a24cb7bf687b041f8c305e"> Problem, condensed <a href="#641a9df4d9a24cb7bf687b041f8c305e" title="permalink">#</a> </h3> <p> The problem with the <code>calculateMoves</code> function was that it needed to thread a 'context' recursively through the entire data structure. In this case, the context was a file path. </p> <p> When <code>calculateMoves</code> runs over the input tree, it needs to thread a relative <code>path</code> through the function, building it up as it traverses the data structure. </p> <p> For example, if a leaf node named <code>1</code> is in a directory named <code>b</code>, which itself is a subdirectory of <code>a</code>, the relative path should be <code>a/b/1</code>. This example is straight from the test cases shown in both articles. You can also find the tests in the <a href="https://github.com/ploeh/picture-archivist">GitHub repository</a>. </p> <p> Each time <code>calculateMoves</code> visits a <code>Node</code> or <code>Leaf</code> it needs to know the parent <code>path</code> to calculate the destination path. As the articles show, this isn't too hard to do with regular pattern matching and recursion. </p> <p> I couldn't figure out, however, how to thread the <code>path</code> through the function when I tried to implement it with the catamorphism. </p> <h3 id="2461821e89084c5f8da43b2199d77d33"> Breakthrough <a href="#2461821e89084c5f8da43b2199d77d33" title="permalink">#</a> </h3> <p> While I'm ready to walk away from problems when I'm stuck, I tend to remember them. Sometimes, I run into a solution much later. </p> <p> This happened to me yesterday. I was trying to answer <a href="https://stackoverflow.com/q/67037663/126014">a Stack Overflow question</a> which was explicitly about the application of universal abstractions. Once more, I was stuck by being unable to thread a 'context' through a catamorphism. This time, instead of a <code>path</code>, the context was an indentation depth. Basically, the question was how to render a tree with proper indentation. </p> <p> Again, this isn't hard if you resort to explicit pattern matching and recursion, but I couldn't figure out how to do it via the data structure's catamorphism. </p> <p> Fortunately, <a href="https://stackoverflow.com/users/1364288/danidiaz">the user danidiaz</a> posted <a href="https://stackoverflow.com/a/67042881/126014">an awesome answer</a> while I was struggling. The answer uses a trick that I hadn't noticed before: It threads the indentation depth through the data structure by using the catamorphism to produce a structure map with <em>a function</em> as the carrier type. Specifically, danidiaz defines the algebra <code>Todo' (Int -&gt; String) -&gt; Int -&gt; String</code> to reduce a <code>Todo' (Int -&gt; String)</code> to an <code>Int -&gt; String</code> function. This function then gets initialised with the depth <code>0</code>. </p> <p> While I've been doing functional programming for years, I sometimes still tend to forget that functions are first-class values... </p> <p> This trick, though, seems to be universally applicable. If you need to thread a context through a catamorphism, define the algebra to work on <em>functions</em> that take the context as an argument. </p> <p> If this is a universally applicable trick, it also ought to work with the <code>calculateMoves</code> function. </p> <h3 id="f3e4908437ea4ab7bf0dd01d82ec470e"> Haskell re-implementation <a href="#f3e4908437ea4ab7bf0dd01d82ec470e" title="permalink">#</a> </h3> <p> In my <a href="https://www.haskell.org">Haskell</a> proof of concept, the <code>calculateMoves</code> function originally looked like this: </p> <p> <pre><span style="color:#2b91af;">calculateMoves</span>&nbsp;::&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">Move</span> calculateMoves&nbsp;=&nbsp;imp&nbsp;<span style="color:#a31515;">&quot;&quot;</span> &nbsp;&nbsp;<span style="color:blue;">where</span>&nbsp;imp&nbsp;path&nbsp;&nbsp;&nbsp;&nbsp;(Leaf&nbsp;x)&nbsp;=&nbsp;Leaf&nbsp;$&nbsp;Move&nbsp;x&nbsp;$&nbsp;replaceDirectory&nbsp;x&nbsp;path &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imp&nbsp;path&nbsp;(Node&nbsp;x&nbsp;xs)&nbsp;=&nbsp;Node&nbsp;(path&nbsp;&lt;/&gt;&nbsp;x)&nbsp;$&nbsp;imp&nbsp;(path&nbsp;&lt;/&gt;&nbsp;x)&nbsp;&lt;$&gt;&nbsp;xs</pre> </p> <p> It uses an <code>imp</code> (for <em>implementation</em>) function to explicitly <a href="/2015/12/01/recurse">recurse</a> over a <code>Tree FilePath FilePath</code>. Until yesterday, I couldn't come up with a better solution to thread the <code>path</code> through the data structure. </p> <p> The new trick suggests that it'd be possible to implement the function on <code>foldTree</code> (the catamorphism) by using <em>a function</em> as the carrier type. Since the context to be threaded through the catamorphism is a <code>String</code> (the <code>path</code>), the catamorphism should produce a function that takes a <code>String</code> as argument. In other words, the carrier type of the <code>Tree</code> should be <code>String -&gt; Tree FilePath Move</code>. </p> <p> Let's expand on this: The type of <code>foldTree</code> is <code>foldTree :: (a -&gt; [c] -&gt; c) -&gt; (b -&gt; c) -&gt; Tree a b -&gt; c</code>. Usually, I tend to think of the type parameter <code>c</code> as the type of some value, but since it's unconstrained, it can also be <em>a function</em>. That's what we need here: <code>c</code> should be <code>String -&gt; Tree FilePath Move</code>. </p> <p> That's not too hard to do, because of currying. Just write functions that take an extra <code>String</code> argument and pass them to <code>foldTree</code>: </p> <p> <pre><span style="color:#2b91af;">calculateMoves</span>&nbsp;::&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">Move</span> calculateMoves&nbsp;t&nbsp;=&nbsp;foldTree&nbsp;fNode&nbsp;fLeaf&nbsp;t&nbsp;<span style="color:#a31515;">&quot;&quot;</span> &nbsp;&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">fLeaf</span>&nbsp;::&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">Move</span> &nbsp;&nbsp;&nbsp;&nbsp;fLeaf&nbsp;x&nbsp;&nbsp;&nbsp;&nbsp;path&nbsp;=&nbsp;Leaf&nbsp;$&nbsp;Move&nbsp;x&nbsp;$&nbsp;replaceDirectory&nbsp;x&nbsp;path &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">fNode</span>&nbsp;::&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;[<span style="color:#2b91af;">String</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">Move</span>]&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:#2b91af;">String</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">Move</span> &nbsp;&nbsp;&nbsp;&nbsp;fNode&nbsp;x&nbsp;fs&nbsp;path&nbsp;=&nbsp;Node&nbsp;(path&nbsp;&lt;/&gt;&nbsp;x)&nbsp;$&nbsp;($&nbsp;path&nbsp;&lt;/&gt;&nbsp;x)&nbsp;&lt;$&gt;&nbsp;fs</pre> </p> <p> Here I've used type annotations for the local functions, but that's entirely optional: </p> <p> <pre><span style="color:#2b91af;">calculateMoves</span>&nbsp;::&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;<span style="color:blue;">Tree</span>&nbsp;<span style="color:#2b91af;">FilePath</span>&nbsp;<span style="color:blue;">Move</span> calculateMoves&nbsp;t&nbsp;=&nbsp;foldTree&nbsp;fNode&nbsp;fLeaf&nbsp;t&nbsp;<span style="color:#a31515;">&quot;&quot;</span> &nbsp;&nbsp;<span style="color:blue;">where</span> &nbsp;&nbsp;&nbsp;&nbsp;fLeaf&nbsp;x&nbsp;&nbsp;&nbsp;&nbsp;path&nbsp;=&nbsp;Leaf&nbsp;$&nbsp;Move&nbsp;x&nbsp;$&nbsp;replaceDirectory&nbsp;x&nbsp;path &nbsp;&nbsp;&nbsp;&nbsp;fNode&nbsp;x&nbsp;fs&nbsp;path&nbsp;=&nbsp;Node&nbsp;(path&nbsp;&lt;/&gt;&nbsp;x)&nbsp;$&nbsp;($&nbsp;path&nbsp;&lt;/&gt;&nbsp;x)&nbsp;&lt;$&gt;&nbsp;fs</pre> </p> <p> I included the type annotations to make it a little clearer what's going on. Recall that the type of <code>foldTree</code> is <code>foldTree :: (a -&gt; [c] -&gt; c) -&gt; (b -&gt; c) -&gt; Tree a b -&gt; c</code>. First consider the second of the two function arguments, the one I call <code>fLeaf</code> in the above code. It's the simplest of the two, so it makes sense to start with that one. </p> <p> The generic type of <code>fLeaf</code> is <code>b -&gt; c</code>. How does that map to the type of <code>fLeaf</code>, which is <code>FilePath -&gt; String -&gt; Tree FilePath Move</code>? </p> <p> Well, the <code>Tree</code> that the catamorphism runs on is a <code>Tree FilePath FilePath</code>. Mapped to the parametrically polymorphic type of <code>foldTree</code> that's <code>Tree a b</code>. In other words, <code>b</code> maps to <code>FilePath</code>. Thus, in order to fit the type of <code>b -&gt; c</code>, the type corresponding to <code>b</code> in <code>fLeaf</code> must be <code>FilePath</code>. What's left? <code>String -&gt; Tree FilePath Move</code> is what's left. The function takes a <code>FilePath</code> as input and returns a <code>String -&gt; Tree FilePath Move</code>. In other words, <code>c ~ String -&gt; Tree FilePath Move</code>. </p> <p> How does that fit with <code>fNode</code>? </p> <p> Generically, this function must have the type <code>a -&gt; [c] -&gt; c</code>. We've already established that <code>c</code> must be <code>String -&gt; Tree FilePath Move</code>. Since the catamorphism runs on a <code>Tree FilePath FilePath</code>, we also know that <code>a</code> must be <code>FilePath</code>. Thus, plugging in all the types, <code>fNode</code> must have the type <code>FilePath -&gt; [String -&gt; Tree FilePath Move] -&gt; String -&gt; Tree FilePath Move</code>. Note, particularly, that the second argument is a list of functions. That's why I decided to name the parameter <code>fs</code>, for <em>functions</em>. </p> <p> The entire expression <code>foldTree fNode fLeaf t</code>, then, has the type <code>String -&gt; Tree FilePath Move</code>, since <code>c</code> is <code>String -&gt; Tree FilePath Move</code> and the return type of <code>foldTree</code> is <code>c</code>. </p> <p> The final trick is to apply this function to the initial relative path <code>""</code>, which returns a <code>Tree FilePath Move</code>. </p> <p> This compiles and passes all tests. <code>calculateMoves</code> is now implemented using the <code>Tree</code> catamorphism, a goal that eluded me for more than one and a half years. </p> <h3 id="48fe66e3bffa413c8fe15e465581cb4e"> F# re-implementation <a href="#48fe66e3bffa413c8fe15e465581cb4e" title="permalink">#</a> </h3> <p> With the Haskell proof of concept in place, it's fairly trivial to port the new implementation to the <a href="https://fsharp.org">F#</a> code base. </p> <p> The <code>calculateMoves</code> function originally looked like this: </p> <p> <pre><span style="color:green;">//&nbsp;Tree&lt;string,FileInfo&gt;&nbsp;-&gt;&nbsp;Tree&lt;string,Move&gt;</span> <span style="color:blue;">let</span>&nbsp;calculateMoves&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;replaceDirectory&nbsp;(f&nbsp;:&nbsp;FileInfo)&nbsp;d&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileInfo&nbsp;(Path.Combine&nbsp;(d,&nbsp;f.Name)) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;<span style="color:blue;">rec</span>&nbsp;imp&nbsp;path&nbsp;=&nbsp;<span style="color:blue;">function</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Leaf&nbsp;x&nbsp;<span style="color:blue;">-&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Leaf&nbsp;{&nbsp;Source&nbsp;=&nbsp;x;&nbsp;Destination&nbsp;=&nbsp;replaceDirectory&nbsp;x&nbsp;path&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Node&nbsp;(x,&nbsp;xs)&nbsp;<span style="color:blue;">-&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;newNPath&nbsp;=&nbsp;Path.Combine&nbsp;(path,&nbsp;x) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tree.node&nbsp;newNPath&nbsp;(List.map&nbsp;(imp&nbsp;newNPath)&nbsp;xs) &nbsp;&nbsp;&nbsp;&nbsp;imp&nbsp;<span style="color:#a31515;">&quot;&quot;</span></pre> </p> <p> In the F# code base, the catamorphism is called <code>Tree.cata</code>, but otherwise looks like the Haskell <code>foldTree</code> function. The refactoring is also similar: </p> <p> <pre><span style="color:green;">//&nbsp;Tree&lt;string,&nbsp;FileInfo&gt;&nbsp;-&gt;&nbsp;Tree&lt;string,&nbsp;Move&gt;</span> <span style="color:blue;">let</span>&nbsp;calculateMoves&nbsp;t&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;FileInfo&nbsp;-&gt;&nbsp;string&nbsp;-&gt;&nbsp;FileInfo</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;replaceDirectory&nbsp;(f&nbsp;:&nbsp;FileInfo)&nbsp;d&nbsp;=&nbsp;FileInfo&nbsp;(Path.Combine&nbsp;(d,&nbsp;f.Name)) &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;FileInfo&nbsp;-&gt;&nbsp;string&nbsp;-&gt;&nbsp;Tree&lt;&#39;a,&nbsp;Move&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;fLeaf&nbsp;x&nbsp;path&nbsp;=&nbsp;Leaf&nbsp;{&nbsp;Source&nbsp;=&nbsp;x;&nbsp;Destination&nbsp;=&nbsp;replaceDirectory&nbsp;x&nbsp;path&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;string&nbsp;-&gt;&nbsp;(string&nbsp;-&gt;&nbsp;Tree&lt;string,&nbsp;&#39;a&gt;)&nbsp;list&nbsp;-&gt;&nbsp;string&nbsp;-&gt;&nbsp;Tree&lt;string,&nbsp;&#39;a&gt;</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;fNode&nbsp;x&nbsp;fs&nbsp;path&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;newNPath&nbsp;=&nbsp;Path.Combine&nbsp;(path,&nbsp;x) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Tree.node&nbsp;newNPath&nbsp;(List.map&nbsp;(<span style="color:blue;">fun</span>&nbsp;f&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;f&nbsp;newNPath)&nbsp;fs) &nbsp;&nbsp;&nbsp;&nbsp;Tree.cata&nbsp;fNode&nbsp;fLeaf&nbsp;t&nbsp;<span style="color:#a31515;">&quot;&quot;</span></pre> </p> <p> Again, the expression <code>Tree.cata fNode fLeaf t</code> has the type <code>string -&gt; Tree&lt;string, Move&gt;</code>, so applying it to <code>""</code> produces a <code>Tree&lt;string, Move&gt;</code> return value. </p> <h3 id="21524d98dcbb4593abc18c55efbfd105"> Conclusion <a href="#21524d98dcbb4593abc18c55efbfd105" title="permalink">#</a> </h3> <p> I don't recall where I read the following, but I was under the impression that a data structure's catamorphism was its 'universal API', upon which you could implement any other functionality. I'd love it if it was true, but after my 2019 failure to implement <code>calculateMoves</code> via the <code>Tree</code> catamorphism, I wasn't sure if such a conjecture would hold. </p> <p> I still don't know if that assertion holds universally, but at least one reason to doubt it has now been removed. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="1301010b460845db8730e4aa617504a4"> <div class="comment-author"><a href="https://about.me/tysonwilliams">Tyson Williams</a></div> <div class="comment-content"> <p> Excellent work Mark! I too had not forgotten about this, and it nagged me as well. </p> <p> To some extent, I feel like your explanation of how to implement <code>calculateMoves</code> via <code>Tree.cata</code> is top-down. By top-down, I mean it might depend on discovering the key idea of having <code>Tree.cata</code> return a function and then figuring out the correct type for that function. A good thing about such top-down approaches is being immediately aware that a better solution likely exists even if it takes some time and effort to find it. </p> <p> I was curious if a bottom-up approach would work. By bottom-up, I mean applying small refacorings to the code that are motivated by the principles, conventions, or style of functional programming. I do think I found such an approach. Of course it is a bit contradictory of me to only be able to find this approach after I read your presentation of the top-down approach. However, I am thinking of it like a kata. I now know such a bottom-up approach should be possible, and I want to find it. </p> <p> My bottom-up approach is in <a href="https://github.com/TysonMN/picture-archivist/tree/calculateMoves_via_cata_slow_refactor">this branch</a>. Here is a brief summary of how I want myself to think of making those commits in that order. </p> <p> Each case of the discriminated union could be extracted to its own function. This is easy to do in the <code>Leaf</code> case (so do it now), but it is not as easy to do in the <code>Node</code> case because of recursion, so delay that change for a bit. If we did extract both functions though, both functions would include the argument that I called <code>pathToParent</code>. Since it is passed in everywhere, it should be passed in nowhere (by eta reducing). To do that, we need it to be the last parameter to <code>imp</code>. After switching this order, we now deal with the recursion by doing it as soon as possible. Then the remaining code in that case can be extracted, and <code>imp</code> is essentially <code>Tree.cata</code>. </p> <p> In this approach, I never thought about the possibility of <code>Tree.cata</code> returning a function. It just sort of fell out as a consequence of my other changes. </p> </div> <div class="comment-date">2021-04-12 17:49 UTC</div> </div> <div class="comment" id="c90c8190c0f44e60a44fc605b9a84113"> <div class="comment-author"><a href="https://github.com/gonzaw">Gonzalo Waszczuk</a></div> <div class="comment-content"> <p> Very nice! </p> <p> In Haskell there is a library called <a href="https://hackage.haskell.org/package/recursion-schemes-5.2.2.1">recursion-schemes</a> that showcases these types of recursion with catamorphisms, but also with many others recursion schemes. You can check it out and see if it gives you any new ideas. </p> <p> Regarding this use of catamorphism, the library itself I believe shows a very similar example <a href="https://hackage.haskell.org/package/recursion-schemes-5.2.2.1/docs/Data-Functor-Foldable.html">here</a>, using the Reader type (which is isomorphic to the function you used in your example): </p> <pre> >>> :{ let pprint2 :: Tree Int -> String pprint2 = flip runReader 0 . cataA go where go :: TreeF Int (Reader Int String) -> Reader Int String go (NodeF i rss) = do -- rss :: [Reader Int String] -- ss :: [String] ss <- local (+ 2) $ sequence rss indent <- ask let s = replicate indent ' ' ++ "* " ++ show i pure $ intercalate "\n" (s : ss) :} </pre> <pre> >>> putStrLn $ pprint2 myTree * 0 * 1 * 2 * 3 * 31 * 311 * 3111 * 3112 </pre> </div> <div class="comment-date">2021-04-14 02:27 UTC</div> </div> <div class="comment" id="d26feeefed69421499e766dc1737ca31"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Gonzalo, thank you for reminding me of the <em>recursion-schemes</em> library. It's one of those tomes of knowledge of which I'm aware, but never really have gotten around to look at... </p> </div> <div class="comment-date">2021-04-16 6:29 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>. Mazes on Voronoi tessellations https://blog.ploeh.dk/2021/04/05/mazes-on-voronoi-tesselations 2021-04-05T09:03:00+00:00 Mark Seemann <div id="post"> <p> <em>Recursive backtracker maze generation on a Voronoi diagram.</em> </p> <p> Today's blog post <a href="https://observablehq.com/@ploeh/mazes-on-voronoi-tessellations">appears on Observable</a>. It's an interactive environment where you can play with and fork the code. <a href="https://observablehq.com/@ploeh/mazes-on-voronoi-tessellations">Go there to read it</a>. </p> <p> <img src="/content/binary/recursive-backtracker-on-voronoi-tiles.png" alt="Recursive backtracker algorithm running on a Voronoi tessellation."> </p> <p> <a href="https://observablehq.com">Observable</a> is a really neat platform which has managed to do what I thought was nigh-impossible: make me return to <a href="https://en.wikipedia.org/wiki/JavaScript">JavaScript</a>. The site's <a href="https://observablehq.com/about">been around for some years</a>, and I hope it'll be around for even more years. </p> <p> <em>ploeh blog</em>, on the other hand, has been around <a href="/2009/01/28/LivingInInterestingTimes">since 2009</a>, and I intend to keep it around for much longer. Who knows if <em>Observable</em> will outlive the blog. Enjoy the article while it's there. </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>. Table-driven tennis scoring https://blog.ploeh.dk/2021/03/29/table-driven-tennis-scoring 2021-03-29T06:15:00+00:00 Mark Seemann <div id="post"> <p> <em>Probably the most boring implementation of the tennis kata I've ever written.</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> The tennis scoring rules essentially describe a finite state machine, and while I was thinking about the state transitions involved, I came across an article by <a href="http://blog.mikemccandless.com">Michael McCandless</a> about <a href="http://blog.mikemccandless.com/2014/08/scoring-tennis-using-finite-state.html">scoring tennis using finite-state automata</a>. </p> <p> This isn't the first time I've thought about simply enumerating all possible states in the state machine, but I decided to spend half an hour on actually doing it. While Michael McCandless shows that an optimisation is possible, his minimised version doesn't enable us to report all intermediary states with the correct labels. For example, he optimises away <em>thirty-all</em> by replacing it with <em>deuce</em>. The end result is still the same, in the sense that the minimised state machine will arrive at the same winner for the same sequence of balls, but it can't correctly report the score while the game is in progress. </p> <p> For that reason, I decided to use his non-optimised state machine as a launch pad. </p> <h3 id="d32da6b59b7448959d6bed2f10f84569"> States <a href="#d32da6b59b7448959d6bed2f10f84569" title="permalink">#</a> </h3> <p> I used <a href="https://fsharp.org">F#</a> to enumerate all twenty states: </p> <p> <pre><span style="color:blue;">type</span>&nbsp;Score&nbsp;= &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveAll &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenLove &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveFifteen &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyLove &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenAll &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveThirty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FortyLove &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyFifteen &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenThirty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveForty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FortyFifteen &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyAll &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenForty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;GamePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FortyThirty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyForty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;GamePlayerTwo &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;AdvantagePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Deuce &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;AdvantagePlayerTwo</pre> </p> <p> Utterly boring, yes, but perhaps boring code might be good code. </p> <h3 id="1eb656d32be0461aa11c321ec478a1cf"> Table-driven methods <a href="#1eb656d32be0461aa11c321ec478a1cf" title="permalink">#</a> </h3> <p> <a href="http://amzn.to/1dLYr0r">Code Complete</a> describes a programming technique called <em>table-driven methods</em>. The idea is to replace branching instructions such as <code>if</code>, <code>else</code>, and <code>switch</code> with a lookup table. The book assumes that the table exists in memory, but in this case, we can implement the table lookup with pattern matching: </p> <p> <pre><span style="color:green;">//&nbsp;Score&nbsp;-&gt;&nbsp;Score</span> <span style="color:blue;">let</span>&nbsp;ballOne&nbsp;=&nbsp;<span style="color:blue;">function</span> &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveAll&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;FifteenLove &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenLove&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;ThirtyLove &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveFifteen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;FifteenAll &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyLove&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;FortyLove &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenAll&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;ThirtyFifteen &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveThirty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;FifteenThirty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FortyLove&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;GamePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyFifteen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;FortyFifteen &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenThirty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;ThirtyAll &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;LoveForty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;FifteenForty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FortyFifteen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;GamePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyAll&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;FortyThirty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FifteenForty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;ThirtyForty &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;GamePlayerOne&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;GamePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;FortyThirty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;GamePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ThirtyForty&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;Deuce &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;GamePlayerTwo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;GamePlayerTwo &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;AdvantagePlayerOne&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;GamePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;Deuce&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;AdvantagePlayerOne &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;AdvantagePlayerTwo&nbsp;<span style="color:blue;">-&gt;</span>&nbsp;Deuce</pre> </p> <p> The <code>ballOne</code> function returns the new score when player one wins a ball. It takes the old score as input. </p> <p> I'm going to leave <code>ballTwo</code> as an exercise to the reader. </p> <h3 id="47bf74d3fafd478fafa354563459f0ad"> Smoke test <a href="#47bf74d3fafd478fafa354563459f0ad" title="permalink">#</a> </h3> <p> Does it work, then? Here's a few interactions with the API in <em>F# Interactive:</em> </p> <p> <pre>&gt; ballOne LoveAll;; val it : Score = FifteenLove &gt; LoveAll |&gt; ballOne |&gt; ballTwo;; val it : Score = FifteenAll &gt; LoveAll |&gt; ballOne |&gt; ballTwo |&gt; ballTwo;; val it : Score = FifteenThirty &gt; LoveAll |&gt; ballOne |&gt; ballTwo |&gt; ballTwo |&gt; ballTwo;; val it : Score = FifteenForty &gt; LoveAll |&gt; ballOne |&gt; ballTwo |&gt; ballTwo |&gt; ballTwo |&gt; ballOne;; val it : Score = ThirtyForty &gt; LoveAll |&gt; ballOne |&gt; ballTwo |&gt; ballTwo |&gt; ballTwo |&gt; ballOne |&gt; ballTwo;; val it : Score = GamePlayerTwo</pre> </p> <p> It looks like it's working. </p> <h3 id="17290385a4a042189ef0b5b04cf200c6"> Automated tests <a href="#17290385a4a042189ef0b5b04cf200c6" title="permalink">#</a> </h3> <p> Should I be writing unit tests for this implementation? </p> <p> I don't see how a test would be anything but a duplication of the two 'transition tables'. <em>Given that the score is thirty-love, when player one wins the ball, then the new score should be forty-love</em>. Indeed, the <code>ballOne</code> function already states that. </p> <p> We <a href="/2013/04/02/why-trust-tests">trust tests because they are simple</a>. When the implementation is as simple as the test that would exercise it, then what's the benefit of the test? </p> <p> To be clear, there are still compelling reasons to write tests for some simple implementations, but that's another discussion. I don't think those reasons apply here. I'll write no tests. </p> <h3 id="fb03ecc39926472790ba2c5eaa025a91"> Code size <a href="#fb03ecc39926472790ba2c5eaa025a91" title="permalink">#</a> </h3> <p> While this code is utterly dull, it takes up some space. In all, it runs to 67 lines of code. </p> <p> For comparison, the code base that evolves throughout my <a href="/2016/02/10/types-properties-software">Types + Properties = Software</a> article series is 65 lines of code, not counting the tests. When I also count the tests, that entire code base contains around 300 lines of code. That's more than four times as much code. </p> <p> Preliminary <a href="https://amzn.to/2OBNBoY">research implies that bug count correlates linearly with line count</a>. The more lines of code, the more bugs. </p> <p> While I believe that this is probably a simplistic rule of thumb, there's much to like about smaller code bases. In total, this utterly dull implementation is actually smaller than a comparable implementation built from small functions. </p> <h3 id="5ac7b217f375464aa21320c8f0bfe0a7"> Conclusion <a href="#5ac7b217f375464aa21320c8f0bfe0a7" title="permalink">#</a> </h3> <p> Many software problems can be modelled as finite state machines. I find that this is often the case in my own field of line-of-business software and web services. </p> <p> It's not always possible to exhaustively enumerate all states, because each 'type' of state carries data that can't practically be enumerated. For example, <a href="/2017/06/27/pure-times">polling consumers</a> need to carry timing statistics. These statistics influence how the state machine transitions, but the range of possible values is so vast that it can't be enumerated as types. </p> <p> It may not happen often that you can fully enumerate all states and transitions of a finite state machine, but I think it's worthwhile to be aware of such refactoring opportunities. It might make your code dully simple. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="57354557ce724eefb675d8788c5bea94"> <div class="comment-author"><a href="https://taeguk.co.uk">Dave Shaw</a></div> <div class="comment-content"> <p>Hi Mark, I have had a similar experience whilst coding a <a href="https://en.wikipedia.org/wiki/Shut_the_box"> Shut the box</a> game, when trying to detect if it was game over or not. <br/> Originally it was a complex set of loops to calculate all the discrete summands for each roll of the dice, then checking if the remaining flaps were in that set. This was done along with a suite of tests for every possible combination set of summands up to 12 (for 2 dice). <br /> Then whilst explaining the pain in writing this to a friend, they simply said, <i>there's only a finite list, why not hard code them?</i>, and that's what I went with, a dictionary with each possible roll from 2 dice, and the possible values from the flaps that could be used to meet that roll. All the tests were removed; as you pointed out, they would just be a reimplmentation of the table. </p> </div> <div class="comment-date">2021-04-07 13:30 UTC</div> </div> <div class="comment" id="858ccadaae1b41268d3bf4454ab9fcb0"> <div class="comment-author"><a href="/">Mark Seemann</a></div> <div class="comment-content"> <p> Dave, thank you for writing. It's good to hear that you have a similar experience. I wonder if it's constrained to game simulation, or if 'real-world' examples exist. </p> </div> <div class="comment-date">2021-04-09 6:30 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>. The dispassionate developer https://blog.ploeh.dk/2021/03/22/the-dispassionate-developer 2021-03-22T06:50:00+00:00 Mark Seemann <div id="post"> <p> <em>Caring for your craft is fine, but should you work for free?</em> </p> <p> I've met many passionate developers in my career. Programmers who are deeply interested in technology, programming languages, methodology, and self-improvement. I've also seen many online profiles where people present themselves as 'passionate developers'. </p> <p> These are the people who organise and speak at user groups. They write blog posts and host podcasts. They contribute to open source development in their free time. </p> <p> I suppose that I can check many of those boxes myself. In the last few years, though, I've become increasingly sceptic that this is a good idea. </p> <h3 id="8894ee52bd514210a5f8193f38634f43"> Working for free <a href="#8894ee52bd514210a5f8193f38634f43" title="permalink">#</a> </h3> <p> In the last five years or so, I've noticed what looks like a new trend. Programmers contact me to ask about paid mentorship. They offer to pay me <em>out of their own pocket</em> to mentor them. </p> <p> I find that flattering, but it also makes me increasingly disenchanted with the software development industry. To be clear, this isn't an attack on the good people who care so much about their craft that they are willing to spend their hard-earned cash on improving their skill. This is more a reflection on employers. </p> <p> For reasons that are complicated and that I don't fully understand, the software development community in the eighties and nineties developed a culture of anti-capitalism and liberal values that put technology on a pedestal for its own sake. Open source good; commercial software bad. Free software good; commercial software bad. </p> <p> I'm not entirely unsympathetic to such ideas, but it's seems clear, now, that these ideas have had unintended consequences. The idea of free software, for example, has led to a software economy where you, the user, are no longer the customer, but the product. </p> <p> The idea of open source, too, seems largely defunct as a means of 'sticking it to the man'. The big tech companies now embrace open source. Despite initial enmity towards open source, <a href="https://en.wikipedia.org/wiki/Microsoft_and_open_source">Microsoft now owns GitHub and is one of the most active contributors</a>. Google and Facebook control popular front-end platforms such as <a href="https://en.wikipedia.org/wiki/Angular_(web_framework)">Angular</a> and <a href="https://en.wikipedia.org/wiki/React_(JavaScript_library)">React</a>, as well as many other technologies such as <a href="https://en.wikipedia.org/wiki/Android_(operating_system)">Android</a> or <a href="https://en.wikipedia.org/wiki/GraphQL">GraphQL</a>. Continue the list at your own leisure. </p> <p> Developing open source is seen as a way to establish credibility, not only for companies, but for individuals as well. Would you like a cool job in tech? Show me your open-source portfolio. </p> <p> Granted, the focus on open-source contributions as a replacement for a CV seems to have peaked, and good riddance. </p> <p> I deliberately chose to use the word <em>portfolio</em>, above. Like a struggling artist, you're expected to show up with such a stunning sample of your work that you amaze your potential new employer and blow away your competition. Unlike struggling artists, though, you've already given away everything in your portfolio, and so have other job applicants. Employers benefit from this. You work for free. </p> <h3 id="2d37b0297422447c9c92e2f18828f5a7"> The passion ethos <a href="#2d37b0297422447c9c92e2f18828f5a7" title="permalink">#</a> </h3> <p> You're expected to 'contribute' to open source software. Why? Because employers want employees who are <em>passionate</em> about their craft. </p> <p> As you start to ponder the implied ethos, the stranger it gets. Would you like engineers to be <em>passionate</em> as they design new bridges? Would you like a surgeon to be <em>passionate</em> as she operates on you? Would you like judges to be <em>passionate</em> as they pass sentence on your friend? </p> <p> I'd like such people to <em>care</em> about their vocation, but I'd prefer that they keep a cool head and make as rational decisions as possible. </p> <p> Why should programmers be <em>passionate?</em> </p> <p> I don't think that it's in our interest to be passionate, but it <em>is</em> in employers' interest. Not only are passionate people expected to work for free, they're also easier to manipulate. Tell a passionate person something he wants to hear, and he may turn off further critical thinking because the praise <em>feels</em> good. </p> <p> Some open-source maintainers have created crucial software that runs everywhere. Companies make millions off that free software, while maintainers are often left with an increasing support burden and no money. </p> <p> They do, however, often get a pat on the back. They get invited to speak at conferences, and can add <em>creator of Xyz</em> to their social media bios. </p> <p> Until they burn out, that is. <ins datetime="2021-03-22T11:49Z"><em>Passion</em>, after all, comes from the Latin for <em>suffering</em></ins>. </p> <h3 id="192b9f90f1e94fcf97649edc5c234f39"> Self-improvement <a href="#192b9f90f1e94fcf97649edc5c234f39" title="permalink">#</a> </h3> <p> I remember consulting with a development organisation, helping them adopt some new technology. As my engagement was winding down, I had a meeting with the manager to discuss how they should be able to carry on without me. This was back in my Microsoft days, so I suggested that they institute a training programme for the employees. To give it structure, they could, for example, study for some Microsoft certifications. </p> <p> The development manager immediately shot down that idea: <em>"If we do that, they'll leave us once they have the certification."</em> </p> <p> I was flabbergasted. </p> <p> You've probably seen quotes like this: <blockquote> <p> "What happens if we train our people and they leave?" </p> <p> "What happens if we don't and they stay?" </p> </blockquote> This is one of those bon mots that seem impossible to attribute to a particular source, but the idea is clear enough. The sentiment doesn't seem to represent mainstream behaviour, though. </p> <p> Granted, I've met more than one visionary leader willing to invest in employees' careers, but most managers don't. </p> <p> While I teach and coach internationally, I naturally have more experience with my home region of Copenhagen, and more broadly Scandinavia. Here, it's a common position that anything that relates to work should only happen during work hours. If the employer doesn't allow training on the job, then most employees don't train. </p> <p> What happens if you don't keep up to date with new methodologies, new frameworks, new programming languages? Your skill set becomes obsolete. Not overnight, but over the years. Finding a new job becomes harder and harder. </p> <p> As your marketability atrophies, your employer can treat you worse and worse. After all, where are you going to go? </p> <p> If you're tired of working with legacy code without tests, most of your suggestions for improvements will be met by a shrug. <em>We don't have time for that now. It's more important to deliver value to the customer.</em> </p> <p> You'll have to work long hours and weekends fire-fighting 'unexpected' issues in production while still meeting deadlines. </p> <p> A sufficiently cynical employer may have no qualms keeping employees busy this way. </p> <p> To be clear, I'm not saying that it's good business sense to treat skilled employees like this, and I'm not saying that this is how <em>all</em> employers conduct business, but I've seen enough development organisations that fit the description. </p> <p> As disappointing as it may be, keeping up to date with technology is <em>your</em> responsibility, and if you can't sneak in some time for self-improvement at work, you'll have to do it on your own time. </p> <p> This has little to do with passion, but much to do with self-preservation. </p> <h3 id="a40b07d82eef4ee0a657df53662b4418"> Can I help you? <a href="#a40b07d82eef4ee0a657df53662b4418" title="permalink">#</a> </h3> <p> The programmers who contact me (and others) for mentorship are the enlightened ones who've already figured this out. </p> <p> That doesn't mean that I'm comfortable taking people's hard-earned money. If I teach you something that improves your productivity, your employer benefits, too. I think that your employer should pay for that. </p> <p> I'm aware that most companies don't want to do that. It's also my experience that while most employers couldn't care less whether you pay me for mentorship, they don't want you to show me their code. This basically means that I can't really mentor you, unless you can reproduce the problems you're having as anonymised code examples. </p> <p> But if you can do that, you can ask the whole internet. You can try asking on <a href="https://stackoverflow.com">Stack Overflow</a> and then ping me. You're also welcome to ask me. If your <a href="https://en.wikipedia.org/wiki/Minimal_working_example">minimal working example</a> is interesting, I may turn it into a blog post, and you pay nothing. </p> <p> People also ask me how they can convince their managers or colleagues to do things differently. I often wonder why they don't <a href="/2019/03/18/the-programmer-as-decision-maker">make technical decisions</a> already, but this may be my cultural bias talking. In Denmark you can often get away with the ask-for-forgiveness-rather-than-permission attitude, but it may not be a good idea in your culture. </p> <p> Can I magically convince your manager to do things differently? Not magically, but I do know an effective trick: get him or her to hire me (or another expensive consultant). Most people don't heed advice given for free, but if they pay dearly for it, they tend to pay attention. </p> <p> Other than that, I can only help you as I've passionately tried to help the world-wide community for decades: by blogging, answering questions on Stack Overflow, writing books, <a href="/schedule">speaking at user groups and conferences</a>, <a href="/about#video">publishing videos</a>, and so on. </p> <h3 id="2eb915d9d2aa411884599d592a310be0"> Ticking most of the boxes <a href="#2eb915d9d2aa411884599d592a310be0" title="permalink">#</a> </h3> <p> Yes, I know that I fit the mould of the <em>passionate developer</em>. I've blogged regularly since 2006, I've <a href="https://stackoverflow.com/users/126014/mark-seemann?tab=answers">answered thousands of questions on Stack Overflow</a>, I've given more than a hundred presentations, been a podcast guest, and co-written <a href="/dippp">a book</a>, none of which has made me rich. If I don't do it for the passion, then why do I do it? </p> <p> Sometimes it's hard and tedious work, but even so, I do much of it because I can't really help it. I <em>like</em> to write and teach. I suppose that makes me passionate. </p> <p> My point with this article isn't that there's anything wrong with being passionate about software development. The point is that you might want to regard it as a <em>weakness</em> rather than an asset. If you <em>are</em> passionate, beware that someone doesn't take advantage of you. </p> <p> I realise that I didn't view the world like this when I started blogging in January 2006. I was driven by my passion. In retrospect, though, I think that I have been both privileged and fortunate. I'm not sure my career path is reproducible today. </p> <p> When I started blogging, it was a new-fangled thing. Just the fact that you blogged was enough to you get a little attention. I was in the right place at the right time. </p> <p> The same is true for Stack Overflow. The site was still fairly new when I started, and a lot of frequently asked questions were only asked on my watch. I still get upvotes on answers from 2009, because these are questions that people still ask. I was just lucky enough to be around <em>the first time</em> it was asked on the site. </p> <p> I'm also privileged by being an able-bodied man born into the middle class in one the world's richest countries. I received a free education. Denmark has free health care and generous social security. Taking some chances with your career in such an environment isn't even reckless. I've worked for more than one startup. That's not risky here. Twice, I've worked for a company that went out of business; in none of those cases did I lose money. </p> <p> Yes, I've been fortunate, but my point is that you should probably not use my career as a model for yours, just as you shouldn't use those of <a href="https://en.wikipedia.org/wiki/Robert_C._Martin">Robert C. Martin</a>, <a href="https://en.wikipedia.org/wiki/Kent_Beck">Kent Beck</a>, or <a href="https://en.wikipedia.org/wiki/Martin_Fowler_(software_engineer)">Martin Fowler</a>. It's hardly a reproducible career path. </p> <h3 id="47dbcc3e81fc408881d0a173f5226f53"> Conclusion <a href="#47dbcc3e81fc408881d0a173f5226f53" title="permalink">#</a> </h3> <p> What <em>can</em> you do, then, if you want to stand out from the crowd? How <em>do</em> you advance your software development career? </p> <p> I don't know. I never claimed that this was easy. </p> <p> Being good at something helps, but you must also make sure that the right people know what you're good at. You're probably still going to have to invest some of your 'free' time to make that happen. </p> <p> Just beware that you aren't being taken advantage of. Be dispassionate. </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="c86dd3a1f4814201a7d15ba3b95c67c0"> <div class="comment-author"><a href="https://github.com/Jankowski-J">Jakub Jankowski</a></div> <div class="comment-content"> <p> Thanks Mark for your post. </p> <p> I really relate to your comment about portfolio. I am still a young developer, not even 30 years old. A few years ago, I had an unhealthy obsession, that I should have a portfolio, otherwise I would be having a hard time finding job. </p> <p> I am not entirely sure where this thought was coming from, but it is not important in what I want to convey. I was worrying that I do not have a portfolio and that anxiety itself, prevented me from doing any real work to have anything to showcase. Kinda vicious cycle. </p> <p> Anyways, even without a portfolio, I didn't have any troubles switching jobs. I focused on presenting what I have learned in every project I worked on. What was good about it, what were the struggles. I presented myself not as a just a "mercenary" if you will. I always gave my best at jobs and at the interviews and somehow managed to prove to myself that a portfolio is not a <em>must</em>. </p> <p> Granted, everybody's experience is different and we all work in different market conditions. But my takeaway is - don't fixate on a thing, if it's not an issue. That's kinda what I was doing a few years back. </p> </div> <div class="comment-date">2021-03-28 16:25 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>. Pendulum swing: pure by default https://blog.ploeh.dk/2021/03/15/pendulum-swing-pure-by-default 2021-03-15T06:47:00+00:00 Mark Seemann <div id="post"> <p> <em>Favour pure functions over polymorphic dependencies.</em> </p> <p> This is an article in <a href="/2021/02/22/pendulum-swings">a small series of articles about personal pendulum swings</a>. Here, I'll discuss another contemporary one-eighty. This one is older than the other two I've discussed in this article series, but I believe that it deserves to be included. </p> <p> Once upon I time, I used to consider Dependency Injection (DI) and injected interfaces an unequivocal good: the more, the merrier. These days, I tend to only model true application dependencies as injected dependencies. For the rest, I use <a href="https://en.wikipedia.org/wiki/Pure_function">pure functions</a>. </p> <h3 id="52438454eb1747cb81e897e1a44dfa1b"> Background <a href="#52438454eb1747cb81e897e1a44dfa1b" title="permalink">#</a> </h3> <p> When I started my programming career, I'd barely taught myself to program. I worked in both Visual Basic, VBScript, and C++ before I encountered the concept of an interface. What C++ I wrote was entirely procedural, and I don't recall being aware of inheritance. Visual Basic 6 didn't have inheritance, and I'm fairly sure that VBScript didn't, either. </p> <p> I vaguely recall first being introduced to the concept of an interface in Visual Basic. It took me some time to wrap my head around it, and while I thought it seemed clever, I couldn't find any practical use for it. </p> <p> I think that I wrote my first professional C# code base in 2002. We didn't use Dependency Injection or interfaces. I don't even recall that we used much inheritance. </p> <h3 id="cae8dc76412149dbbe4eb4854888f652"> Inject all the things <a href="#cae8dc76412149dbbe4eb4854888f652" title="permalink">#</a> </h3> <p> When I discovered test-driven development (TDD) the year after, it didn't take me too long to figure out that I'd need to isolate units from their dependencies. Based on initial successes, I even wrote <a href="https://docs.microsoft.com/archive/msdn-magazine/2004/october/unit-testing-mock-objects-to-the-rescue-test-your-net-code-with-nmock">an article about mock objects</a> for MSDN Magazine October 2004. </p> <p> At that time I'd made interfaces a part of my active technique. I still struggled with how to replace a unit's 'real' dependencies with the mock objects. Initially, I used what I in <a href="https://amzn.to/36xLycs">Dependency Injection in .NET</a> later called <em>Bastard Injection</em>. As I also described in the book, things took a dark turn for while as I discovered the <a href="/2010/02/03/ServiceLocatorisanAnti-Pattern">Service Locator anti-pattern</a> - only, at that time, I didn't realise that it was an anti-pattern. Soon after, fortunately, I discovered <a href="/2014/06/10/pure-di">Pure DI</a>. </p> <p> That problem solved, I began an era of my programming career where everything became an interface. It does enable unit testing, so it's better than not being able to test, but after some years I began to sense the limits. </p> <p> Perhaps the worst problem is that you get a deluge of interfaces. Many of these interfaces have similar-sounding names like <code>IReservationsManager</code> and <code>IRestaurantManager</code>. This makes discoverability harder: Which of these interfaces should you use? One defines <a href="/2020/11/23/good-names-are-skin-deep">a <code>TrySave</code> method, the other a <code>Check</code> method</a>, and they aren't that different. </p> <p> This wasn't clear to me when I worked in teams with one or two programmers. Once I saw how this played out in larger teams, however, I began to understand that one developer's interface remained undiscovered by other team members. When existing 'abstractions' are unclear, it leads to frequent reinvention of interfaces to implement the same functionality. Duplication abounds. </p> <p> Designing with many fine-grained dependencies also has a tendency drag into existence many <em>factory interfaces</em>, a <a href="https://blogs.cuttingedge.it/steven/posts/2016/abstract-factories-are-a-code-smell">well-known design smell</a>. </p> <h3 id="b29309513d1946238cb08718f6be8903"> Have a sandwich <a href="#b29309513d1946238cb08718f6be8903" title="permalink">#</a> </h3> <p> It's remarkable how effectively you can lie to yourself. As late as 2017 <a href="https://softwareengineering.stackexchange.com/a/356822/19115">I still concluded that fine-grained dependencies were best</a>, despite most of my arguments pointing in another direction. </p> <p> I first encountered functional programming in 2010, but was off to a slow start. It took me years before I realised that <a href="/2017/01/27/from-dependency-injection-to-dependency-rejection">Dependency Injection isn't functional</a>. There are other ways to address the problem of separating pure functions from impure actions, the simplest of which is the <a href="/2020/03/02/impureim-sandwich">impureim sandwich</a>. </p> <p> Which parts of the application architecture are inherently impure? The usual suspects: the system clock, random number generators, the file system, databases, network resources. Notice how these are the dependencies that you usually need to replace with <a href="http://xunitpatterns.com/Test%20Double.html">Test Doubles</a> in order to make unit tests deterministic. </p> <p> It makes sense to model these as dependencies. I still define interfaces for those and use Dependency Injection to control them. I do, however, use the impureim sandwich architecture to deal with the impure actions first, so that I can then delegate all the complex decision logic to pure functions. </p> <p> <a href="/2015/05/07/functional-design-is-intrinsically-testable">Pure functions are intrinsically testable</a>, so that solves many of the problems with testability. There's still a need to test how the impure actions interact with the pure functions. Here I take a step up in the <a href="https://martinfowler.com/bliki/TestPyramid.html">Test Pyramid</a> and write just enough <a href="/2019/02/18/from-interaction-based-to-state-based-testing">state-based integration tests</a> to render it probable that the integration works as intended. You can see an example of such a test <a href="/2021/01/18/parametrised-test-primitive-obsession-code-smell">here</a>. </p> <h3 id="bb9264be0f1648b48f6572e1054fab95"> Conclusion <a href="#bb9264be0f1648b48f6572e1054fab95" title="permalink">#</a> </h3> <p> From having favoured fine-grained Dependency Injection, I now write all decision logic as pure functions by default. These only need to implement interfaces if you need the <em>logic</em> of the system to be interchangeable, which isn't that often. I do still use Dependency Injection for the impure dependencies of the system. There's usually only a handful of those. </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>. Pendulum swing: sealed by default https://blog.ploeh.dk/2021/03/08/pendulum-swing-sealed-by-default 2021-03-08T07:28:00+00:00 Mark Seemann <div id="post"> <p> <em>Inheritance is evil. Seal your classes.</em> </p> <p> This is an article in <a href="/2021/02/22/pendulum-swings">a small series of articles about personal pendulum swings</a>. Here, I document another recent change of heart that's been a long way coming. In short, I now <code>seal</code> C# classes whenever I remember to do it. </p> <p> <ins datetime="2021-06-15T06:14Z">The code shown here is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> <h3 id="1f7f814e8f314fd291ad5fd73b12c7bf"> Background <a href="#1f7f814e8f314fd291ad5fd73b12c7bf" title="permalink">#</a> </h3> <p> After I discovered test-driven development (TDD) (circa 2003) I embarked on a quest for proper ways to enable testability. <a href="https://martinfowler.com/articles/nonDeterminism.html">Automated tests should be deterministic</a>, but real software systems rarely are. Software depends on the system clock, random number generators, the file system, the states of databases, web services, and so on. All of these may change independently of the software, making it difficult to express an automated systems test in a deterministic manner. </p> <p> This is a known problem in TDD. In order to get the system under test (SUT) under control, you have to <a href="http://bit.ly/working-effectively-with-legacy-code">introduce what Michael Feathers calls <em>seams</em></a>. In C#, there's traditionally been two ways you could do that: <a href="/2016/06/15/sut-double">extract and override</a>, and interfaces. </p> <p> The original <a href="http://amzn.to/16E4q3z">Framework Design Guidelines</a> explicitly recommended base classes over interfaces, and I wasn't wise to how unfortunate that recommendation was. For a long time, I'd define abstractions with (abstract) base classes. I was even envious of Java, where instance members are virtual (overridable) by default. In C# you must explicitly declare a method <code>virtual</code> to make it overridable. </p> <p> Abstract base classes aren't too bad if you leave them completely empty, but I never had much success with non-abstract base classes and virtual members and the whole extract-and-override manoeuvre. I soon concluded that <a href="/2016/06/15/sut-double">Dependency Injection with interfaces</a> was a better alternative. </p> <p> Even after I changed to exclusively relying on interfaces (instead of abstract base classes), remnants of the rule stuck with me for years: <em>unsealed good; sealed bad</em>. Even today, the framework design guidelines favour unsealed classes: <blockquote> <p> "CONSIDER using unsealed classes with no added virtual or protected members as a great way to provide inexpensive yet much appreciated extensibility to a framework." </p> <footer><cite><a href="https://docs.microsoft.com/dotnet/standard/design-guidelines/unsealed-classes">Framework Design Guidelines</a></cite></footer> </blockquote> I can no longer agree with this guidance; I think it's poor advice. </p> <h3 id="ae5513333afc437fb4ac795c2af8a4a1"> You don't need inheritance <a href="#ae5513333afc437fb4ac795c2af8a4a1" title="permalink">#</a> </h3> <p> Base classes imply class inheritance as a reuse and extensibility mechanism. We've known since 1994, though, that inheritance probably isn't the best design principle. <blockquote> <p> "Favor object composition over class inheritance." </p> <footer><cite><a href="http://amzn.to/XBYukB">Design Patterns</a></cite></footer> </blockquote> In single-inheritance languages like C# and Java, inheritance is just evil. Once you decide to inherit from a base class, you exclude all other base classes. <em>Inheritance signifies a single 'yes' and an infinity of 'noes'.</em> This is particularly problematic if you rely on inheritance for reuse. You can only 'reuse' a single base class, which again leads to duplication or bloated base classes. </p> <p> It's been years (probably more than a decade) since I stopped relying on base classes for anything. You don't need inheritance. <a href="https://www.haskell.org">Haskell</a> doesn't have it at all, and I only use it in C# when a framework forces me to derive from some base class. </p> <p> There's little you can do with an abstract class that you can't do in some other way. <a href="/2018/02/19/abstract-class-isomorphism">Abstract classes are isomorphic with Dependency Injection up to accessibility.</a> </p> <h3 id="516f72a613aa4884a86448da1c256ebb"> Seal <a href="#516f72a613aa4884a86448da1c256ebb" title="permalink">#</a> </h3> <p> If I already follow a design principle of not relying on inheritance, then why keep classes unsealed? <a href="https://www.python.org/dev/peps/pep-0020">Explicit is better than implicit</a>, so why not make that principle visible? Seal classes. </p> <p> It doesn't have any immediate impact on the code, but it might make it clearer to other programmers that an explicit decision was made. </p> <p> You already saw examples in the <a href="/2021/03/01/pendulum-swing-internal-by-default">previous article</a>: Both <code>Month</code> and <code>Seating</code> are sealed classes. They're also immutable records. I seal more than record types, too: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">HomeController</span></pre> </p> <p> I seal Controllers, as well as services: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">SmtpPostOffice</span>&nbsp;:&nbsp;<span style="color:#2b91af;">IPostOffice</span></pre> </p> <p> Another example is <a href="/2020/11/09/checking-signed-urls-with-aspnet">an ASP.NET filter</a> named <code>UrlIntegrityFilter</code>. </p> <p> A common counter-argument is that 'you may need extensibility in the future': <blockquote> <p> "by using "sealed" and not virtual in libs dev says "I thought of all extension point" which seems arrogant" </p> <footer><cite><a href="https://twitter.com/dun3/status/586790512528596992">Tobias Hertkorn</a></cite></footer> </blockquote> I agree that it'd be arrogant to claim that you've thought about all extension points. Trying to predict future need is futile. </p> <p> I don't agree, however, that making everything virtual is a good idea, but it's because I disagree with the underlying premise. The presupposition is that extensibility should be enabled through inheritance. If it's not already clear, I believe that this has many undesirable consequences. There are better ways to enable extensibility than through inheritance. </p> <h3 id="3ab4e94848d742aa8e3b12377415e8d1"> Conclusion <a href="#3ab4e94848d742aa8e3b12377415e8d1" title="permalink">#</a> </h3> <p> I've begun to routinely seal new classes. I don't always remember to do it, but I think that I ought to. As I also explained in the previous article, this is only my default. If something has to be a base class, that's still an option. Likewise, just because a class starts out <code>sealed</code> doesn't mean that it has to stay <code>sealed</code> forever. While sealing an unsealed class is a breaking change, unsealing a sealed class isn't. </p> <p> I can't think of any reason why I'd do that, though. </p> <p> <strong>Next: </strong> <a href="/2021/03/15/pendulum-swing-pure-by-default">Pendulum swing: pure by default</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>. Pendulum swing: internal by default https://blog.ploeh.dk/2021/03/01/pendulum-swing-internal-by-default 2021-03-01T08:26:00+00:00 Mark Seemann <div id="post"> <p> <em>Declare new C# classes as internal by default, and public by choice.</em> </p> <p> This is an article in <a href="/2021/02/22/pendulum-swings">a small series of articles about personal pendulum swings</a>. Here, I document a recent change of heart that's been a long way coming. In short, I now declare C# classes as <code>internal</code> unless they're driven by tests. </p> <p> <ins datetime="2021-06-15T06:14Z">The code shown here is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> <h3 id="199c0f3d9cdc4ee5a6e93ce54a3f39a8"> Background <a href="#199c0f3d9cdc4ee5a6e93ce54a3f39a8" title="permalink">#</a> </h3> <p> When you create a new class in Visual Studio, the default accessibility is <code>internal</code>. In fact, Visual Studio's default templates don't add an access modifier at all, but if no access modifier is present, it implies <code>internal</code>. </p> <p> When I started out programming C#, I don't recall thinking much about accessibility modifiers. By default, then, I'd be using mostly <code>internal</code> classes. What little I knew about encapsulation (<em>information hiding</em>, anyone?) led me to believe that the more <code>internal</code> my code was, the better encapsulation it had. </p> <p> It's possible that I make my past self more ignorant than I actually was. It's almost twenty years ago: I don't recall all the details. </p> <h3 id="c98c637b240f4f0c97d6fc4d0f7d10f2"> Public all the things <a href="#c98c637b240f4f0c97d6fc4d0f7d10f2" title="permalink">#</a> </h3> <p> When I discovered test-driven development (TDD) (circa 2003) all my classes became public. They had to. When tests are interacting with code in another library, they can only exercise the system under test (SUT) if they can reach it. The tests make the SUT classes public. </p> <p> Yes, it's technically possible to test <code>internal</code> classes in .NET, but <a href="/2015/09/22/unit-testing-internals">I don't believe that you should</a>. I've yet to change my mind about that; no imminent pendulum swing there. You're testing something you <em>care</em> about. If the <code>internal</code> code serves any, <em>any</em>, purpose, it must be somehow observable. If so, verify that such observable behaviour takes place; if not, delete the code. (I'm sure you can dream up some corner cases where this doesn't hold; fine: I'm painting with a broad brush, here.) </p> <p> For years, I applied TDD, but I wasn't aware of the red-green-refactor cycle. I rarely changed the public API that the tests interacted with, and when I did, I made sure to adjust the tests accordingly. If a refactoring gave rise to new classes, I'd often write tests for those new classes as well. </p> <p> Imagine, for example, invoking the <em>Extract Class</em> refactoring. The new class would be as covered by tests as before the extraction, but what happens next is typically that you need to tweak it. When that happened to me, I'd typically write completely new tests to cover it. To do that, I'd need the extracted class to be <code>public</code>. </p> <p> In this phase of my professional life, my classes were almost exclusively <code>public</code>, with <code>internal</code> classes only making a rare appearance. </p> <p> One problem this tends to cause is that it makes code bases more brittle. Every type change is a potential breaking change. When every public class is covered by tests, this makes tests brittle. </p> <p> I think that it's relevant to consider the context of the code base. At this phase of my professional life, I maintained <a href="https://github.com/AutoFixture/AutoFixture">AutoFixture</a>, a fairly popular open-source library. I wanted that library to be stable so that users could trust it. I considered the test suite a guard of the contract. As long as a change didn't break any test, I considered it likely that it wasn't a breaking change. Thus, I was already conservative when it came to editing tests. I <a href="/2013/04/02/why-trust-tests">considered test to be append-only</a> in principle. </p> <p> I still consider it prudent to be conservative when it comes to a library with a public API. This doesn't mean, however, that this line of thinking carries over to code bases without a public (language-level) API. This may include web sites and services, but could also include installed apps. As long as there's no public API, there's no contract to break. </p> <h3 id="af12c8cba91944a29b9c377f5c3e045f"> Internal by default <a href="#af12c8cba91944a29b9c377f5c3e045f" title="permalink">#</a> </h3> <p> In 2020 I wrote a REST API of middling complexity. I used <a href="/outside-in-tdd">outside-in TDD</a> as a major driver. In the spirit of behaviour-driven development I favour describing the observable behaviour of the system. I use <a href="/2021/01/25/self-hosted-integration-tests-in-aspnet">self-hosted</a> <a href="/2019/02/18/from-interaction-based-to-state-based-testing">state-based integration tests</a> for this purpose. Only when I find that these tests get too complex do I grudgingly drop down to the unit-test level. </p> <p> The things that I test with unit tests have to be <code>public</code>. This still leaves plenty of room for behaviour described by the integration tests to have <code>internal</code> implementation details. The code base I mentioned has several examples of that. Some of them I've already described here on the blog. </p> <p> For example, notice that the <code>LinksFilter</code> <a href="/2020/08/24/adding-rest-links-as-a-cross-cutting-concern">shown here</a> is an <code>internal</code> class. Its behaviour is covered by abundant integration tests, so I'm not afraid to refactor it if need be. Those <code>LinkToYear</code>, <code>LinkToMonth</code>, and <code>LinkToDay</code> extension methods that it uses <a href="/2020/08/10/an-aspnet-core-url-builder">are internal too</a>. </p> <p> Another example is the <code>UrlIntegrityFilter</code> <a href="/2020/11/09/checking-signed-urls-with-aspnet">seen here</a>. The class itself is <code>internal</code> and its behaviour is composed from <code>private</code> helper functions. Its <a href="/2020/11/02/signing-urls-with-aspnet">counterpart</a> <code>SigningUrlHelper</code> is also <code>internal</code>. (Its companion <code>SigningUrlHelperFactory</code>, shown in the same article, is <code>public</code>, but that's an oversight on my part. It can easily be <code>internal</code> as well.) All that URL-signing behaviour is, again, covered by tests that verify the behaviour of the REST API. </p> <p> Another example from the same code base can be found in its so-called <em>calendar</em> feature. The system is an online restaurant reservation system. It allows clients to browse a day, a month, or even a year to see if there are any free spots for a given time slot. You can <a href="/2020/08/24/adding-rest-links-as-a-cross-cutting-concern">see an example here</a>. While I test-drove the calendar feature with integration tests, it quickly dawned on me that I had three disparate cases (day, month, year) that essentially represented the same concept: a <em>period</em>. </p> <p> A period is a closed set of heterogeneous data. A year contains only a single datum: the year itself (e.g. 2021). A month contains both a month and a year, and so on. A closed set of heterogeneous data describes a <a href="https://en.wikipedia.org/wiki/Tagged_union">sum type</a>, and since I know that in object-oriented programming, <a href="/2018/06/25/visitor-as-a-sum-type">sum types can be encoded as Visitors</a>, I introduced a Visitor API: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IPeriod</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">T</span>&nbsp;Accept&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:#2b91af;">IPeriodVisitor</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;visitor); } <span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">interface</span>&nbsp;<span style="color:#2b91af;">IPeriodVisitor</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">T</span>&nbsp;VisitYear(<span style="color:blue;">int</span>&nbsp;year); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">T</span>&nbsp;VisitMonth(<span style="color:blue;">int</span>&nbsp;year,&nbsp;<span style="color:blue;">int</span>&nbsp;month); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">T</span>&nbsp;VisitDay(<span style="color:blue;">int</span>&nbsp;year,&nbsp;<span style="color:blue;">int</span>&nbsp;month,&nbsp;<span style="color:blue;">int</span>&nbsp;day); }</pre> </p> <p> I decided, however, to keep this API <code>internal</code>, since this isn't the only possible way to model this feature. As is the case with the other examples I've shown here, the behaviour is covered by integration tests. I feel free to refactor. In fact, this Visitor-based API is actually the result of a refactoring from something more ad hoc that I didn't like. </p> <p> Here's one of the three <code>IPeriod</code> implementation, in case you're curious: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Month</span>&nbsp;:&nbsp;<span style="color:#2b91af;">IPeriod</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">int</span>&nbsp;year; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:blue;">int</span>&nbsp;month; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Month</span>(<span style="color:blue;">int</span>&nbsp;year,&nbsp;<span style="color:blue;">int</span>&nbsp;month) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.year&nbsp;=&nbsp;year; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.month&nbsp;=&nbsp;month; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">T</span>&nbsp;Accept&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:#2b91af;">IPeriodVisitor</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;visitor) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;visitor.VisitMonth(year,&nbsp;month); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;Equals(<span style="color:blue;">object</span>?&nbsp;obj) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;obj&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:#2b91af;">Month</span>&nbsp;month&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;year&nbsp;==&nbsp;month.year&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">this</span>.month&nbsp;==&nbsp;month.month; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;GetHashCode() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:#2b91af;">HashCode</span>.Combine(year,&nbsp;month); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> This class, too, is <code>internal</code>, as are its two companions <code>Day</code> and <code>Year</code>. I'll leave it as an exercise for the interested reader to implement these two classes, as well as <code>IPeriodVisitor&lt;T&gt;</code> implementations that return the next or previous period, or the first or last tick of the period, etcetera. </p> <h3 id="af9c22ec88af4e3fa5f4b5c2356b5692"> Public by choice <a href="#af9c22ec88af4e3fa5f4b5c2356b5692" title="permalink">#</a> </h3> <p> This shifted emphasis of mine isn't a return to a simpler time. It's not <em>internal all the things!</em> It's about shifting the default for classes that are <em>not</em> driven by tests. Those classes that are artefacts of TDD are still <code>public</code> since <a href="/2015/09/22/unit-testing-internals">I don't directly unit test internal classes</a>. </p> <p> Other classes may start out as <code>internal</code> and then get promoted to <code>public</code> by choice. For example, I'd introduced a <code>Seating</code> class in the code base to model how long a seating was supposed to take: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Seating</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">internal</span>&nbsp;<span style="color:#2b91af;">Seating</span>(<span style="color:#2b91af;">TimeSpan</span>&nbsp;seatingDuration,&nbsp;<span style="color:#2b91af;">Reservation</span>&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SeatingDuration&nbsp;=&nbsp;seatingDuration; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;=&nbsp;reservation; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Members&nbsp;follow...</span></pre> </p> <p> Some restaurants have second seatings (or more). They give you a predefined duration after which you're supposed to be done so that they can reuse your table for another party. I'd used the <code>Seating</code> class to encapsulate some logic related to that, such as the <code>Overlaps</code> method: </p> <p> <pre><span style="color:blue;">internal</span>&nbsp;<span style="color:#2b91af;">DateTime</span>&nbsp;Start { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">get</span>&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;Reservation.At;&nbsp;} } <span style="color:blue;">internal</span>&nbsp;<span style="color:#2b91af;">DateTime</span>&nbsp;End { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">get</span>&nbsp;{&nbsp;<span style="color:blue;">return</span>&nbsp;Start&nbsp;+&nbsp;SeatingDuration;&nbsp;} } <span style="color:blue;">internal</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;Overlaps(<span style="color:#2b91af;">Reservation</span>&nbsp;other) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;otherSeating&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">Seating</span>(SeatingDuration,&nbsp;other); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;Start&nbsp;&lt;&nbsp;otherSeating.End&nbsp;&amp;&amp;&nbsp;otherSeating.Start&nbsp;&lt;&nbsp;End; }</pre> </p> <p> While I considered this a well-designed little class with good encapsulation, I kept it <code>internal</code> simply because there was no need to make it <code>public</code>. It was indirectly covered by test cases, but it was a result of a refactoring and not directly test-driven. </p> <p> As I started to add a new feature, I realised that I'd be able to write new unit tests in a better way if I could reuse <code>Seating</code> and a variation of its <code>Overlaps</code> method. I considered it carefully and decided to make the class and its members public: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Seating</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Seating</span>(<span style="color:#2b91af;">TimeSpan</span>&nbsp;seatingDuration,&nbsp;<span style="color:#2b91af;">Reservation</span>&nbsp;reservation) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SeatingDuration&nbsp;=&nbsp;seatingDuration; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reservation&nbsp;=&nbsp;reservation; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Members&nbsp;follow...</span></pre> </p> <p> I made this decision after explicit deliberation. It didn't take long, though, but I did shortly stop to consider whether this seemed like a good idea. This code base isn't a <a href="/2012/12/18/RangersandZookeepers">reusable library in the wild</a>, so I wasn't concerned about misuse of the API. I did consider, on the other hand, how this would increase coupling between the tests and the production code base. It didn't take me long to decide that in this case, I was okay with that. </p> <p> <code>Seating</code> had already existed as an <code>internal</code> class for some time and had proven useful and stable. Putting on my <a href="http://amzn.to/WBCwx7">DDD</a> hat, I also thought that <code>Seating</code> represented a proper domain concept. </p> <h3 id="f6ef0cc965d845fe889170ee956baa4d"> Conclusion <a href="#f6ef0cc965d845fe889170ee956baa4d" title="permalink">#</a> </h3> <p> You can go back and forth on how you write code; which rules of thumb you apply. For many years, I favoured <code>public</code> classes. I think that I even, at one time, tweaked the Visual Studio templates to explicitly create new classes as <code>public</code>. </p> <p> Now, I've changed my heuristic. Classes driven into existence by tests are <code>public</code>; they have to be. Other classes I now make <em>internal by default, and public by choice</em>. </p> <p> This is going to be my rule until I change it. </p> <p> <strong>Next:</strong> <a href="/2021/03/08/pendulum-swing-sealed-by-default">Pendulum swing: sealed by default</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>. Pendulum swings https://blog.ploeh.dk/2021/02/22/pendulum-swings 2021-02-22T08:04:00+00:00 Mark Seemann <div id="post"> <p> <em>The software development industry goes back and forth on how to do things, and so do I.</em> </p> <p> I've been working with something IT-related since 1994, and I've been a professional programmer since 1999. When you observe the software development industry over decades, you may start to notice some trends. One decade, service-oriented architecture (SOA) is cool; the next, consolidation sets in; then it's micro-services; and, as far as I can tell, monoliths are on the way in again, although I'm sure that we'll find something else to call them. </p> <p> It's as if a pendulum swings from one extreme to the other. Sooner or later, it comes back, only to then continue its swing in the other direction. If you view it over time and assume no loss to friction, a pendulum describes a sine wave. </p> <p> <img src="/content/binary/sine-wave.png" alt="A sine wave."> </p> <p> There's probably several reasons for this motion. The benign interpretation is that it's still a young industry and we're still learning. It's not uncommon to see oscillations in dynamic systems, particularly when feedback isn't immediate. </p> <p> Software architecture tends to produce slow feedback. Architecture solves more than one problem, including scalability, but a major motivation to think about architecture is to pick a way to organise the source code so that you don't have to rewrite from scratch every 2-3 years. Tautologically, then, it takes years before you know whether or not you succeeded. </p> <p> While waiting for feedback, you may continue doing what you believe is right: micro-services versus monoliths, unit tests versus acceptance tests, etcetera. Once you discover that a particular way to work has problems, you may overcompensate by going too far in the other direction. </p> <p> Once you discover the problem with that, you may begin to pull back towards the original position. Because feedback is delayed, the pendulum once more swings too far. </p> <p> If we manage to learn from our mistakes, one could hope that the oscillations we currently observe will dampen until we reach equilibrium in the future. The industry is still so young, though, that the pendulum makes wide swings. Perhaps it'll takes decades, or even centuries, before the oscillations die down. </p> <p> The more cynic interpretation is that most software developers have only a few years of professional experience, and aren't taught the experiences of past generations. <blockquote> <p> "Those who cannot remember the past are condemned to repeat it." </p> <footer><cite>George Santayana</cite></footer> </blockquote> In this light, the industry keeps regurgitating the same ideas over and over, never learning from past mistakes. </p> <p> The truth is probably a mix of both explanations. </p> <h3 id="36d029a90bfa4d35a7e8fc10048b8bcc"> Personal pendulum <a href="#36d029a90bfa4d35a7e8fc10048b8bcc" title="permalink">#</a> </h3> <p> I've noticed a similar tendency in myself. I work in a particular way until I run into the limitations of that way. Then, after a time of frustration, I change direction. </p> <p> As an example, I'm an autodidact programmer. In the beginning of my career, I'd just throw together code until I thought it worked, then launch the software with the debugger attached only to discover that it didn't, then go back and tweak some more, and so on. </p> <p> Then I discovered test-driven development (TDD) and for years, it was the only way I could conceive of working. As my experience with TDD grew, I started to notice that it wasn't the panacea that I believed when it was all new. <a href="/2010/12/22/TheTDDApostate">I wrote about that as early as late 2010</a>. Knowing myself, I'd probably started to notice problems with TDD before that. I have cognitive biases just like the next person. You can lie to yourself for years before the problems become so blatant that you can no longer ignore them. </p> <p> To be clear, I never lost faith in TDD, but I began to glimpse the contours of its limitations. It's good for many circumstances, and it's still my preferred technique for developing new production code, but I use other techniques for e.g. prototyping. </p> <p> In 2020 I wrote a code base of middling complexity, and I noticed that I'd started to change my position on some other long-standing practices. As I've tried to explain, it may look like pendulum swings, but I hope that they are, at least, dampened swings. I intend to observe what happens so that I can learn from these new directions. </p> <p> In the following, I'll be writing about these new approaches that I'm trying on, and so far like: <ul> <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/03/15/pendulum-swing-pure-by-default">Pendulum swing: pure by default</a></li> </ul> I'd be naive if I believed these to be my final words on any of these topics. I'm currently trying them out for size; in a few decades I'll know more about how it all turns out. </p> <h3 id="fdb1ddeb6709428ca1f0e7f441085b3d"> Conclusion <a href="#fdb1ddeb6709428ca1f0e7f441085b3d" title="permalink">#</a> </h3> <p> One year TDD is all the rage; a few years later, it's BDD. One year it's SOA, then it's <a href="https://alistair.cockburn.us/hexagonal-architecture/">ports and adapters</a> (which implies consolidated deployment), then it's micro-services. One year, it's XML, then it's JSON, then it's YAML. One decade it's structured programming, then it's object-orientation, then it's functional programming, and so on ad nauseam. </p> <p> Hopefully, this is just a symptom of growing pains. Hopefully, we'll learn from all these wild swings so that we don't have to rewrite applications when older developers leave. </p> <p> The only course of action that I can see for myself here is to document how I work so that I, and others, can learn from those experiences. </p> <p> <strong>Next:</strong> <a href="/2021/03/01/pendulum-swing-internal-by-default">Pendulum swing: internal by default</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>. When properties are easier than examples https://blog.ploeh.dk/2021/02/15/when-properties-are-easier-than-examples 2021-02-15T07:33:00+00:00 Mark Seemann <div id="post"> <p> <em>Sometimes, describing the properties of a function is easier than coming up with examples.</em> </p> <p> Instead of the term <em>test-driven development</em> you may occasionally encounter the phrase <em>example-driven development</em>. The idea is that each test is an example of how the system under test ought to behave. As you add more tests, you add more examples. </p> <p> I've noticed that beginners often find it difficult to come up with good examples. This is the reason I've developed the <a href="/2019/10/07/devils-advocate">Devil's advocate</a> technique. It's meant as a heuristic that may help you identify the next good example. It's particularly effective if you combine it with the <a href="https://blog.cleancoder.com/uncle-bob/2013/05/27/TheTransformationPriorityPremise.html">Transformation Priority Premise</a> (TPP) and <a href="https://en.wikipedia.org/wiki/Equivalence_partitioning">equivalence partitioning</a>. </p> <p> I've noticed, however, that translating concrete examples into code is not always straightforward. In the following, I'll describe an experience I had in 2020 while developing an online restaurant reservation system. </p> <p> <ins datetime="2021-06-15T06:14Z">The code shown here is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> <h3 id="83a8dd13c9694ebc99b5fa4ae049b3b4"> Problem outline <a href="#83a8dd13c9694ebc99b5fa4ae049b3b4" title="permalink">#</a> </h3> <p> I'm going to start by explaining what it was that I was trying to do. I wanted to present the <a href="https://en.wikipedia.org/wiki/Ma%C3%AEtre_d%27h%C3%B4tel">maître d'</a> (or other restaurant staff) with a schedule of a day's reservations. It should take the form of a list of time entries, one entry for every time one or more new reservations would start. I also wanted to list, for each entry, all reservations that were currently ongoing, or would soon start. Here's a simple example, represented as JSON: </p> <p> <pre><span style="color:#2e75b6;">&quot;date&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2023-08-23&quot;</span>, <span style="color:#2e75b6;">&quot;entries&quot;</span>:&nbsp;[ &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;time&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;20:00:00&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;reservations&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;af5feb35f62f475cb02df2a281948829&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2023-08-23T20:00:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;crystalmeth@example.net&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Crystal&nbsp;Metheney&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;3 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;eae39bc5b3a7408eb2049373b2661e32&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2023-08-23T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;x.benedict@example.org&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Benedict&nbsp;Xavier&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;4 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;}, &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;time&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;20:30:00&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;reservations&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;af5feb35f62f475cb02df2a281948829&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2023-08-23T20:00:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;crystalmeth@example.net&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Crystal&nbsp;Metheney&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;3 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;eae39bc5b3a7408eb2049373b2661e32&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2023-08-23T20:30:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;x.benedict@example.org&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Benedict&nbsp;Xavier&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;4 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;} ]</pre> </p> <p> To keep the example simple, there are only two reservations for that particular day: one for 20:00 and one for 20:30. Since something happens at both of these times, both time has an entry. My intent isn't necessarily that a user interface should show the data in this way, but I wanted to make the relevant data available so that a user interface could show it if it needed to. </p> <p> The first entry for 20:00 shows both reservations. It shows the reservation for 20:00 for obvious reasons, and it shows the reservation for 20:30 to indicate that the staff can expect a party of four at 20:30. Since this restaurant runs with a single seating per evening, this effectively means that although the reservation hasn't started yet, it still reserves a table. This gives a user interface an opportunity to show the state of the restaurant at that time. The table for the 20:30 party isn't active yet, but it's effectively reserved. </p> <p> For restaurants with shorter seating durations, the schedule should reflect that. If the seating duration is, say, two hours, and someone has a reservation for 20:00, you can sell that table to another party at 18:00, but not at 18:30. I wanted the functionality to take such things into account. </p> <p> The other entry in the above example is for 20:30. Again, both reservations are shown because one is ongoing (and takes up a table) and the other is just starting. </p> <h3 id="63e308b1c630441e8f55fe3ecaa5a03f"> Desired API <a href="#63e308b1c630441e8f55fe3ecaa5a03f" title="permalink">#</a> </h3> <p> A major benefit of test-driven development (TDD) is that you get fast feedback on the API you intent for the system under test (SUT). You write a test against the intended API, and besides a pass-or-fail result, you also learn something about the interaction between client code and the SUT. You often learn that the original design you had in mind isn't going to work well once it meets the harsh realities of an actual programming language. </p> <p> In TDD, you often have to revise the design multiple times during the process. </p> <p> This doesn't mean that you can't have a plan. You can't write the initial test if you have no inkling of what the API should look like. For the schedule feature, I did have a plan. It turned out to hold, more or less. I wanted the API to be a method on a class called <code>MaitreD</code>, which already had these four fields and the constructors to support them: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">TimeOfDay</span>&nbsp;OpensAt&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">TimeOfDay</span>&nbsp;LastSeating&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">TimeSpan</span>&nbsp;SeatingDuration&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&nbsp;Tables&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;}</pre> </p> <p> I planned to implement the new feature as a new instance method on that class: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>)</pre> </p> <p> This plan turned out to hold in general, although I ultimately decided to simplify the return type by getting rid of the <code>Occurrence</code> <a href="https://bartoszmilewski.com/2014/01/14/functors-are-containers">container</a>. It's going to be present throughout this article, however, so I need to briefly introduce it. I meant to use it as a generic container of anything, but with an time-stamp associated with the value: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">T</span>&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Occurrence</span>(<span style="color:#2b91af;">DateTime</span>&nbsp;<span style="color:#1f377f;">at</span>,&nbsp;<span style="color:#2b91af;">T</span>&nbsp;<span style="color:#1f377f;">value</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;=&nbsp;<span style="color:#1f377f;">at</span>; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;=&nbsp;<span style="color:#1f377f;">value</span>; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">DateTime</span>&nbsp;At&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">T</span>&nbsp;Value&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">TResult</span>&gt;&nbsp;<span style="color:#74531f;">Select</span>&lt;<span style="color:#2b91af;">TResult</span>&gt;(<span style="color:#2b91af;">Func</span>&lt;<span style="color:#2b91af;">T</span>,&nbsp;<span style="color:#2b91af;">TResult</span>&gt;&nbsp;<span style="color:#1f377f;">selector</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(<span style="color:#1f377f;">selector</span>&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:blue;">null</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">throw</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">ArgumentNullException</span>(<span style="color:blue;">nameof</span>(<span style="color:#1f377f;">selector</span>)); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">TResult</span>&gt;(At,&nbsp;<span style="color:#1f377f;">selector</span>(Value)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">bool</span>&nbsp;<span style="color:#74531f;">Equals</span>(<span style="color:blue;">object</span>?&nbsp;<span style="color:#1f377f;">obj</span>) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#1f377f;">obj</span>&nbsp;<span style="color:blue;">is</span>&nbsp;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;<span style="color:#1f377f;">occurrence</span>&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;At&nbsp;<span style="color:#74531f;">==</span>&nbsp;<span style="color:#1f377f;">occurrence</span>.At&nbsp;&amp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">EqualityComparer</span>&lt;<span style="color:#2b91af;">T</span>&gt;.Default.<span style="color:#74531f;">Equals</span>(Value,&nbsp;<span style="color:#1f377f;">occurrence</span>.Value); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:blue;">override</span>&nbsp;<span style="color:blue;">int</span>&nbsp;<span style="color:#74531f;">GetHashCode</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#2b91af;">HashCode</span>.<span style="color:#74531f;">Combine</span>(At,&nbsp;Value); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> You may notice that due to the presence of the <code>Select</code> method this is a <a href="/2018/03/22/functors">functor</a>. </p> <p> There's also a little extension method that we may later encounter: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">T</span>&gt;&nbsp;<span style="color:#74531f;">At</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:blue;">this</span>&nbsp;<span style="color:#2b91af;">T</span>&nbsp;<span style="color:#1f377f;">value</span>,&nbsp;<span style="color:#2b91af;">DateTime</span>&nbsp;<span style="color:#1f377f;">at</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">T</span>&gt;(<span style="color:#1f377f;">at</span>,&nbsp;<span style="color:#1f377f;">value</span>); }</pre> </p> <p> The plan, then, is to return a collection of occurrences, each of which may contain a collection of tables that are relevant to include at that time entry. </p> <h3 id="d121920365874005a3bf46d0555bd008"> Examples <a href="#d121920365874005a3bf46d0555bd008" title="permalink">#</a> </h3> <p> When I embarked on developing this feature, I thought that it was a good fit for example-driven development. Since the input for <code>Schedule</code> requires a collection of <code>Reservation</code> objects, each of which comes with some data, I expected the test cases to become verbose. So I decided to bite the bullet right away and define test cases using <a href="https://xunit.net">xUnit.net</a>'s <code>[ClassData]</code> feature. I wrote this test: </p> <p> <pre>[<span style="color:#2b91af;">Theory</span>,&nbsp;<span style="color:#2b91af;">ClassData</span>(<span style="color:blue;">typeof</span>(<span style="color:#2b91af;">ScheduleTestCases</span>))] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">Schedule</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">MaitreD</span>&nbsp;<span style="color:#1f377f;">sut</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">Table</span>[]&gt;&gt;&nbsp;<span style="color:#1f377f;">expected</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;<span style="color:#1f377f;">sut</span>.<span style="color:#74531f;">Schedule</span>(<span style="color:#1f377f;">reservations</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">expected</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">o</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">ts</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">ts</span>.<span style="color:#74531f;">AsEnumerable</span>())), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>); }</pre> </p> <p> This is almost as simple as it can be: Call the method and verify that <code>expected</code> is equal to <code>actual</code>. The only slightly complicated piece is the nested projection of <code>expected</code> from <code>IEnumerable&lt;Occurrence&lt;Table[]&gt;&gt;</code> to <code>IEnumerable&lt;Occurrence&lt;IEnumerable&lt;Table&gt;&gt;&gt;</code>. There are ugly reasons for this that I don't want to discuss here, since they have no bearing on the actual topic, which is coming up with tests. </p> <p> I also added the <code>ScheduleTestCases</code> class and a single test case: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ScheduleTestCases</span>&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TheoryData</span>&lt;<span style="color:#2b91af;">MaitreD</span>,&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;,&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">Table</span>[]&gt;&gt;&gt; { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ScheduleTestCases</span>() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;No&nbsp;reservations,&nbsp;so&nbsp;no&nbsp;occurrences:</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#74531f;">Add</span>(<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">MaitreD</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(18), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(21), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(6), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Communal</span>(12)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Array</span>.<span style="color:#74531f;">Empty</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Array</span>.<span style="color:#74531f;">Empty</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">Table</span>[]&gt;&gt;()); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> The simplest implementation that passed that test was this: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">break</span>; }</pre> </p> <p> Okay, hardly rocket science, but this was just a test case to get started. So I added another one: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">SingleReservationCommunalTable</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">table</span>&nbsp;=&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Communal</span>(12); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:#2b91af;">Some</span>.Reservation; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#74531f;">Add</span>(<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">MaitreD</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(18), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(21), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(6), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">table</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#1f377f;">r</span>&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#1f377f;">table</span>.<span style="color:#74531f;">Reserve</span>(<span style="color:#1f377f;">r</span>)&nbsp;}.<span style="color:#74531f;">At</span>(<span style="color:#1f377f;">r</span>.At)&nbsp;}); }</pre> </p> <p> This test case adds a single reservation to a restaurant with a single communal table. The <code>expected</code> result is now a single occurrence with that reservation. In true TDD fashion, this new test case caused a test failure, and I now had to adjust the <code>Schedule</code> method to pass all tests: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">if</span>&nbsp;(<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Any</span>()) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">r</span>&nbsp;=&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">First</span>(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Communal</span>(12).<span style="color:#74531f;">Reserve</span>(<span style="color:#1f377f;">r</span>)&nbsp;}.<span style="color:#74531f;">AsEnumerable</span>().<span style="color:#74531f;">At</span>(<span style="color:#1f377f;">r</span>.At); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">yield</span>&nbsp;<span style="color:#8f08c4;">break</span>; }</pre> </p> <p> You might have wanted to jump to something prettier right away, but I wanted to proceed according to the Devil's advocate technique. I was concerned that I was going to mess up the implementation if I moved too fast. </p> <p> And that was when I basically hit a wall. </p> <h3 id="c8fd655d50414215b04f891676a09bd8"> Property-based testing to the rescue <a href="#c8fd655d50414215b04f891676a09bd8" title="permalink">#</a> </h3> <p> I couldn't figure out how to proceed from there. Which test case ought to be the next? I wanted to follow the spirit of the TPP and pick a test case that would cause another incremental step in the right direction. The sheer number of possible combinations overwhelmed me, though. Should I adjust the reservations? The table configuration for the <code>MaitreD</code> class? The <code>SeatingDuration</code>? </p> <p> It's possible that you'd be able to conjure up the perfect next test case, but I couldn't. I actually let it stew for a couple of days before I decided to give up on the example-driven approach. While I couldn't see a clear path forward with concrete examples, I had a vivid vision of how to proceed with <a href="/property-based-testing-intro">property-based testing</a>. </p> <p> I left the above tests in place and instead added a new test class to my code base. Its only purpose: to test the <code>Schedule</code> method. The test method itself is only a composition of various data definitions and the actual test code: </p> <p> <pre>[<span style="color:#2b91af;">Property</span>] <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Property</span>&nbsp;<span style="color:#74531f;">Schedule</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#2b91af;">Prop</span>.<span style="color:#74531f;">ForAll</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GenReservation.<span style="color:#74531f;">ArrayOf</span>().<span style="color:#74531f;">ToArbitrary</span>(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#74531f;">ScheduleImp</span>); }</pre> </p> <p> This uses <a href="https://fscheck.github.io/FsCheck">FsCheck</a> 2.14.3, which is written in <a href="https://fsharp.org">F#</a> and composes better if you also write the tests in F#. In order to make things a little more palatable for C# developers, I decided to implement the building blocks for the property using methods and class properties. </p> <p> The <code>ScheduleImp</code> method, for example, actually implements the test. This method runs a hundred times (FsCheck's default value) with randomly generated input values: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ScheduleImp</span>(<span style="color:#2b91af;">Reservation</span>[]&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Create&nbsp;a&nbsp;table&nbsp;for&nbsp;each&nbsp;reservation,&nbsp;to&nbsp;ensure&nbsp;that&nbsp;all</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;reservations&nbsp;can&nbsp;be&nbsp;allotted&nbsp;a&nbsp;table.</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">tables</span>&nbsp;=&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Standard</span>(<span style="color:#1f377f;">r</span>.Quantity)); &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;<span style="color:#2b91af;">MaitreD</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(18), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(21), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(6), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">tables</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;<span style="color:#1f377f;">sut</span>.<span style="color:#74531f;">Schedule</span>(<span style="color:#1f377f;">reservations</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">r</span>.At).<span style="color:#74531f;">Distinct</span>().<span style="color:#74531f;">Count</span>(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Count</span>()); }</pre> </p> <p> The step you see in the first line of code is an example of a trick that I find myself doing often with property-based testing: instead of trying to find some good test values for a particular set of circumstances, I create a set of circumstances that fits the randomly generated test values. As the code comment explains, given a set of <code>Reservation</code> values, it creates a table that fits each reservation. In that way I ensure that all the reservations can be allocated a table. </p> <p> I'll soon return to how those random <code>Reservation</code> values are generated, but first let's discuss the rest of the test body. Given a valid <code>MaitreD</code> object it calls the <code>Schedule</code> method. In the <a href="/2013/06/24/a-heuristic-for-formatting-code-according-to-the-aaa-pattern">assertion phase</a>, it so far only verifies that there's as many time entries in <code>actual</code> as there are distinct <code>At</code> values in <code>reservations</code>. </p> <p> That's hardly a comprehensive description of the SUT, but it's a start. The following implementation passes both the new property, as well as the two examples above. </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;r&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#1f377f;">reservations</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">group</span>&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Communal</span>(12).<span style="color:#74531f;">Reserve</span>(r)&nbsp;<span style="color:blue;">by</span>&nbsp;r.At&nbsp;<span style="color:blue;">into</span>&nbsp;g &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;g.<span style="color:#74531f;">AsEnumerable</span>().<span style="color:#74531f;">At</span>(g.Key); }</pre> </p> <p> I know that many C# programmers don't like query syntax, but I've always had a soft spot for it. I liked it, but wasn't sure that I'd be able to keep it up as I added more constraints to the property. </p> <h3 id="5670f47a815542bfac848645e9a3ccf4"> Generators <a href="#5670f47a815542bfac848645e9a3ccf4" title="permalink">#</a> </h3> <p> Before we get to that, though, I promised to show you how the random <code>reservations</code> are generated. FsCheck has an API for that, and it's also query-syntax-friendly: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">Email</span>&gt;&nbsp;GenEmail&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Arb</span>.<span style="color:#2b91af;">Default</span>.<span style="color:#74531f;">NonWhiteSpaceString</span>().Generator &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">Email</span>(s.Item); <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">Name</span>&gt;&nbsp;GenName&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;s&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Arb</span>.<span style="color:#2b91af;">Default</span>.<span style="color:#74531f;">StringWithoutNullChars</span>().Generator &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">Name</span>(s.Item); <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;GenReservation&nbsp;=&gt; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;id&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Arb</span>.<span style="color:#2b91af;">Default</span>.<span style="color:#74531f;">Guid</span>().Generator &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;d&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Arb</span>.<span style="color:#2b91af;">Default</span>.<span style="color:#74531f;">DateTime</span>().Generator &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;e&nbsp;<span style="color:blue;">in</span>&nbsp;GenEmail &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;n&nbsp;<span style="color:blue;">in</span>&nbsp;GenName &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;q&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Arb</span>.<span style="color:#2b91af;">Default</span>.<span style="color:#74531f;">PositiveInt</span>().Generator &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">Reservation</span>(id,&nbsp;d,&nbsp;e,&nbsp;n,&nbsp;q.Item);</pre> </p> <p> <code>GenReservation</code> is a generator of <code>Reservation</code> values (for a simplified explanation of how such a generator might work, see <a href="/2017/09/18/the-test-data-generator-functor">The Test Data Generator functor</a>). It's composed from smaller generators, among these <code>GenEmail</code> and <code>GenName</code>. The rest of the generators are general-purpose generators defined by FsCheck. </p> <p> If you refer back to the <code>Schedule</code> property above, you'll see that it uses <code>GenReservation</code> to produce an array generator. This is another general-purpose combinator provided by FsCheck. It turns any single-object generator into a generator of arrays containing such objects. Some of these arrays will be empty, which is often desirable, because it means that you'll automatically get coverage of that edge case. </p> <h3 id="ad13aac51d654a7f988b1106579f42fd"> Iterative development <a href="#ad13aac51d654a7f988b1106579f42fd" title="permalink">#</a> </h3> <p> As I already <a href="/2015/01/10/diamond-kata-with-fscheck">discovered in 2015</a> some problems are just much better suited for property-based development than example-driven development. As I expected, this one turned out to be just such a problem. (Recently, <a href="https://www.hillelwayne.com">Hillel Wayne</a> identified a set of problems with no clear properties as <a href="https://buttondown.email/hillelwayne/archive/cross-branch-testing/">rho problems</a>. I wonder if we should pick another Greek letter for this type of problems that almost ooze properties. Sigma problems? Maybe we should just call them <em>describable problems</em>...) </p> <p> For the next step, I didn't have to write a completely new property. I only had to add a new assertion, and thereby strengthening the postconditions of the <code>Schedule</code> method: </p> <p> <pre><span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">o</span>.At).<span style="color:#74531f;">OrderBy</span>(<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">d</span>), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">o</span>.At));</pre> </p> <p> I added the above assertion to <code>ScheduleImp</code> after the previous assertion. It simply states that <code>actual</code> should be sorted in ascending order. </p> <p> To pass this new requirement I added an ordering clause to the implementation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;r&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#1f377f;">reservations</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">group</span>&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Communal</span>(12).<span style="color:#74531f;">Reserve</span>(r)&nbsp;<span style="color:blue;">by</span>&nbsp;r.At&nbsp;<span style="color:blue;">into</span>&nbsp;g &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">orderby</span>&nbsp;g.Key &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;g.<span style="color:#74531f;">AsEnumerable</span>().<span style="color:#74531f;">At</span>(g.Key); }</pre> </p> <p> It passes all tests. Commit to Git. Next. </p> <h3 id="040edba86dfd4bfe8a57cef15b4a9ff6"> Table configuration <a href="#040edba86dfd4bfe8a57cef15b4a9ff6" title="permalink">#</a> </h3> <p> If you consider the current implementation, there's much not to like. The worst offence, I think, is that it conjures a hard-coded communal table out of thin air. The method ought to use the table configuration passed to the <code>MaitreD</code> object. This seems like an obvious flaw to address. I therefore added this to the property: </p> <p> <pre>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">All</span>(<span style="color:#1f377f;">actual</span>,&nbsp;<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">AssertTables</span>(<span style="color:#1f377f;">tables</span>,&nbsp;<span style="color:#1f377f;">o</span>.Value)); } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">AssertTables</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&nbsp;<span style="color:#1f377f;">expected</span>, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&nbsp;<span style="color:#1f377f;">actual</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>(<span style="color:#1f377f;">expected</span>.<span style="color:#74531f;">Count</span>(),&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Count</span>()); }</pre> </p> <p> It's just another assertion that uses the helper assertion also shown. As a first pass, it's not enough to cheat the Devil, but it sets me up for my next move. The plan is to assert that no tables are generated out of thin air. Currently, <code>AssertTables</code> only verifies that the actual count of tables in each occurrence matches the expected count. </p> <p> The Devil easily foils that plan by generating a table for each reservation: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">tables</span>&nbsp;=&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Communal</span>(12).<span style="color:#74531f;">Reserve</span>(<span style="color:#1f377f;">r</span>)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;r&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#1f377f;">reservations</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">group</span>&nbsp;r&nbsp;<span style="color:blue;">by</span>&nbsp;r.At&nbsp;<span style="color:blue;">into</span>&nbsp;g &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">orderby</span>&nbsp;g.Key &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:#1f377f;">tables</span>.<span style="color:#74531f;">At</span>(g.Key); }</pre> </p> <p> This (unfortunately) passes all tests, so commit to Git and move on. </p> <p> The next move I made was to add an assertion to <code>AssertTables</code>: </p> <p> <pre><span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">expected</span>.<span style="color:#74531f;">Sum</span>(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">t</span>.Capacity), &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Sum</span>(<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">t</span>.Capacity));</pre> </p> <p> This new requirement states that the total capacity of the actual tables should be equal to the total capacity of the allocated tables. It doesn't prevent the Devil from generating tables out of thin air, but it makes it harder. At least, it makes it so hard that I found it more reasonable to use the supplied table configuration: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">tables</span>&nbsp;=&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Zip</span>(Tables,&nbsp;(<span style="color:#1f377f;">r</span>,&nbsp;<span style="color:#1f377f;">t</span>)&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">t</span>.<span style="color:#74531f;">Reserve</span>(<span style="color:#1f377f;">r</span>)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;r&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#1f377f;">reservations</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">group</span>&nbsp;r&nbsp;<span style="color:blue;">by</span>&nbsp;r.At&nbsp;<span style="color:blue;">into</span>&nbsp;g &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">orderby</span>&nbsp;g.Key &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:#1f377f;">tables</span>.<span style="color:#74531f;">At</span>(g.Key); }</pre> </p> <p> The implementation of <code>Schedule</code> still cheats because it 'knows' that no tests (except for the degenerate test where there are no reservations) have surplus tables in the configuration. It takes advantage of that knowledge to zip the two collections, which is really not appropriate. </p> <p> Still, it seems that things are moving in the right direction. </p> <h3 id="5891a00f231f46b68afb0b6aff43b0b0"> Generated SUT <a href="#5891a00f231f46b68afb0b6aff43b0b0" title="permalink">#</a> </h3> <p> Until now, <code>ScheduleImp</code> has been using a hard-coded <code>sut</code>. It's time to change that. </p> <p> To keep my steps as small as possible, I decided to start with the <code>SeatingDuration</code> since it was currently not being used by the implementation. This meant that I could start randomising it without affecting the SUT. Since this was a code change of middling complexity in the test code, I found it most prudent to move in such a way that I didn't have to change the SUT as well. </p> <p> I completely extracted the initialisation of the <code>sut</code> to a method argument of the <code>ScheduleImp</code> method, and adjusted it accordingly: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ScheduleImp</span>(<span style="color:#2b91af;">MaitreD</span>&nbsp;<span style="color:#1f377f;">sut</span>,&nbsp;<span style="color:#2b91af;">Reservation</span>[]&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;<span style="color:#1f377f;">sut</span>.<span style="color:#74531f;">Schedule</span>(<span style="color:#1f377f;">reservations</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">r</span>.At).<span style="color:#74531f;">Distinct</span>().<span style="color:#74531f;">Count</span>(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Count</span>()); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">o</span>.At).<span style="color:#74531f;">OrderBy</span>(<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">d</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">o</span>.At)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">All</span>(<span style="color:#1f377f;">actual</span>,&nbsp;<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">AssertTables</span>(<span style="color:#1f377f;">sut</span>.Tables,&nbsp;<span style="color:#1f377f;">o</span>.Value)); }</pre> </p> <p> This meant that I also had to adjust the calling property: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Property</span>&nbsp;<span style="color:#74531f;">Schedule</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#2b91af;">Prop</span>.<span style="color:#74531f;">ForAll</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GenReservation &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">ArrayOf</span>() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">SelectMany</span>(<span style="color:#1f377f;">rs</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">GenMaitreD</span>(<span style="color:#1f377f;">rs</span>).<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">m</span>&nbsp;=&gt;&nbsp;(<span style="color:#1f377f;">m</span>,&nbsp;<span style="color:#1f377f;">rs</span>))) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">ToArbitrary</span>(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">ScheduleImp</span>(<span style="color:#1f377f;">t</span>.m,&nbsp;<span style="color:#1f377f;">t</span>.rs)); }</pre> </p> <p> You've already seen <code>GenReservation</code>, but <code>GenMaitreD</code> is new: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">MaitreD</span>&gt;&nbsp;<span style="color:#74531f;">GenMaitreD</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Create&nbsp;a&nbsp;table&nbsp;for&nbsp;each&nbsp;reservation,&nbsp;to&nbsp;ensure&nbsp;that&nbsp;all</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;reservations&nbsp;can&nbsp;be&nbsp;allotted&nbsp;a&nbsp;table.</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">tables</span>&nbsp;=&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Standard</span>(<span style="color:#1f377f;">r</span>.Quantity)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;seatingDuration&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Choose</span>(1,&nbsp;6) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">MaitreD</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(18), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(21), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(seatingDuration), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">tables</span>); }</pre> </p> <p> The only difference from before is that the new <code>MaitreD</code> object is now initialised from within a generator expression. The duration is randomly picked from the range of one to six hours (those numbers are my arbitrary choices). </p> <p> Notice that it's possible to base one generator on values randomly generated by another generator. Here, <code>reservations</code> are randomly produced by <code>GenReservation</code> and merged to a tuple with <code>SelectMany</code>, as you can see above. </p> <p> This in itself didn't impact the SUT, but set up the code for my next move, which was to generate <em>more</em> tables than reservations, so that there'd be some free tables left after the schedule allocation. I first added a more complex table generator: </p> <p> <pre><span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;</span><span style="color:gray;">summary</span><span style="color:gray;">&gt;</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;Generate&nbsp;a&nbsp;table&nbsp;configuration&nbsp;that&nbsp;can&nbsp;at&nbsp;minimum&nbsp;accomodate&nbsp;all</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;reservations.</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;/</span><span style="color:gray;">summary</span><span style="color:gray;">&gt;</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;</span><span style="color:gray;">param</span><span style="color:gray;">&nbsp;name</span><span style="color:gray;">=</span><span style="color:gray;">&quot;</span><span style="color:#1f377f;">reservations</span><span style="color:gray;">&quot;</span><span style="color:gray;">&gt;</span><span style="color:green;">The&nbsp;reservations&nbsp;to&nbsp;accommodate</span><span style="color:gray;">&lt;/</span><span style="color:gray;">param</span><span style="color:gray;">&gt;</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;</span><span style="color:gray;">returns</span><span style="color:gray;">&gt;</span><span style="color:green;">A&nbsp;generator&nbsp;of&nbsp;valid&nbsp;table&nbsp;configurations.</span><span style="color:gray;">&lt;/</span><span style="color:gray;">returns</span><span style="color:gray;">&gt;</span> <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&nbsp;<span style="color:#74531f;">GenTables</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Create&nbsp;a&nbsp;table&nbsp;for&nbsp;each&nbsp;reservation,&nbsp;to&nbsp;ensure&nbsp;that&nbsp;all</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;reservations&nbsp;can&nbsp;be&nbsp;allotted&nbsp;a&nbsp;table.</span> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">tables</span>&nbsp;=&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Standard</span>(<span style="color:#1f377f;">r</span>.Quantity)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;moreTables&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Choose</span>(1,&nbsp;12).<span style="color:#74531f;">Select</span>(<span style="color:#2b91af;">Table</span>.<span style="color:#74531f;">Standard</span>).<span style="color:#74531f;">ArrayOf</span>() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;allTables&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Shuffle</span>(<span style="color:#1f377f;">tables</span>.<span style="color:#74531f;">Concat</span>(moreTables)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;allTables.<span style="color:#74531f;">AsEnumerable</span>(); }</pre> </p> <p> This function first creates standard tables that exactly accommodate each reservation. It then generates an array of <code>moreTables</code>, each fitting between one and twelve people. It then mixes those tables together with the ones that fit a reservation and returns the sequence. Since <code>moreTables</code> can be empty, it's possible that the entire sequence of tables only just accommodates the <code>reservations</code>. </p> <p> I then modified <code>GenMaitreD</code> to use <code>GenTables</code>: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">MaitreD</span>&gt;&nbsp;<span style="color:#74531f;">GenMaitreD</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;seatingDuration&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Choose</span>(1,&nbsp;6) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;tables&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#74531f;">GenTables</span>(<span style="color:#1f377f;">reservations</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">MaitreD</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(18), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(21), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromHours</span>(seatingDuration), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tables); }</pre> </p> <p> This provoked a change in the SUT: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;r&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#1f377f;">reservations</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">group</span>&nbsp;r&nbsp;<span style="color:blue;">by</span>&nbsp;r.At&nbsp;<span style="color:blue;">into</span>&nbsp;g &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">orderby</span>&nbsp;g.Key &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:#74531f;">Allocate</span>(g).<span style="color:#74531f;">At</span>(g.Key); }</pre> </p> <p> The <code>Schedule</code> method now calls a private helper method called <code>Allocate</code>. This method already existed, since it supports the algorithm used to decide whether or not to accept a reservation request. </p> <h3 id="79e43322721b45a390c68caeaa1a3dcf"> Rinse and repeat <a href="#79e43322721b45a390c68caeaa1a3dcf" title="permalink">#</a> </h3> <p> I hope that a pattern starts to emerge. I kept adding more and more randomisation to the data generators, while I also added more and more assertions to the property. Here's what it looked like after a few more iterations: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:blue;">void</span>&nbsp;<span style="color:#74531f;">ScheduleImp</span>(<span style="color:#2b91af;">MaitreD</span>&nbsp;<span style="color:#1f377f;">sut</span>,&nbsp;<span style="color:#2b91af;">Reservation</span>[]&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">actual</span>&nbsp;=&nbsp;<span style="color:#1f377f;">sut</span>.<span style="color:#74531f;">Schedule</span>(<span style="color:#1f377f;">reservations</span>); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">r</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">r</span>.At).<span style="color:#74531f;">Distinct</span>().<span style="color:#74531f;">Count</span>(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Count</span>()); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">Equal</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">o</span>.At).<span style="color:#74531f;">OrderBy</span>(<span style="color:#1f377f;">d</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">d</span>), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>.<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">o</span>.At)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">All</span>(<span style="color:#1f377f;">actual</span>,&nbsp;<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">AssertTables</span>(<span style="color:#1f377f;">sut</span>.Tables,&nbsp;<span style="color:#1f377f;">o</span>.Value)); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.<span style="color:#74531f;">All</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">actual</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">o</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">AssertRelevance</span>(<span style="color:#1f377f;">reservations</span>,&nbsp;<span style="color:#1f377f;">sut</span>.SeatingDuration,&nbsp;<span style="color:#1f377f;">o</span>)); }</pre> </p> <p> While <code>AssertTables</code> didn't change further, I added another helper assertion called <code>AssertRelevance</code>. I'm not going to show it here, but it checks that each occurrence only contains reservations that overlaps that point in time, give or take the <code>SeatingDuration</code>. </p> <p> I also made the reservation generator more sophisticated. If you consider the one defined above, one flaw is that it generates reservations at random dates. The chance that it'll generate two reservations that are actually adjacent in time is minimal. To counter this problem, I added a function that would return a generator of adjacent reservations: </p> <p> <pre><span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;</span><span style="color:gray;">summary</span><span style="color:gray;">&gt;</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;Generate&nbsp;an&nbsp;adjacant&nbsp;reservation&nbsp;with&nbsp;a&nbsp;25%&nbsp;chance.</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;/</span><span style="color:gray;">summary</span><span style="color:gray;">&gt;</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;</span><span style="color:gray;">param</span><span style="color:gray;">&nbsp;name</span><span style="color:gray;">=</span><span style="color:gray;">&quot;</span><span style="color:#1f377f;">reservation</span><span style="color:gray;">&quot;</span><span style="color:gray;">&gt;</span><span style="color:green;">The&nbsp;candidate&nbsp;reservation</span><span style="color:gray;">&lt;/</span><span style="color:gray;">param</span><span style="color:gray;">&gt;</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;</span><span style="color:gray;">returns</span><span style="color:gray;">&gt;</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;A&nbsp;generator&nbsp;of&nbsp;an&nbsp;array&nbsp;of&nbsp;reservations.&nbsp;The&nbsp;generated&nbsp;array&nbsp;is</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;either&nbsp;a&nbsp;singleton&nbsp;or&nbsp;a&nbsp;pair.&nbsp;In&nbsp;75%&nbsp;of&nbsp;the&nbsp;cases,&nbsp;the&nbsp;input</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;</span><span style="color:gray;">paramref</span><span style="color:gray;">&nbsp;name</span><span style="color:gray;">=</span><span style="color:gray;">&quot;</span><span style="color:#1f377f;">reservation</span><span style="color:gray;">&quot;</span><span style="color:gray;">&nbsp;/&gt;</span><span style="color:green;">&nbsp;is&nbsp;returned&nbsp;as&nbsp;a&nbsp;singleton&nbsp;array.</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;In&nbsp;25%&nbsp;of&nbsp;the&nbsp;cases,&nbsp;the&nbsp;array&nbsp;contains&nbsp;two&nbsp;reservations:&nbsp;the&nbsp;input</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;reservation&nbsp;as&nbsp;well&nbsp;as&nbsp;another&nbsp;reservation&nbsp;adjacent&nbsp;to&nbsp;it.</span> <span style="color:gray;">///</span><span style="color:green;">&nbsp;</span><span style="color:gray;">&lt;/</span><span style="color:gray;">returns</span><span style="color:gray;">&gt;</span> <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">Reservation</span>[]&gt;&nbsp;<span style="color:#74531f;">GenAdjacentReservations</span>(<span style="color:#2b91af;">Reservation</span>&nbsp;<span style="color:#1f377f;">reservation</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;adjacent&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#74531f;">GenReservationAdjacentTo</span>(<span style="color:#1f377f;">reservation</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;useAdjacent&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Frequency</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">WeightAndValue</span>&lt;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:blue;">bool</span>&gt;&gt;(3,&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Constant</span>(<span style="color:blue;">false</span>)), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">WeightAndValue</span>&lt;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:blue;">bool</span>&gt;&gt;(1,&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Constant</span>(<span style="color:blue;">true</span>))) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;rs&nbsp;=&nbsp;useAdjacent&nbsp;? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#1f377f;">reservation</span>,&nbsp;adjacent&nbsp;}&nbsp;: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">new</span>[]&nbsp;{&nbsp;<span style="color:#1f377f;">reservation</span>&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;rs; } <span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#74531f;">GenReservationAdjacentTo</span>(<span style="color:#2b91af;">Reservation</span>&nbsp;<span style="color:#1f377f;">reservation</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;minutes&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Choose</span>(-6&nbsp;*&nbsp;4,&nbsp;6&nbsp;*&nbsp;4)&nbsp;<span style="color:green;">//&nbsp;4:&nbsp;quarters/h</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;r&nbsp;<span style="color:blue;">in</span>&nbsp;GenReservation &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;r.<span style="color:#74531f;">WithDate</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">reservation</span>.At&nbsp;<span style="color:#74531f;">+</span>&nbsp;<span style="color:#2b91af;">TimeSpan</span>.<span style="color:#74531f;">FromMinutes</span>(minutes)); }</pre> </p> <p> Now that I look at it again, I wonder whether I could have expressed this in a simpler way... It gets the job done, though. </p> <p> I then defined a generator that would either create entirely random reservations, or some with some adjacent ones mixed in: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">Gen</span>&lt;<span style="color:#2b91af;">Reservation</span>[]&gt;&nbsp;GenReservations { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">get</span> &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">normalArrayGen</span>&nbsp;=&nbsp;GenReservation.<span style="color:#74531f;">ArrayOf</span>(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;<span style="color:#1f377f;">adjacentReservationsGen</span>&nbsp;=&nbsp;GenReservation.<span style="color:#74531f;">ArrayOf</span>() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">SelectMany</span>(<span style="color:#1f377f;">rs</span>&nbsp;=&gt;&nbsp;<span style="color:#2b91af;">Gen</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">Sequence</span>(<span style="color:#1f377f;">rs</span>.<span style="color:#74531f;">Select</span>(<span style="color:#74531f;">GenAdjacentReservations</span>)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">SelectMany</span>(<span style="color:#1f377f;">rss</span>&nbsp;=&gt;&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">Shuffle</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">rss</span>.<span style="color:#74531f;">SelectMany</span>(<span style="color:#1f377f;">rs</span>&nbsp;=&gt;&nbsp;<span style="color:#1f377f;">rs</span>)))); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#2b91af;">Gen</span>.<span style="color:#74531f;">OneOf</span>(<span style="color:#1f377f;">normalArrayGen</span>,&nbsp;<span style="color:#1f377f;">adjacentReservationsGen</span>); &nbsp;&nbsp;&nbsp;&nbsp;} }</pre> </p> <p> I changed the property to use this generator instead: </p> <p> <pre>[<span style="color:#2b91af;">Property</span>] <span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">Property</span>&nbsp;<span style="color:#74531f;">Schedule</span>() { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span>&nbsp;<span style="color:#2b91af;">Prop</span>.<span style="color:#74531f;">ForAll</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GenReservations &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">SelectMany</span>(<span style="color:#1f377f;">rs</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">GenMaitreD</span>(<span style="color:#1f377f;">rs</span>).<span style="color:#74531f;">Select</span>(<span style="color:#1f377f;">m</span>&nbsp;=&gt;&nbsp;(<span style="color:#1f377f;">m</span>,&nbsp;<span style="color:#1f377f;">rs</span>))) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.<span style="color:#74531f;">ToArbitrary</span>(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#1f377f;">t</span>&nbsp;=&gt;&nbsp;<span style="color:#74531f;">ScheduleImp</span>(<span style="color:#1f377f;">t</span>.m,&nbsp;<span style="color:#1f377f;">t</span>.rs)); }</pre> </p> <p> I could have kept at it longer, but this turned out to be good enough to bring about the change in the SUT that I was looking for. </p> <h3 id="f34220b7400d464c9fce7c2b65454971"> Implementation <a href="#f34220b7400d464c9fce7c2b65454971" title="permalink">#</a> </h3> <p> These incremental changes iteratively brought me closer and closer to an implementation that I think has the correct behaviour: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Occurrence</span>&lt;<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Table</span>&gt;&gt;&gt;&nbsp;<span style="color:#74531f;">Schedule</span>(<span style="color:#2b91af;">IEnumerable</span>&lt;<span style="color:#2b91af;">Reservation</span>&gt;&nbsp;<span style="color:#1f377f;">reservations</span>) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#8f08c4;">return</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">from</span>&nbsp;r&nbsp;<span style="color:blue;">in</span>&nbsp;<span style="color:#1f377f;">reservations</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">group</span>&nbsp;r&nbsp;<span style="color:blue;">by</span>&nbsp;r.At&nbsp;<span style="color:blue;">into</span>&nbsp;g &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">orderby</span>&nbsp;g.Key &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;seating&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">Seating</span>(SeatingDuration,&nbsp;g.Key) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">let</span>&nbsp;overlapping&nbsp;=&nbsp;<span style="color:#1f377f;">reservations</span>.<span style="color:#74531f;">Where</span>(seating.<span style="color:#74531f;">Overlaps</span>) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">select</span>&nbsp;<span style="color:#74531f;">Allocate</span>(overlapping).<span style="color:#74531f;">At</span>(g.Key); }</pre> </p> <p> Contrary to my initial expectations, I managed to keep the implementation to a single query expression all the way through. </p> <h3 id="c64408017700494a808fae9388341e87"> Conclusion <a href="#c64408017700494a808fae9388341e87" title="permalink">#</a> </h3> <p> This was a problem that I was stuck on for a couple of days. I could describe the properties I wanted the function to have, but I had a hard time coming up with a good set of examples for unit tests. </p> <p> You may think that using property-based testing looks even more complicated, and I admit that it's far from trivial. The problem itself, however, isn't easy, and while the property-based approach may look daunting, it turned an intractable problem into a manageable one. That's a win in my book. </p> <p> It's also worth noting that this would all have looked more elegant in F#. There's an object-oriented tax to be paid when using FsCheck from C#. </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>. Accountability and free speech https://blog.ploeh.dk/2021/02/09/accountability-and-free-speech 2021-02-09T07:53:00+00:00 Mark Seemann <div id="post"> <p> <em>A most likely naive suggestion.</em> </p> <p> A few years ago, my mother (born 1940) went to Paris on vacation with her older sister. She was a little concerned if she'd be able to navigate the <a href="https://en.wikipedia.org/wiki/Paris_M%C3%A9tro">Métro</a>, so she asked me to print out all sorts of maps in advance. I wasn't keen on another encounter with my nemesis, the printer, so I instead showed her how she could use Google Maps to get on-demand routes. Google Maps now include timetables and line information for many metropolitan subway lines around the world. I've successfully used it to find my way around London, Paris, New York, Tokyo, Sydney, and Melbourne. </p> <p> It even works in my backwater home-town: </p> <p> <img src="/content/binary/cph-metro-map.png" alt="Snapshot of Copenhagen Metro route generated by Google Maps."> </p> <p> It's rapidly turning into indispensable digital infrastructure, and that's beginning to trouble me. </p> <p> You can still get paper maps of the various rapid transit systems around the world, but for how long? </p> <h3 id="e5296cbd33f04db3b79890c09d8e3146"> Digital infrastructure <a href="#e5296cbd33f04db3b79890c09d8e3146" title="permalink">#</a> </h3> <p> If you're old enough, you may remember <a href="https://en.wikipedia.org/wiki/Telephone_directory">phone books</a>. In the days of land lines and analogue phones, you'd look up a number and then dial it. As the internet became increasingly ubiquitous, phone directories went online as well. Paper phone books were seen as waste, and ultimately disappeared from everyday life. </p> <p> You can think of paper phone books as a piece of infrastructure that's now gone. I don't miss them, but it's worth reflecting on what impact their disappearing has. Today, if I need to find a phone number, Google is often the place I go. The physical infrastructure is gone, replaced by a digital infrastructure. </p> <p> Google, in particular, now provides important infrastructure for modern society. Not only web search, but also maps, video sharing, translation, emails, and much more. </p> <p> Other companies offer other services that verge on being infrastructure. Facebook is more than just updates to friends and families. Many organisations, including schools and universities, coordinate activities via Facebook, and the political discourse increasingly happens there and on Twitter. </p> <p> We've come to rely on these 'free' services to a degree that resembles our reliance on physical infrastructure like the power grid, running water, roads, telephones, etcetera. </p> <h3 id="bf364e0f0ca84fbbb0536b462743993b"> TANSTAAFL <a href="#bf364e0f0ca84fbbb0536b462743993b" title="permalink">#</a> </h3> <p> <a href="https://en.wikipedia.org/wiki/Robert_A._Heinlein">Robert A. Heinlein</a> coined the phrase <em>There ain't no such thing as a free lunch</em> (TANSTAAFL) in his excellent book <a href="https://amzn.to/3pWi7aM">The Moon is a Harsh Mistress</a>. Indeed, the digital infrastructure isn't free. </p> <p> Recent events have magnified some of the cost we're paying. In January, Facebook and Twitter suspended the then-president of the United States from the platforms. I've little sympathy for Donald Trump, who strikes me as an uncouth narcissist, but since I'm a Danish citizen living in Denmark, I don't think that I ought to have much of an opinion about American politics. </p> <p> I do think, on the other hand, that the suspension sets an uncomfortable precedent. </p> <p> Should we let a handful of tech billionaires control essential infrastructure? This time, the victim was someone half the world was glad to see go, but who's next? Might these companies suspend the accounts of politicians who work against them? </p> <p> Never in the history of the world has decision power over so many people been so concentrated. I'll remind my readers that Facebook, Twitter, Google, etcetera are in worldwide use. The decisions of a handful of majority shareholders can now affect billions of people. </p> <p> If you're suspended from one of these platforms, you may lose your ability to participate in school activities, or from finding your way through a foreign city, or from taking part of the democratic discussion. </p> <h3 id="23e71b25789c465e9530a51a1cceac21"> The case for regulation <a href="#23e71b25789c465e9530a51a1cceac21" title="permalink">#</a> </h3> <p> In this article, I mainly want to focus on the free-speech issue related mostly to Facebook and Twitter. These companies make money from ads. The longer you stay on the platform, the more ads they can show you, and they've discovered that nothing pulls you in like anger. These incentives are incredibly counter-productive for society. </p> <p> Users are implicitly encouraged to create or spread anger, yet few are held accountable. One reason is that you can easily create new accounts without disclosing your real-world identity. This makes it difficult to hold users accountable for their utterances. </p> <p> Instead of clear rules, users are suspended for inexplicable and arbitrary reasons. It seems that these are mostly the verdicts of algorithms, but as we've seen in the case of Donald Trump, it can also be the result of an undemocratic, but political decision. </p> <p> Everyone can lose their opportunities for self-expression for arbitrary reasons. This is a free-speech issue. </p> <p> Yes, free speech. </p> <p> I'm well aware that Facebook and Twitter are private companies, and no-one has any <em>right</em> to an account on those platforms. That's why I started this essay by discussing how these services are turning into infrastructure. </p> <p> More than a century ago, the telephone was new technology operated by private companies. I know the Danish history best, but it serves well as an example. <a href="https://da.wikipedia.org/wiki/KTAS">KTAS</a>, one of the world's first telephone companies, was a private company. Via mergers and acquisitions, it still is, but as it grew and became the backbone of the country's electronic communications network, the government introduced legislation. For decades, it and its sister companies were regional monopolies. </p> <p> The government allowed the monopoly in exchange for various obligations. Even when the monopoly ended in 1996, the original monopoly companies inherited these legal obligations. For instance, every Danish citizen has the right to get a land-line installed, even if that installation by itself is a commercial loss for the company. This could be the case on certain remote islands or other rural areas. The Danish state compensates the telephone operator for this potential loss. </p> <p> Many other utility companies run in a similar fashion. Some are semi-public, some are private, but common to water, electricity, garbage disposal, heating, and other operators is that they are regulated by government. </p> <p> When a utility becomes important to the functioning of society, a sensible government steps in to regulate it to ensure the further smooth functioning of society. </p> <p> I think that the services offered by Google, Facebook, and Twitter are fast approaching a level of significance that ought to trigger government regulation. </p> <p> I don't say that lightly. I'm actually quite libertarian in my views, but I'm no anarcho-libertarian. I do acknowledge that a state offers essential services such as protection of property rights, a judicial system, and so on. </p> <h3 id="f4c78c79e1eb46d2941611d443f89ea1"> Accountability <a href="#f4c78c79e1eb46d2941611d443f89ea1" title="permalink">#</a> </h3> <p> How should we regulate social media? I think we should start by exchanging accountability for the right to post. </p> <p> Let's take another step back for a moment. For generations, it's been possible to send a letter to the editor of a regular newspaper. If the editor deems it worthy for publication, it'll be printed in the next issue. You don't have any right to get your letter published; this happens at the discretion of the editor. </p> <p> Why does it work that way? It works that way because the editor is accountable for what's printed in the paper. Ultimately, he or she can go to jail for what's printed. </p> <p> Freedom of speech is more complicated than it looks at first glance. For instance, censorship in Denmark was abolished with the 1849 constitution. This doesn't mean that you can freely say whatever you'd like; it only means that government has no right to <em>prevent</em> you from saying or writing something. You can still be prosecuted after the fact if you say or write something libellous, or if you incite violence, or if you disclose secrets that you've agreed to keep, etcetera. </p> <p> This is accountability. It works when the person making the utterance is known and within reach of the law. </p> <p> Notice, particularly, that an editor-in-chief is accountable for a newspaper's contents. Why isn't Facebook or Twitter accountable for content? </p> <p> These companies have managed to spin a story that they're <em>platforms</em> rather than publishers. This argument might have had some legs ten years ago. When I started using Twitter in 2009, the algorithm was easy to understand: My feed showed the tweets from the accounts that I followed, in the order that they were published. This was easy to understand, and Twitter didn't, as far as I could tell, edit the feed. Since no editing took place, I find the platform argument applicable. </p> <p> Later, the social networks began editing the feeds. No humans were directly involved, but today, some posts are amplified while others get little attention. Since this is done by 'algorithms' rather than editors, the companies have managed to convince lawmakers that they're still only platforms. Let's be real, though. Apparently, the public needs a programmer to say the following, and I'm a programmer. </p> <p> Programmers, employees of those companies, wrote the algorithms. They experimented and tweaked those algorithms to maximise 'engagement'. Humans are continually involved in this process. Editing takes place. </p> <p> I think it's time to stop treating social media networks as platforms, and start treating them as publishers. </p> <h3 id="ab23d2f377db45bf99970479238dd982"> Practicality <a href="#ab23d2f377db45bf99970479238dd982" title="permalink">#</a> </h3> <p> Facebook and Twitter will protest that it's practically impossible for them to 'edit' what happens on the networks. I find this argument unconvincing, since editing already takes place. </p> <p> I'd like to suggest a partial way out, though. This brings us back to regulation. </p> <p> I think that each country or jurisdiction should make it possible for users to opt in to being accountable. Users should be able to verify their accounts as real, legal persons. If they do that, their activity on the platform should be governed by the jurisdiction in which they reside, instead of by the arbitrary and ill-defined 'community guidelines' offered by the networks. You'd be accountable for your utterances according to local law where you live. The advantage, though, is that this accountability buys you the <em>right</em> to be present on the platform. You can be sued for your posts, but you can't be kicked off. </p> <p> I'm aware that not everyone lives in a benign welfare state such as Denmark. This is why I suggest this as an option. Even if you live in a state that regulates social media as outlined above, the option to stay anonymous should remain. This is how it already works, and I imagine that it should continue to work like that for this group of users. The cost of staying anonymous, though, is that you submit to the arbitrary and despotic rules of those networks. For many people, including minorities and citizens of oppressive states, this is likely to remain a better trade-off. </p> <h3 id="84eccfad9fe649c3b38d9e4d6ddb2698"> Problems <a href="#84eccfad9fe649c3b38d9e4d6ddb2698" title="permalink">#</a> </h3> <p> This suggestion is in no way perfect. I can already identify one problem with it. </p> <p> A country could grant its citizens the right to conduct infowar on an adversary; think troll armies and the like. If these citizens are verified and 'accountable' to their local government, but this government encourages rather than punishes incitement to violence in a foreign country, then how do we prevent that? </p> <p> I have a few half-baked ideas, but I'd rather leave the problem here in the hope that it might inspire other people to start thinking about it, too. </p> <h3 id="f25f8486eed54d3d89fd607ef41e3ac7"> Conclusion <a href="#f25f8486eed54d3d89fd607ef41e3ac7" title="permalink">#</a> </h3> <p> This is a post that I've waited for a long time for someone else to write. If someone already did, I'm not aware of it. I can think of three reasons: <ul> <li>It's a really stupid idea.</li> <li>It's a common idea, but no-one talks about it because of <a href="https://en.wikipedia.org/wiki/Pluralistic_ignorance">pluralistic ignorance</a>.</li> <li>It's an original idea that no-one else have had.</li> </ul> I don't believe much in the last option, and I'm afraid that the first is the most likely. I've no desire to look stupid, but on the other hand, I can't help keep thinking about this. </p> <p> The idea is, in short, to make it optional for users to 'buy' the right to stay on a social network for the price of being held legally accountable. This requires some national as well as international regulation of the digital infrastructure. </p> <p> Could it work? I don't know, but isn't it worth discussing? </p> </div> <div id="comments"> <hr> <h2 id="comments-header"> Comments </h2> <div class="comment" id="c9bf9249f05342dcae02d9581b7e7e5c"> <div class="comment-author"><a href="https://jeremiahflaga.github.io/">Jboy Flaga</a></div> <div class="comment-content"> <p> Hi Mark, I would just like to say that I like the idea :) </p> <p> Thank you for writing this. </p> </div> <div class="comment-date">2021-02-18 13:34 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>. ASP.NET POCO Controllers: an experience report https://blog.ploeh.dk/2021/02/01/aspnet-poco-controllers-an-experience-report 2021-02-01T08:10:00+00:00 Mark Seemann <div id="post"> <p> <em>Controllers don't have to derive from a base class.</em> </p> <p> In most tutorials about ASP.NET web APIs you'll be told to let Controller classes derive from a base class. It may be convenient if you believe that productivity is measured by how fast you can get an initial version of the software into production. Granted, sometimes that's the case, but usually there's a price to be paid. Did you produce legacy code in the process? </p> <p> One <a href="http://bit.ly/working-effectively-with-legacy-code">common definition of legacy code</a> is that it's code without tests. With ASP.NET I've repeatedly found that when Controllers derive from <a href="https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.controllerbase">ControllerBase</a> they become harder to unit test. It may be convenient to have access to the <a href="https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.url#Microsoft_AspNetCore_Mvc_ControllerBase_Url">Url</a> and <a href="https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.user#Microsoft_AspNetCore_Mvc_ControllerBase_User">User</a> properties, but this tends to make the <em>arrange</em> phase of a unit test much more complex. Not impossible; just more complex than I like. In short, inheriting from <code>ControllerBase</code> just to get access to, say, <code>Url</code> or <code>User</code> violates the <a href="https://en.wikipedia.org/wiki/Interface_segregation_principle">Interface Segregation Principle</a>. That <code>ControllerBase</code> is too big a dependency for my taste. </p> <p> I already use <a href="/2021/01/25/self-hosted-integration-tests-in-aspnet">self-hosting in integration tests</a> so that I can interact with my REST APIs via HTTP. When I want to test how my API reacts to various HTTP-specific circumstances, I do that via integration tests. So, in a recent code base I decided to see if I could write an entire REST API in ASP.NET Core without inheriting from <code>ControllerBase</code>. </p> <p> The short answer is that, yes, this is possible, and I'd do it again, but you have to jump through some hoops. I consider that hoop-jumping a fine price to pay for the benefits of simpler unit tests and (it turns out) better separation of concerns. </p> <p> In this article, I'll share what I've learned. <ins datetime="2021-06-15T06:14Z">The code shown here is part of the sample code base that accompanies my book <a href="/code-that-fits-in-your-head">Code That Fits in Your Head</a>.</ins> </p> <h3 id="fa68860febe6482287eadc65cf3e8a46"> POCO Controllers <a href="#fa68860febe6482287eadc65cf3e8a46" title="permalink">#</a> </h3> <p> Just so that we're on the same page: A <a href="https://en.wikipedia.org/wiki/Plain_old_CLR_object">POCO</a> Controller is a Controller class that doesn't inherit from any base class. In my code base, they're defined like this: </p> <p> <pre>[<span style="color:#2b91af;">Route</span>(<span style="color:#a31515;">&quot;&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">HomeController</span></pre> </p> <p> or </p> <p> <pre>[<span style="color:#2b91af;">Authorize</span>(Roles&nbsp;=&nbsp;<span style="color:#a31515;">&quot;MaitreD&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ScheduleController</span></pre> </p> <p> As you can tell, they don't inherit from <code>ControllerBase</code> or any other base class. They <em>are</em> annotated with attributes, like <code>[Route]</code>, <code>[Authorize]</code>, or <code>[ApiController]</code>. Strictly speaking, that may disqualify them as true POCOs, but in practice I've found that those attributes don't impact the sustainability of the code base in a negative manner. </p> <p> Dependency Injection is still possible, and in use: </p> <p> <pre>[<span style="color:#2b91af;">ApiController</span>] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">ReservationsController</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ReservationsController</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IClock</span>&nbsp;clock, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IRestaurantDatabase</span>&nbsp;restaurantDatabase, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IReservationsRepository</span>&nbsp;repository) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clock&nbsp;=&nbsp;clock; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RestaurantDatabase&nbsp;=&nbsp;restaurantDatabase; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Repository&nbsp;=&nbsp;repository; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IClock</span>&nbsp;Clock&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IRestaurantDatabase</span>&nbsp;RestaurantDatabase&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">IReservationsRepository</span>&nbsp;Repository&nbsp;{&nbsp;<span style="color:blue;">get</span>;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Controller&nbsp;actions&nbsp;and&nbsp;other&nbsp;members&nbsp;go&nbsp;here...</span></pre> </p> <p> I consider Dependency Injection nothing but an application of polymorphism, so I think that still fits the POCO label. After all, <a href="/2017/01/27/dependency-injection-is-passing-an-argument">Dependency Injection is just argument-passing</a>. </p> <h3 id="b1672f04c9774dca9f221a301c191d95"> HTTP responses and status codes <a href="#b1672f04c9774dca9f221a301c191d95" title="permalink">#</a> </h3> <p> The first thing I had to figure out was how to return various HTTP status codes. If you just return some model object, the default status code is <code>200 OK</code>. That's fine in many situations, but if you're implementing a proper REST API, you should be using headers and status codes to communicate with the client. </p> <p> The <code>ControllerBase</code> class defines many helper methods to return various other types of responses, such as <a href="https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.badrequest#Microsoft_AspNetCore_Mvc_ControllerBase_BadRequest">BadRequest</a> or <a href="https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.notfound#Microsoft_AspNetCore_Mvc_ControllerBase_NotFound">NotFound</a>. I had to figure out how to return such responses without access to the base class. </p> <p> Fortunately, ASP.NET Core is now open source, so it isn't too hard to look at the source code for those helper methods to see what they do. It turns out that they are just discoverable methods that create and return various result objects. So, instead of calling the <code>BadRequest</code> helper method, I can just return a <code>BadRequestResult</code>: </p> <p> <pre><span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">BadRequestResult</span>();</pre> </p> <p> Some of the responses were a little more involved, so I created my own domain-specific helper methods for them: </p> <p> <pre><span style="color:blue;">private</span>&nbsp;<span style="color:blue;">static</span>&nbsp;<span style="color:#2b91af;">ActionResult</span>&nbsp;Reservation201Created(<span style="color:blue;">int</span>&nbsp;restaurantId,&nbsp;<span style="color:#2b91af;">Reservation</span>&nbsp;r) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">CreatedAtActionResult</span>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actionName:&nbsp;<span style="color:blue;">nameof</span>(Get), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;controllerName:&nbsp;<span style="color:blue;">null</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;routeValues:&nbsp;<span style="color:blue;">new</span>&nbsp;{&nbsp;restaurantId,&nbsp;id&nbsp;=&nbsp;r.Id.ToString(<span style="color:#a31515;">&quot;N&quot;</span>)&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value:&nbsp;r.ToDto()); }</pre> </p> <p> Apparently, the <code>controllerName</code> argument isn't required, so should be <code>null</code>. I had to experiment with various combinations to get it right, but I have self-hosted integration tests that cover this result. If it doesn't work as intended, tests will fail. </p> <p> Returning this <code>CreatedAtActionResult</code> object produces an HTTP response like this: </p> <p> <pre>HTTP/1.1 201 Created Content-Type: application/json; charset=utf-8 Location: https://example.net:443/restaurants/2112/reservations/276d124f20cf4cc3b502f57b89433f80 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;276d124f20cf4cc3b502f57b89433f80&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2022-01-14T19:45:00.0000000&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;donkeyman@example.org&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Don&nbsp;Keyman&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;4 }</pre> </p> <p> I've edited and coloured the response for readability. The <code>Location</code> URL actually also <a href="/2020/10/26/fit-urls">includes a digital signature</a>, which I've removed here just to make the example look a little prettier. </p> <p> In any case, returning various HTTP headers and status codes is less discoverable when you don't have a base class with all the helper methods, but once you've figured out the objects to return, it's straightforward, and the code is simple. </p> <h3 id="ecbc913d450d49b7ab92d2e0c193230e"> Generating links <a href="#ecbc913d450d49b7ab92d2e0c193230e" title="permalink">#</a> </h3> <p> A true (<a href="https://martinfowler.com/articles/richardsonMaturityModel.html">level 3</a>) REST API uses <a href="https://en.wikipedia.org/wiki/HATEOAS">hypermedia as the engine of application state</a>; that is, <em>links</em>. This means that a HTTP response will typically include a JSON or XML representation with several links. <a href="/2020/10/26/fit-urls">This article</a> includes several examples. </p> <p> ASP.NET provides <a href="https://docs.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.iurlhelper">IUrlHelper</a> for exactly that purpose, and if you inherit from <code>ControllerBase</code> the above-mentioned <code>Url</code> property gives you convenient access to just such an object. </p> <p> When a class <em>doesn't</em> inherit from <code>ControllerBase</code>, you don't have convenient access to an <code>IUrlHelper</code>. Then what? </p> <p> It's possible to get an <code>IUrlHelper</code> via the framework's built-in Dependency Injection engine, but if you add such a dependency to a POCO Controller, you'll have to jump through all sorts of hoops to configure it in unit tests. That was exactly the situation I wanted to avoid, so that got me thinking about design alternatives. </p> <p> That was the real, underlying reason I came up with the idea to instead <a href="/2020/08/24/adding-rest-links-as-a-cross-cutting-concern">add REST links as a cross-cutting concern</a>. The Controllers are wonderfully free of that concern, which helps keeping the complexity down of the unit tests. </p> <p> I still have test coverage of the links, but I prefer testing HTTP-related behaviour via the HTTP API instead of relying on implementation details: </p> <p> <pre>[<span style="color:#2b91af;">Theory</span>] [<span style="color:#2b91af;">InlineData</span>(<span style="color:#a31515;">&quot;Hipgnosta&quot;</span>)] [<span style="color:#2b91af;">InlineData</span>(<span style="color:#a31515;">&quot;Nono&quot;</span>)] [<span style="color:#2b91af;">InlineData</span>(<span style="color:#a31515;">&quot;The&nbsp;Vatican&nbsp;Cellar&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;<span style="color:#2b91af;">Task</span>&nbsp;RestaurantReturnsCorrectLinks(<span style="color:blue;">string</span>&nbsp;name) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">using</span>&nbsp;<span style="color:blue;">var</span>&nbsp;api&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">SelfHostedApi</span>(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;client&nbsp;=&nbsp;api.CreateClient(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;response&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;client.GetRestaurant(name); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;expected&nbsp;=&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">HashSet</span>&lt;<span style="color:blue;">string</span>?&gt;(<span style="color:blue;">new</span>[] &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;urn:reservations&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;urn:year&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;urn:month&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#a31515;">&quot;urn:day&quot;</span> &nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;actual&nbsp;=&nbsp;<span style="color:blue;">await</span>&nbsp;response.ParseJsonContent&lt;<span style="color:#2b91af;">RestaurantDto</span>&gt;(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">var</span>&nbsp;actualRels&nbsp;=&nbsp;actual.Links.Select(l&nbsp;=&gt;&nbsp;l.Rel).ToHashSet(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.Superset(expected,&nbsp;actualRels); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">Assert</span>.All(actual.Links,&nbsp;AssertHrefAbsoluteUrl); }</pre> </p> <p> This test verifies that the representation returned in <code>response</code> contains four labelled links. Granted, this particular test only verifies that each link contains an absolute URL (which could, in theory, be <code>http://www.example.com</code>), but the whole point of <a href="/2020/10/26/fit-urls">fit URLs</a> is that they should be opaque. I've other tests that follow links to verify that the API affords the desired behaviour. </p> <h3 id="cd0769917ec441f786877bba0e630f00"> Authorisation <a href="#cd0769917ec441f786877bba0e630f00" title="permalink">#</a> </h3> <p> The final kind of behaviour that caused me a bit of trouble was authorisation. It's easy enough to annotate a Controller with an <code>[Authorize]</code> attribute, which is fine as long all you need is role-based authorisation. </p> <p> I did, however, run into one situation where I needed something closer to an <a href="https://en.wikipedia.org/wiki/Access-control_list">access control list</a>. The system that includes all these code examples is a multi-tenant restaurant reservation system. There's one protected resource: a day's schedule, intended for use by the restaurant's staff. Here's a simplified example: </p> <p> <pre>GET /restaurants/2112/schedule/2021/2/23 HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInCI6IkpXVCJ9.eyJ... HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Nono&quot;</span>, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;year&quot;</span>:&nbsp;2021, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;month&quot;</span>:&nbsp;2, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;day&quot;</span>:&nbsp;23, &nbsp;&nbsp;<span style="color:#2e75b6;">&quot;days&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;date&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-02-23&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;entries&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;time&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;19:45:00&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;reservations&quot;</span>:&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;id&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2c7ace4bbee94553950afd60a86c530c&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;at&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;2021-02-23T19:45:00.0000000&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;email&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;anarchi@example.net&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;name&quot;</span>:&nbsp;<span style="color:#a31515;">&quot;Ann&nbsp;Archie&quot;</span>, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2e75b6;">&quot;quantity&quot;</span>:&nbsp;2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;] &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;] }</pre> </p> <p> Since this resource contains personally identifiable information (email addresses) it's protected. You have to present a valid <a href="https://en.wikipedia.org/wiki/JSON_Web_Token">JSON Web Token</a> with required claims. Role claims, however, aren't enough. A minimum bar is that the token must contain a sufficient role claim like <code>"MaitreD"</code> shown above, but that's not enough. This is, after all, a multi-tenant system, and we don't want one restaurant's <em>MaitreD</em> to be able to see another restaurant's schedule. </p> <p> If ASP.NET can address that kind of problem with annotations, I haven't figured out how. The Controller needs to check an access control list against the resource being accessed. The above-mentioned <code>User</code> property of <code>ControllerBase</code> would be <em>really</em> convenient here. </p> <p> Again, there are ways to inject an entire <a href="https://docs.microsoft.com/dotnet/api/system.security.claims.claimsprincipal">ClaimsPrincipal</a> class into the Controller that needs it, but once more I felt that that would violate the Interface Segregation Principle. I didn't need an entire <code>ClaimsPrincipal</code>; I just needed a list of restaurant IDs that a particular JSON Web Token allows access to. </p> <p> As is often my modus operandi in such situations, I started by writing the code I wished to use, and then figured out how to make it work: </p> <p> <pre>[<span style="color:#2b91af;">HttpGet</span>(<span style="color:#a31515;">&quot;restaurants/{restaurantId}/schedule/{year}/{month}/{day}&quot;</span>)] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;<span style="color:#2b91af;">Task</span>&lt;<span style="color:#2b91af;">ActionResult</span>&gt;&nbsp;Get(<span style="color:blue;">int</span>&nbsp;restaurantId,&nbsp;<span style="color:blue;">int</span>&nbsp;year,&nbsp;<span style="color:blue;">int</span>&nbsp;month,&nbsp;<span style="color:blue;">int</span>&nbsp;day) { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>&nbsp;(!AccessControlList.Authorize(restaurantId)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">new</span>&nbsp;<span style="color:#2b91af;">ForbidResult</span>(); &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green;">//&nbsp;Do&nbsp;the&nbsp;real&nbsp;work&nbsp;here...</span></pre> </p> <p> <code>AccessControlList</code> is a <a href="/2012/08/31/ConcreteDependencies">Concrete Dependency</a>. It's just a wrapper around a collection of IDs: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:blue;">sealed</span>&nbsp;<span style="color:blue;">class</span>&nbsp;<span style="color:#2b91af;">AccessControlList</span> { &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">private</span>&nbsp;<span style="color:blue;">readonly</span>&nbsp;<span style="color:#2b91af;">IReadOnlyCollection</span>&lt;<span style="color:blue;">int</span>&gt;&nbsp;restaurantIds;</pre> </p> <p> I had to create a new class in order to keep the built-in ASP.NET DI Container happy. Had I been doing <a href="/2014/06/10/pure-di">Pure DI</a> I could have just injected <code>IReadOnlyCollection&lt;int&gt;</code> directly into the Controller, but in this code base I used the built-in DI Container, which I had to configure like this: </p> <p> <pre>services.AddHttpContextAccessor(); services.AddTransient(sp&nbsp;=&gt;&nbsp;<span style="color:#2b91af;">AccessControlList</span>.FromUser( &nbsp;&nbsp;&nbsp;&nbsp;sp.GetService&lt;<span style="color:#2b91af;">IHttpContextAccessor</span>&gt;().HttpContext.User));</pre> </p> <p> Apart from having to wrap <code>IReadOnlyCollection&lt;int&gt;</code> in a new class, I found such an implementation preferable to inheriting from <code>ControllerBase</code>. The Controller in question only depends on the services it needs: </p> <p> <pre><span style="color:blue;">public</span>&nbsp;<span style="color:#2b91af;">ScheduleController</span>( &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IRestaurantDatabase</span>&nbsp;restaurantDatabase, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">IReservationsRepository</span>&nbsp;repository, &nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af;">AccessControlList</span>&nbsp;accessControlList)</pre> </p> <p> The <code>ScheduleController</code> uses its <code>restaurantDatabase</code> dependency to look up a specific restaurant based on the <code>restaurantId</code>, the <code>repository</code> to read the schedule, and <code>accessControlList</code> to implement authorisation. That's what it needs, so that's its dependencies. It follows the Interface Segregation Principle. </p> <p> The <code>ScheduleController</code> class is easy to unit test, since a test can just create a new <code>AccessControlList</code> object whenever it needs to: </p> <p> <pre>[<span style="color:#2b91af;">Fact</span>] <span style="color:blue;">public</span>&nbsp;<span style="color:blue;">async</span>&nbsp;<span style="color:#2b91af;">Task</span>&nbsp;GetScheduleForAbsentRestaurant() { &nbsp;&nbsp;&