{
    "version": "https://jsonfeed.org/version/1",
    "title": "Agilogy",
    "home_page_url": "",
    "feed_url": "https://blog.agilogy.com/feed.json",
    "description": null,
    "icon": "",
    "favicon": "https://blog.agilogy.com/favicon.ico",
    "expired": false,
    "items": [
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2024-02-02-testing-the-agilogy-way.html",
            "title": "Testing the Agilogy Way",
            "content_text": "We at Agilogy love our craft. And we like having technical discussions, trainings and workshops that allow us to continuously improve the way we develop software. That’s the reason we devote part of our Friday’s mornings to what we call the Agilogy School. These sessions are the weekly occasion for everyone at Agilogy to share and learn about common interests like testing, programming languages, functional programming, software architecture, design, etc.\n\nAs the main facilitator, I have decided to make 2024 the year of software testing at the Agilogy School.\n\nTo do so, we needed a common starting point, for which we used the Hexagonal Architecture, which we reviewed so that all of us share an ubiquitous language when talking about its components You know, driven ports and adapters, driving ports and adapters… or where they driver ports and adapters?.\n\n\n\nFrom there on, we started, as we should, by the basic principles, patterns and strategies that are common to software testing in any technology or programming language.\n\nIn the following weeks or months I’ll be blogging about these testing strategies we use at Agilogy. We may even write about Hexagonal Architecture before that, so we make it clear the way we talk about it.\n\nIn the meantime, I’m sharing the slides of the workshop we are working on:\n\n\n\nYou can download the PDF of the slides here.\n\nFurthermore, I want to take the opportunity to review things I already shared in this blog, now that I have some names for the patterns and strategies I was talking about back then.\n\nPattern: Arrange, Act, Assert with State\n\nIn What is an automated test, again? I talked about how to test methods that have state:\n\n// 1. Set initial state:\nval ma = MemoryAdder()\nma.add(23)\n// 2 and 3. Execute the method and assert\nassertEquals(25, ma.add(2))\n// 4. Collect the final state and assert\nassertEquals(2, ma.lastInput)\n\n\nI have identified this way of testing methods with state as a pattern I call Arrange, Act, Assert with State, or AAA with State for short.\n\nStrategy: Integration Tests of Driven Adapters\n\nIn Testing and persistent state I showed how we can apply the AAA with State pattern to test components whose state is persisted:\n\n// 1. Set initial state\nval userId = 23L\nval userName = \"John\"\nconn.execute(\"delete from users\")\nconn.execute(\n  \"insert into users(id, name, last_visit), ?, ?, null\", \n  userId, \n  userName\n)\n// 2 and 3. Execute the method and assert\nval lastVisit = Instant.now()\nval wasUpdated = updateUserLastVisit(userId, lastVisit)\nassertTrue(wasUpdated)\n// 4. Collect the final state and assert\nval endState =\n  conn.execute(\"select id,name,last_visit from users order by id\"){ \n    (i, n, lv) -&gt; User(id, n, lv)\n  }\nassertEquals(listOf(User(userId, userName, lastVisit)), endState)\n\n\nIf we apply this to an Hexagonal Architecture, we’ll see that the Driven Adapters are the perfect example of such a case. We say these are Integration Tests because we are testing (part of) our system in integration with an actual external system (an actual database, in the example).\n\n\n\nDesign for testability\n\nIn Testing other side effects we started discussing how to test side effects other than state. That led us to discuss Dependency Injection and software design in general.\n",
            "content_html": "<p>We at Agilogy love our craft. And we like having technical discussions, trainings and workshops that allow us to continuously improve the way we develop software. That’s the reason we devote part of our Friday’s mornings to what we call the Agilogy School. These sessions are the weekly occasion for everyone at Agilogy to share and learn about common interests like testing, programming languages, functional programming, software architecture, design, etc.</p>\n\n<p>As the main facilitator, I have decided to make 2024 the year of software testing at the Agilogy School.</p>\n\n<p>To do so, we needed a common starting point, for which we used the Hexagonal Architecture, which we reviewed so that all of us share an ubiquitous language when talking about its <em class=\"sidenote-number\">components</em> <em class=\"sidenote\">You know, driven ports and adapters, driving ports and adapters… or where they <strong>driver</strong> ports and adapters?</em>.</p>\n\n<p><img src=\"../assets/img/hexagonalArchitecture.png\" alt=\"Hexagonal Architecture\" /></p>\n\n<p>From there on, we started, as we should, by the basic principles, patterns and strategies that are common to software testing in any technology or programming language.</p>\n\n<p>In the following weeks or months I’ll be blogging about these testing strategies we use at Agilogy. We may even write about Hexagonal Architecture before that, so we make it clear the way we talk about it.</p>\n\n<p>In the meantime, I’m sharing the slides of the workshop we are working on:</p>\n\n<iframe src=\"https://www.slideshare.net/slideshow/embed_code/key/ogMuxAuuefpUOW?hostedIn=slideshare&amp;page=upload\" width=\"700\" height=\"443\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"></iframe>\n\n<p>You can download the PDF of the slides <a href=\"/assets/SoftwareTestingTheAgilogyWay.pdf\">here</a>.</p>\n\n<p>Furthermore, I want to take the opportunity to review things I already shared in this blog, now that I have some names for the patterns and strategies I was talking about back then.</p>\n\n<h2 id=\"pattern-arrange-act-assert-with-state\">Pattern: Arrange, Act, Assert with State</h2>\n\n<p>In <a href=\"/2022-05-27-what-is-an-automated-test-again.html\">What is an automated test, again?</a> I talked about how to test methods that have state:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// 1. Set initial state:</span>\n<span class=\"kd\">val</span> <span class=\"py\">ma</span> <span class=\"p\">=</span> <span class=\"nc\">MemoryAdder</span><span class=\"p\">()</span>\n<span class=\"n\">ma</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">)</span>\n<span class=\"c1\">// 2 and 3. Execute the method and assert</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">25</span><span class=\"p\">,</span> <span class=\"n\">ma</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">))</span>\n<span class=\"c1\">// 4. Collect the final state and assert</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">ma</span><span class=\"p\">.</span><span class=\"n\">lastInput</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>I have identified this way of testing methods with state as a pattern I call <em><strong>Arrange, Act, Assert with State</strong></em>, or <strong><em>AAA with State</em></strong> for short.</p>\n\n<h2 id=\"strategy-integration-tests-of-driven-adapters\">Strategy: Integration Tests of Driven Adapters</h2>\n\n<p>In <a href=\"/2022-06-17-testing-and-persistent-state.html\">Testing and persistent state</a> I showed how we can apply the <em>AAA with State</em> pattern to test components whose state is persisted:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// 1. Set initial state</span>\n<span class=\"kd\">val</span> <span class=\"py\">userId</span> <span class=\"p\">=</span> <span class=\"mi\">23L</span>\n<span class=\"kd\">val</span> <span class=\"py\">userName</span> <span class=\"p\">=</span> <span class=\"s\">\"John\"</span>\n<span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"delete from users\"</span><span class=\"p\">)</span>\n<span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span>\n  <span class=\"s\">\"insert into users(id, name, last_visit), ?, ?, null\"</span><span class=\"p\">,</span> \n  <span class=\"n\">userId</span><span class=\"p\">,</span> \n  <span class=\"n\">userName</span>\n<span class=\"p\">)</span>\n<span class=\"c1\">// 2 and 3. Execute the method and assert</span>\n<span class=\"kd\">val</span> <span class=\"py\">lastVisit</span> <span class=\"p\">=</span> <span class=\"nc\">Instant</span><span class=\"p\">.</span><span class=\"nf\">now</span><span class=\"p\">()</span>\n<span class=\"kd\">val</span> <span class=\"py\">wasUpdated</span> <span class=\"p\">=</span> <span class=\"nf\">updateUserLastVisit</span><span class=\"p\">(</span><span class=\"n\">userId</span><span class=\"p\">,</span> <span class=\"n\">lastVisit</span><span class=\"p\">)</span>\n<span class=\"nf\">assertTrue</span><span class=\"p\">(</span><span class=\"n\">wasUpdated</span><span class=\"p\">)</span>\n<span class=\"c1\">// 4. Collect the final state and assert</span>\n<span class=\"kd\">val</span> <span class=\"py\">endState</span> <span class=\"p\">=</span>\n  <span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"select id,name,last_visit from users order by id\"</span><span class=\"p\">){</span> \n    <span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">lv</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">id</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">lv</span><span class=\"p\">)</span>\n  <span class=\"p\">}</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">userId</span><span class=\"p\">,</span> <span class=\"n\">userName</span><span class=\"p\">,</span> <span class=\"n\">lastVisit</span><span class=\"p\">)),</span> <span class=\"n\">endState</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>If we apply this to an Hexagonal Architecture, we’ll see that the Driven Adapters are the perfect example of such a case. We say these are <em>Integration Tests</em> because we are testing (part of) our system in integration with an actual external system (an actual database, in the example).</p>\n\n<p><img src=\"../assets/img/integration_test_of_driven_adapters.png\" alt=\"Integration Tests of Driven Adapters\" /></p>\n\n<h2 id=\"design-for-testability\">Design for testability</h2>\n\n<p>In <a href=\"2022-07-08-testing-other-side-effects.html\">Testing other side effects</a> we started discussing how to test side effects other than state. That led us to discuss Dependency Injection and software design in general.</p>\n",
            "url": "https://blog.agilogy.com/2024-02-02-testing-the-agilogy-way.html",
            "date_published": "2024-02-02T00:00:00+01:00",
            "date_modified": "2024-02-02T00:00:00+01:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2024-01-12-writing-a-pbt-library-4-housekeeping.html",
            "title": "Writing a Property Based Testing library in Kotlin, a Journey. Part 4: Housekeeping",
            "content_text": "I’ve had some busy months since I last wrote anything for the blog. Let’s start 2024 by retaking the blog. Today I rescue an entry that I had in progress. We’ll do some housekeeping of the Property Based Library I was writing back in 2023.\n\nIn the previous articles in this series (1, 2 and 3) I was developing a property based testing library from scratch and blogging about the process. It turns out that such library actually exists as a companion repository you can follow while reading. It’s here. So far all articles in the series were about property based testing themselves. But, at the same time, I’m blogging about the actual design of a library.\n\n\nLet’s start!\n\nAs I was focusing on writing about PBT the library has accumulated some problems I’d like fixed. And you bet I’ll be blogging about this too.\n\nReorganizing tests\n\nAs I’m using the library to write this blog series, I’m actually programming (and running the tests) for the code I use in the blog. But some of those code fragments are actually usage examples (like Int tests, DayOfWeek and Geometry). Let’s put all of those in a simple package com.agilogy.wapbtl.examples so that they are not mixed with actual tests of the library, that will be in com.agilogy.wapbtl.test. Examples should probably be in a different project in the multiproject build but I’m frankly not in the mood for a fight with Gradle to get that done. Not now.\n\nAs a result of such cleaner separation, our examples of property based testing of Int where somehow poor. I thought I needed some other property checked, so I checked Int sum is associative:\n\n@Test\nfun testAssociativity(){\n  forAny(Arb.int, Arb.int, Arb.int){ a, b, c -&gt; (a + b) + c == a + (b + c)}\n}\n\n\nI also refactored the class names so all tests (those testing the library and those working as usage examples) all follow the same pattern: XXXTest.\n\nEncountering (and fixing) a bug\n\nWhen programming the additional Int test above I got a green test the first time I run it. I don’t know you, but if I don’t see a test fail I can’t trust it. So I hacked the property so that it failed and I got this:\n\n@Test\nfun testAssociativity(){\n  forAny(Arb.int, Arb.int, Arb.int){ a, b, c -&gt; (a + b) + c == a + (b + c + 1)}\n}\n\n\nProperty failed at attempt 1 with sample false.\nSeed: 4769791297438385931\n\n\nIt failed ok. I have a seed. Yeah!! But, hey, what the heck means “with sample false”??? I wanted it to give me… what, the 3 samples the test used? This is obviously a bug. A design bug, I’d say, as I’m not even sure what PropertyFailedException should be like.\n\n📝 A quick retrospective: I said I like to write tests of everything I develop I didn’t live up to these expectations. This property based testing library is indeed poorly tested. Let’s take note of this technical debt… and, as you do with debts, let’s pay it promptly.\n\nBut as much as I care about paying this debt, I have a production bug to fix first. Let’s fix that. And let’s start by designing the solution.\n\nOur current PropertyFailedException implementation isThis Any? type is something I already hate. And, oh! surprise! it is failing to us now. What I would like is for PropertyFailedException to be parameterized like class PropertyFailedException&lt;A&gt;(val attempt: Int, val seed: Long, val sample: A) but Kotlin complains with “Subclass of ‘Throwable’ may not have type parameters”. So let’s attempt to continue to live with that. For now.:\n\nclass PropertyFailedException(\n  val attempt: Int,\n  val seed: Long,\n  val sample: Any?\n): Exception(...)\n\n\nWhen forAny takes more than one Arg, what would the sample be? We could use tuples and have a sample of type Pair&lt;A, B&gt; if we were given 2 args, and a Triple&lt;A, B, C&gt; if we were given 3. What if we want a forAny of 4 or more values? Coming from Scala I’d say bigger tuples (Tuple4, Tuple5…) would totally make sense here… even though they are not idiomatic in Kotlin. I could use a List&lt;Any?&gt; and put all samples in that list, but I hate to have something that poorly typed. So, lacking a better solution, I will go with the two tuples we already have. Any ideas are welcome here, if you want to tweet or toot (with a mention) or DM them. I’m @jordipradel@fosstodon.org (Mastodon, preferred) and  @agile_jordi (Twitter).\n\nSo now that we decided we expect a tuple, we can fix the bug. But, hey, I just did a quick retrospective, right? Don’t let the gap grow bigger and fix the bug the way se should: by first reproducing it:\n\n@Test\nfun forAny2ArbsFailure() {\n  val property: (Int, Int) -&gt; Boolean = { a, b -&gt; (a + b) &gt; a }\n  var attempts = 0\n  val failure = assertFailsWith&lt;PropertyFailedException&gt; {\n    forAny(Arb.int, Arb.int) { a, b -&gt;\n      attempts += 1\n      property(a, b) \n    }\n  }\n  @Suppress(\"UNCHECKED_CAST\")\n  val failedSample = failure.sample as Pair&lt;Int, Int&gt;\n  assertFalse { property(failedSample.first, failedSample.second) }\n  assertEquals(attempts, failure.attempt)\n}\n\n\nSo, letting aside the ugly casts, we are testing that whenever a forAny that takes two Arb&lt;Int&gt; fails, it should return a Pair&lt;Int,Int&gt; as the failed sample, and that checking the property on those 2 values should fail. And, it fails. Yay! Yes, yay! Because when you are writing a test you expect it to be useful. And a test that you write but never fails is giving you exactly 0 value. We are also testing what we already tested for the one arbitrary version of forAny, to make sure we didn’t break the attempt result.\n\nclass java.lang.Boolean cannot be cast to class kotlin.Pair\njava.lang.ClassCastException: (...)\n\tat com.agilogy.wapbtl.test.ForAnyTest.(...)\n\t...\n\n\nOk, now fix this. The problem is the fancy trick I did to avoid creating a tuple:\n\nfun &lt;A, B, C&gt; forAny(\n  a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;, seed: Long? = null, \n  property: (A, B, C) -&gt; Boolean\n): Unit =\n    forAny(Arb.product3(a, b, c, property), seed) { it }\n\n\nRemember? We were building an Arb&lt;Boolean&gt; that directly told us whether the property passed or not and passing that to the forAny that only takes one Arb. Therefore, we can’t recover the sample values once the forAny fails. But the tuple we wanted to avoid creating is now created at least when the test fails. So I’ll undo the trick and simplify things. In the end, this was a premature optimization, probably. Or the Scala developer in me being confused by the lack of tuples in Kotlin. So, let’s simplify:\n\nfun &lt;A, B&gt; forAny(\n  a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, seed: Long? = null, \n  property: (A, B) -&gt; Boolean\n): Unit = \n    forAny(Arb.pair(a, b), seed) { (a, b) -&gt; property(a, b) }\n\nfun &lt;A, B, C&gt; forAny(\n  a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;, seed: Long? = null,\n  property: (A, B, C) -&gt; Boolean\n): Unit =\n    forAny(Arb.triple(a, b, c), seed) { (a, b, c) -&gt; property(a, b, c) }\n\n\nAnd now our test passes!\n\nTest exceptions\n\nThat’s a basic one I didn’t introduce in the first version just for the sake of a simpler explanation of what property based testing means. Imagine you are trying to check a property of Integer division:\n\n@Test\nfun testIntegerDivision() {\n  forAny(Arb.int, Arb.int) { a, b -&gt;\n    val d = a / b\n    val m = a % b\n    a == b * d + m\n  }\n}\n\n\nAs you already know this is an actual property of integer division… except when b is 0. Of course we can fix the test with a simple if, but let’s imagine you are not aware what the problem is. The result you currently get is:\n\n/ by zero\njava.lang.ArithmeticException: / by zero\n\tat com.agilogy.wapbtl.examples....\n\t...\n\n\nNo PropertyFailedException, no seed, no samples. You are on your own to understand the problem. And it may be a flaky test, where you were fortunate enough to catch an example that fails… but that doesn’t come along that frequently in your test.\n\nAs is customary in testing libraries, we would like to treat an exception as a test failure. Therefore, we may have 3 possible outcomes of the evaluation of your property for a given example. Either the property successfully returns true, or it successfully returns false or it fails with an exception. We’ll consider both returning false or throwing an exception a way of telling us the property does not abide.\n\nFor that we need to… first write a test!\n\n@Test\nfun testForAnyException() {\n  val property: (Int) -&gt; Boolean = { i -&gt;\n    if (i &lt; 0) throw IllegalArgumentException(\"$i\")\n    true\n  }\n  var attempts = 0\n  val failure = assertFailsWith&lt;PropertyFailedException&gt; {\n    forAny(Arb.int) {\n      attempts += 1\n      property(it)\n    }\n  }\n  val failedSample = failure.sample as Int\n  assertTrue(failure.cause is IllegalArgumentException)\n  assertEquals(\"$failedSample\", failure.cause?.message)\n  assertEquals(attempts, failure.attempt)\n}\n\n\nNow we can fix our forAny implementation and make the test pass:\n\nfun &lt;A&gt; forAny(r: Arb&lt;A&gt;, seed: Long? = null, property: (A) -&gt; Boolean) {\n    fun test(currentSeed: Long, attemptNumber: Int) {\n        val sample = r.generate(Random(currentSeed))\n        runCatching { property(sample) }.fold(\n            onSuccess = { result -&gt;\n                if (!result) throw PropertyFailedException(attemptNumber, currentSeed, sample)\n            },\n            onFailure = { exception -&gt;\n                throw PropertyFailedException(attemptNumber, currentSeed, sample, exception)\n            }\n        )\n    }\n    if (seed == null) {\n        (1..100).forEach { attemptNumber -&gt;\n            test(Random.Default.nextLong(), attemptNumber)\n        }\n    } else {\n        test(seed, 1)\n    }\n}\n\n\nPropertyFailedException is now:\n\nclass PropertyFailedException(\n    val attempt: Int,\n    val seed: Long,\n    val sample: Any?,\n    override val cause: Throwable? = null\n) : Exception(\n    \"\"\"Property failed at attempt $attempt\n        |Sample $sample\n        |Seed: $seed\n        |Cause: ${cause?.message}\"\"\".trimMargin()\n)\n\n\nAnd our int division test now throws:\n\ncom.agilogy.wapbtl.PropertyFailedException: Property failed at attempt 1\nSample (-1838537511, 0)\nSeed: -2405689340444717625\nCause: / by zero\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny$test(forAny.kt:25)\n\t...\nCaused by: java.lang.ArithmeticException: / by zero\n\tat com.agilogy.wapbtl.examples.ForAnyIntTest$testIntegerDivision$1...\n\n\nYour favourite assertion library\n\nAs a side effect of handling exceptions as test failures, now you could use your favourite assertions library to check properties if you prefer:\n\nforAny(Arb.int, Arb.int) { a, b -&gt;\n  val d = a / b\n  val m = a % b\n  assertEquals(a, b * d + m)\n}\n\n\nThat has one important advantage: In case of failure now you get the descriptive behaviour your assertion library carefully provides. And one disadvantatge: it does not compile, because forAny expects a function that returns a Boolean. Of course you could return true, but that would be horrible. So let’s do something about it.\n\nRed:\n\n@Test\nfun testTestForAny() {\n  val property: (Int) -&gt; Unit = { i -&gt;\n    if (i &lt; 0) throw AssertionError(\"$i\")\n  }\n  var attempts = 0\n  val failure = assertFailsWith&lt;PropertyFailedException&gt; {\n    testForAny(Arb.int) {\n      attempts += 1\n      property(it)\n    }\n  }\n  val failedSample = failure.sample as Int\n  assertTrue(failure.cause is AssertionError)\n  assertEquals(\"$failedSample\", failure.cause?.message)\n  assertEquals(attempts, failure.attempt)\n}\n\n\nGreen:\n\nfun &lt;A&gt; testForAny(aa: Arb&lt;A&gt;, seed: Long? = null, property: (A) -&gt; Unit) =\n  forAny(aa, seed) { a-&gt;\n    property(a)\n    true\n  }\n\n\nRefactor: I could reuse some lines between the two functions that test how the property based tests fail, but the resulting code is too much difficult to grasp.\n\nHaving fun with fun interfaces\n\nOne more thing… So far, every time we define a new instance of Arb we go like this:\n\nval Arb.Companion.float: Arb&lt;Float&gt;\n    get() = object : Arb&lt;Float&gt; {\n        override fun generate(random: Random): Float = \n          random.nextFloat()\n    }\n\n\nBut you may know Kotlin has this nice feature called functional interfaces. We only need to add the fun keyword to our interface:\n\nfun interface Arb&lt;A&gt; {\n    fun generate(random: Random): A\n\n    companion object\n}\n\n\nAnd we can now simplify all those object : Arb&lt;...&gt; expressions like in the example below:\n\nval Arb.Companion.float: Arb&lt;Float&gt;\n    get() = Arb { random -&gt; random.nextFloat() }\n\n\nUpgrading Gradle and libraries\n\nFinally, since it’s been quite long since I last worked on this library, some of its dependencies are a bit outdated. Let us fix that.\n\nI’ll start with Gradle. Acording to ./gradlew --version, the project is currently using Gradle 7.3.3. What version should we upgrade to? Let’s do some research:\n\n\n  The latest Gradle version at the time of writing is 8.5\n  The Kotlin Gradle Plugin latest supported Gradle version is 8.1.1 acording to the documentation.\n  But Ktor is using 8.4\n\n\nSo we’ll use 8.4.\n\nWe could change files by hand, but there is already a Gradle task to upgrade the gradle wrapper:\n\n$ gradle wrapper --gradle-version 8.4\n...\n$ git status\n...\nChanges not staged for commit:\n        modified:   gradle/wrapper/gradle-wrapper.jar\n        modified:   gradle/wrapper/gradle-wrapper.properties\n        modified:   gradlew\n        modified:   gradlew.bat\n...\n$ git commit -am \"Upgrade Gradle to latest supported version\"\n\n\nNow we can upgrade the Kotlin Gradle Plugin to the latest version. For that, we need to change the corresponding line in build.gradle.kts:\n\nkotlin(\"multiplatform\") version \"1.9.22\"\n\n\nBut then, we’ll find our build fails and, when fixed, emits some warnings. Here are some changes we need to do to build.gradle.kts:\n\n\n  cssSupport.enabled = true is not supported anymore. We need to replace it with cssSupport{enabled = true}\n  The Kotlin/JS Legacy compiler backend is deprecated. We need to replace js(LEGACY) with js.\n  Variable nativeTarget is never used. I wanted a Kotlin multiplatform build so that the library can be used in any platform. But I don’t want to spend time configuring native builds now, so I’ll simply remove the build for those. We can add them later on if we want.\n\n\nFurthermore, Kotlin 1.9.20 brought us templates for multiplatform projects. The neat result is that we can simply remove all the manual sourceSets configuration we had and replace it with just the configuration of the dependencies we need:\n\ndependencies {\n    commonTestImplementation(kotlin(\"test\"))\n}\n\n\nRecap\n\nWe made some maintenance tasks on our beloved Property Based Testing library. We reorganized packages to better distinguish between tests and examples. As a result of that, we improved some example tests and found a design failure that we fixed using TDD. We enhanced the usability of the library by adding explicit support to exceptions during tests. Finally, we upgraded both Gradle and Kotlin to the latest current versions.\n\nAll articles in the series\n\n\n  Writing a property based testing library, part 1\n  Writing a property based testing library, part 2\n  Writing a property based testing library, part 3\n  Writing a property based testing library, part 4\n\n",
            "content_html": "<p>I’ve had some busy months since I last wrote anything for the blog. Let’s start 2024 by retaking the blog. Today I rescue an entry that I had in progress. We’ll do some housekeeping of the Property Based Library I was writing back in 2023.</p>\n\n<p>In the previous articles in this series (<a href=\"./2022-10-04-writing-a-pbt-ibrary-1.html\">1</a>, <a href=\"./2022-10-14-writing-a-pbt-ibrary-2.html\">2</a> and <a href=\"./2022-10-21-writing-a-pbt-ibrary-3.html\">3</a>) I was developing a property based testing library from scratch and blogging about the process. It turns out that such library actually exists as a companion repository you can follow while reading. It’s <a href=\"https://github.com/agile-jordi/wapbtl/tree/part4\">here</a>. So far all articles in the series were about property based testing themselves. But, at the same time, I’m blogging about the actual design of a library.</p>\n\n<p><img src=\"../assets/img/winstonWolf.gif\" alt=\"Pulp Fiction Winston Wolf\" class=\"figcaption\" />\n<em class=\"figcaption\">Let’s start!</em></p>\n\n<p>As I was focusing on writing about PBT the library has accumulated some problems I’d like fixed. And you bet I’ll be blogging about this too.</p>\n\n<h2 id=\"reorganizing-tests\">Reorganizing tests</h2>\n\n<p>As I’m using the library to write this blog series, I’m actually programming (and running the tests) for the code I use in the blog. But some of those code fragments are actually usage examples (like <code class=\"language-plaintext highlighter-rouge\">Int</code> tests, <code class=\"language-plaintext highlighter-rouge\">DayOfWeek</code> and <code class=\"language-plaintext highlighter-rouge\">Geometry</code>). Let’s put all of those in a simple package <code class=\"language-plaintext highlighter-rouge\">com.agilogy.wapbtl.examples</code> so that they are not mixed with actual tests of the library, that will be in <code class=\"language-plaintext highlighter-rouge\">com.agilogy.wapbtl.test</code>. Examples should probably be in a different project in the multiproject build but I’m frankly not in the mood for a fight with Gradle to get that done. Not now.</p>\n\n<p>As a result of such cleaner separation, our examples of property based testing of <code class=\"language-plaintext highlighter-rouge\">Int</code> where somehow poor. I thought I needed some other property checked, so I checked <code class=\"language-plaintext highlighter-rouge\">Int</code> sum is associative:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testAssociativity</span><span class=\"p\">(){</span>\n  <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">){</span> <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span> <span class=\"p\">-&gt;</span> <span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"p\">+</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">+</span> <span class=\"n\">c</span> <span class=\"p\">==</span> <span class=\"n\">a</span> <span class=\"p\">+</span> <span class=\"p\">(</span><span class=\"n\">b</span> <span class=\"p\">+</span> <span class=\"n\">c</span><span class=\"p\">)}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>I also refactored the class names so all tests (those testing the library and those working as usage examples) all follow the same pattern: <code class=\"language-plaintext highlighter-rouge\">XXXTest</code>.</p>\n\n<h2 id=\"encountering-and-fixing-a-bug\">Encountering (and fixing) a bug</h2>\n\n<p>When programming the additional <code class=\"language-plaintext highlighter-rouge\">Int</code> test above I got a green test the first time I run it. I don’t know you, but if I don’t see a test fail I can’t trust it. So I hacked the property so that it failed and I got this:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testAssociativity</span><span class=\"p\">(){</span>\n  <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">){</span> <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span> <span class=\"p\">-&gt;</span> <span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"p\">+</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">+</span> <span class=\"n\">c</span> <span class=\"p\">==</span> <span class=\"n\">a</span> <span class=\"p\">+</span> <span class=\"p\">(</span><span class=\"n\">b</span> <span class=\"p\">+</span> <span class=\"n\">c</span> <span class=\"p\">+</span> <span class=\"mi\">1</span><span class=\"p\">)}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<div class=\"language-shell highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Property failed at attempt 1 with sample false.\nSeed: 4769791297438385931\n</code></pre></div></div>\n\n<p>It failed ok. I have a seed. Yeah!! But, hey, what the heck means “with sample <code class=\"language-plaintext highlighter-rouge\">false</code>”??? I wanted it to give me… what, the 3 samples the test used? This is obviously a bug. A design bug, I’d say, as I’m not even sure what <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> should be like.</p>\n\n<p>📝 A quick retrospective: I said I like to write tests of everything I develop I didn’t live up to these expectations. This property based testing library is indeed poorly tested. Let’s take note of this technical debt… and, as you do with debts, let’s pay it promptly.</p>\n\n<p>But as much as I care about paying this debt, I have a production bug to fix first. Let’s fix that. And let’s start by designing the solution.</p>\n\n<p>Our current <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> implementation <em class=\"sidenote-number\">is</em><em class=\"sidenote\">This <code class=\"language-plaintext highlighter-rouge\">Any?</code> type is something I already hate. And, oh! surprise! it is failing to us now. What I would like is for <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> to be parameterized like <code class=\"language-plaintext highlighter-rouge\">class PropertyFailedException&lt;A&gt;(val attempt: Int, val seed: Long, val sample: A) </code>but Kotlin complains with “Subclass of ‘Throwable’ may not have type parameters”. So let’s attempt to continue to live with that. For now.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span>\n  <span class=\"kd\">val</span> <span class=\"py\">attempt</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span>\n  <span class=\"kd\">val</span> <span class=\"py\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">,</span>\n  <span class=\"kd\">val</span> <span class=\"py\">sample</span><span class=\"p\">:</span> <span class=\"nc\">Any</span><span class=\"p\">?</span>\n<span class=\"p\">):</span> <span class=\"nc\">Exception</span><span class=\"p\">(</span><span class=\"o\">..</span><span class=\"p\">.)</span>\n</code></pre></div></div>\n\n<p>When <code class=\"language-plaintext highlighter-rouge\">forAny</code> takes more than one <code class=\"language-plaintext highlighter-rouge\">Arg</code>, what would the sample be? We could use tuples and have a sample of type <code class=\"language-plaintext highlighter-rouge\">Pair&lt;A, B&gt;</code> if we were given 2 args, and a <code class=\"language-plaintext highlighter-rouge\">Triple&lt;A, B, C&gt;</code> if we were given 3. What if we want a <code class=\"language-plaintext highlighter-rouge\">forAny</code> of 4 or more values? Coming from Scala I’d say bigger tuples (<code class=\"language-plaintext highlighter-rouge\">Tuple4</code>, <code class=\"language-plaintext highlighter-rouge\">Tuple5</code>…) would totally make sense here… even though they are not idiomatic in Kotlin. I could use a <code class=\"language-plaintext highlighter-rouge\">List&lt;Any?&gt;</code> and put all samples in that list, but I hate to have something that poorly typed. So, lacking a better solution, I will go with the two tuples we already have. Any ideas are welcome here, if you want to tweet or toot (with a mention) or DM them. I’m <a href=\"https://fosstodon.org/@jordipradel\">@jordipradel@fosstodon.org</a> (Mastodon, preferred) and  <a href=\"https://twitter.com/agile_jordi\">@agile_jordi</a> (Twitter).</p>\n\n<p>So now that we decided we expect a tuple, we can fix the bug. But, hey, I just did a quick retrospective, right? Don’t let the gap grow bigger and fix the bug the way se should: by first reproducing it:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">forAny2ArbsFailure</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"kd\">val</span> <span class=\"py\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">Int</span><span class=\"p\">,</span> <span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"p\">-&gt;</span> <span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"p\">+</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">&gt;</span> <span class=\"n\">a</span> <span class=\"p\">}</span>\n  <span class=\"kd\">var</span> <span class=\"py\">attempts</span> <span class=\"p\">=</span> <span class=\"mi\">0</span>\n  <span class=\"kd\">val</span> <span class=\"py\">failure</span> <span class=\"p\">=</span> <span class=\"n\">assertFailsWith</span><span class=\"p\">&lt;</span><span class=\"nc\">PropertyFailedException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"p\">-&gt;</span>\n      <span class=\"n\">attempts</span> <span class=\"p\">+=</span> <span class=\"mi\">1</span>\n      <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)</span> \n    <span class=\"p\">}</span>\n  <span class=\"p\">}</span>\n  <span class=\"nd\">@Suppress</span><span class=\"p\">(</span><span class=\"s\">\"UNCHECKED_CAST\"</span><span class=\"p\">)</span>\n  <span class=\"kd\">val</span> <span class=\"py\">failedSample</span> <span class=\"p\">=</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">sample</span> <span class=\"k\">as</span> <span class=\"nc\">Pair</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">,</span> <span class=\"nc\">Int</span><span class=\"p\">&gt;</span>\n  <span class=\"nf\">assertFalse</span> <span class=\"p\">{</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">failedSample</span><span class=\"p\">.</span><span class=\"n\">first</span><span class=\"p\">,</span> <span class=\"n\">failedSample</span><span class=\"p\">.</span><span class=\"n\">second</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"n\">attempts</span><span class=\"p\">,</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">attempt</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>So, letting aside the ugly casts, we are testing that whenever a <code class=\"language-plaintext highlighter-rouge\">forAny</code> that takes two <code class=\"language-plaintext highlighter-rouge\">Arb&lt;Int&gt;</code> fails, it should return a <code class=\"language-plaintext highlighter-rouge\">Pair&lt;Int,Int&gt;</code> as the failed sample, and that checking the property on those 2 values should fail. And, it fails. <em class=\"sidenote-number\">Yay!</em> <em class=\"sidenote\">Yes, yay! Because when you are writing a test you expect it to be useful. And a test that you write but never fails is giving you exactly 0 value.</em> We are also testing what we already tested for the one arbitrary version of <code class=\"language-plaintext highlighter-rouge\">forAny</code>, to make sure we didn’t break the <code class=\"language-plaintext highlighter-rouge\">attempt</code> result.</p>\n\n<div class=\"language-shell highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>class java.lang.Boolean cannot be cast to class kotlin.Pair\njava.lang.ClassCastException: <span class=\"o\">(</span>...<span class=\"o\">)</span>\n\tat com.agilogy.wapbtl.test.ForAnyTest.<span class=\"o\">(</span>...<span class=\"o\">)</span>\n\t...\n</code></pre></div></div>\n\n<p>Ok, now fix this. The problem is the fancy trick I did to avoid creating a tuple:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span>\n  <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span> \n  <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span>\n<span class=\"p\">):</span> <span class=\"nc\">Unit</span> <span class=\"p\">=</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">product3</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">),</span> <span class=\"n\">seed</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">it</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Remember? We were building an <code class=\"language-plaintext highlighter-rouge\">Arb&lt;Boolean&gt;</code> that directly told us whether the property passed or not and passing that to the <code class=\"language-plaintext highlighter-rouge\">forAny</code> that only takes one <code class=\"language-plaintext highlighter-rouge\">Arb</code>. Therefore, we can’t recover the sample values once the <code class=\"language-plaintext highlighter-rouge\">forAny</code> fails. But the tuple we wanted to avoid creating is now created at least when the test fails. So I’ll undo the trick and simplify things. In the end, this was a premature optimization, probably. Or the Scala developer in me being confused by the lack of tuples in Kotlin. So, let’s simplify:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span>\n  <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span> \n  <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span>\n<span class=\"p\">):</span> <span class=\"nc\">Unit</span> <span class=\"p\">=</span> \n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">pair</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">),</span> <span class=\"n\">seed</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n\n<span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span>\n  <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span>\n  <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span>\n<span class=\"p\">):</span> <span class=\"nc\">Unit</span> <span class=\"p\">=</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">triple</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">),</span> <span class=\"n\">seed</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>And now our test passes!</p>\n\n<h2 id=\"test-exceptions\">Test exceptions</h2>\n\n<p>That’s a basic one I didn’t introduce in the first version just for the sake of a simpler explanation of what property based testing means. Imagine you are trying to check a property of Integer division:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testIntegerDivision</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"p\">-&gt;</span>\n    <span class=\"kd\">val</span> <span class=\"py\">d</span> <span class=\"p\">=</span> <span class=\"n\">a</span> <span class=\"p\">/</span> <span class=\"n\">b</span>\n    <span class=\"kd\">val</span> <span class=\"py\">m</span> <span class=\"p\">=</span> <span class=\"n\">a</span> <span class=\"p\">%</span> <span class=\"n\">b</span>\n    <span class=\"n\">a</span> <span class=\"p\">==</span> <span class=\"n\">b</span> <span class=\"p\">*</span> <span class=\"n\">d</span> <span class=\"p\">+</span> <span class=\"n\">m</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>As you already know this is an actual property of integer division… except when b is 0. Of course we can fix the test with a simple <code class=\"language-plaintext highlighter-rouge\">if</code>, but let’s imagine you are not aware what the problem is. The result you currently get is:</p>\n\n<div class=\"language-shell highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>/ by zero\njava.lang.ArithmeticException: / by zero\n\tat com.agilogy.wapbtl.examples....\n\t...\n</code></pre></div></div>\n\n<p>No <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code>, no seed, no samples. You are on your own to understand the problem. And it may be a flaky test, where you were fortunate enough to catch an example that fails… but that doesn’t come along that frequently in your test.</p>\n\n<p>As is customary in testing libraries, we would like to treat an exception as a test failure. Therefore, we may have 3 possible outcomes of the evaluation of your property for a given example. Either the property successfully returns <code class=\"language-plaintext highlighter-rouge\">true</code>, or it successfully returns <code class=\"language-plaintext highlighter-rouge\">false</code> or it fails with an exception. We’ll consider both returning <code class=\"language-plaintext highlighter-rouge\">false</code> or throwing an exception a way of telling us the property does not abide.</p>\n\n<p>For that we need to… first write a test!</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testForAnyException</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"kd\">val</span> <span class=\"py\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">i</span> <span class=\"p\">&lt;</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"k\">throw</span> <span class=\"nc\">IllegalArgumentException</span><span class=\"p\">(</span><span class=\"s\">\"$i\"</span><span class=\"p\">)</span>\n    <span class=\"k\">true</span>\n  <span class=\"p\">}</span>\n  <span class=\"kd\">var</span> <span class=\"py\">attempts</span> <span class=\"p\">=</span> <span class=\"mi\">0</span>\n  <span class=\"kd\">val</span> <span class=\"py\">failure</span> <span class=\"p\">=</span> <span class=\"n\">assertFailsWith</span><span class=\"p\">&lt;</span><span class=\"nc\">PropertyFailedException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"n\">attempts</span> <span class=\"p\">+=</span> <span class=\"mi\">1</span>\n      <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">it</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n  <span class=\"p\">}</span>\n  <span class=\"kd\">val</span> <span class=\"py\">failedSample</span> <span class=\"p\">=</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">sample</span> <span class=\"k\">as</span> <span class=\"nc\">Int</span>\n  <span class=\"nf\">assertTrue</span><span class=\"p\">(</span><span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">cause</span> <span class=\"k\">is</span> <span class=\"nc\">IllegalArgumentException</span><span class=\"p\">)</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"s\">\"$failedSample\"</span><span class=\"p\">,</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">cause</span><span class=\"o\">?.</span><span class=\"n\">message</span><span class=\"p\">)</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"n\">attempts</span><span class=\"p\">,</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">attempt</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Now we can fix our <code class=\"language-plaintext highlighter-rouge\">forAny</code> implementation and make the test pass:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">fun</span> <span class=\"nf\">test</span><span class=\"p\">(</span><span class=\"n\">currentSeed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">,</span> <span class=\"n\">attemptNumber</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"kd\">val</span> <span class=\"py\">sample</span> <span class=\"p\">=</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"nc\">Random</span><span class=\"p\">(</span><span class=\"n\">currentSeed</span><span class=\"p\">))</span>\n        <span class=\"nf\">runCatching</span> <span class=\"p\">{</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">sample</span><span class=\"p\">)</span> <span class=\"p\">}.</span><span class=\"nf\">fold</span><span class=\"p\">(</span>\n            <span class=\"n\">onSuccess</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">result</span> <span class=\"p\">-&gt;</span>\n                <span class=\"k\">if</span> <span class=\"p\">(!</span><span class=\"n\">result</span><span class=\"p\">)</span> <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"n\">attemptNumber</span><span class=\"p\">,</span> <span class=\"n\">currentSeed</span><span class=\"p\">,</span> <span class=\"n\">sample</span><span class=\"p\">)</span>\n            <span class=\"p\">},</span>\n            <span class=\"n\">onFailure</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">exception</span> <span class=\"p\">-&gt;</span>\n                <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"n\">attemptNumber</span><span class=\"p\">,</span> <span class=\"n\">currentSeed</span><span class=\"p\">,</span> <span class=\"n\">sample</span><span class=\"p\">,</span> <span class=\"n\">exception</span><span class=\"p\">)</span>\n            <span class=\"p\">}</span>\n        <span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">seed</span> <span class=\"p\">==</span> <span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"o\">..</span><span class=\"mi\">100</span><span class=\"p\">).</span><span class=\"nf\">forEach</span> <span class=\"p\">{</span> <span class=\"n\">attemptNumber</span> <span class=\"p\">-&gt;</span>\n            <span class=\"nf\">test</span><span class=\"p\">(</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nc\">Default</span><span class=\"p\">.</span><span class=\"nf\">nextLong</span><span class=\"p\">(),</span> <span class=\"n\">attemptNumber</span><span class=\"p\">)</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n        <span class=\"nf\">test</span><span class=\"p\">(</span><span class=\"n\">seed</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p><code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> is now:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span>\n    <span class=\"kd\">val</span> <span class=\"py\">attempt</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span>\n    <span class=\"kd\">val</span> <span class=\"py\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">,</span>\n    <span class=\"kd\">val</span> <span class=\"py\">sample</span><span class=\"p\">:</span> <span class=\"nc\">Any</span><span class=\"p\">?,</span>\n    <span class=\"k\">override</span> <span class=\"kd\">val</span> <span class=\"py\">cause</span><span class=\"p\">:</span> <span class=\"nc\">Throwable</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span>\n<span class=\"p\">)</span> <span class=\"p\">:</span> <span class=\"nc\">Exception</span><span class=\"p\">(</span>\n    <span class=\"s\">\"\"\"Property failed at attempt $attempt\n        |Sample $sample\n        |Seed: $seed\n        |Cause: ${cause?.message}\"\"\"</span><span class=\"p\">.</span><span class=\"nf\">trimMargin</span><span class=\"p\">()</span>\n<span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>And our int division test now throws:</p>\n\n<pre><code class=\"language-shel\">com.agilogy.wapbtl.PropertyFailedException: Property failed at attempt 1\nSample (-1838537511, 0)\nSeed: -2405689340444717625\nCause: / by zero\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny$test(forAny.kt:25)\n\t...\nCaused by: java.lang.ArithmeticException: / by zero\n\tat com.agilogy.wapbtl.examples.ForAnyIntTest$testIntegerDivision$1...\n</code></pre>\n\n<h3 id=\"your-favourite-assertion-library\">Your favourite assertion library</h3>\n\n<p>As a side effect of handling exceptions as test failures, now you could use your favourite assertions library to check properties if you prefer:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"p\">-&gt;</span>\n  <span class=\"kd\">val</span> <span class=\"py\">d</span> <span class=\"p\">=</span> <span class=\"n\">a</span> <span class=\"p\">/</span> <span class=\"n\">b</span>\n  <span class=\"kd\">val</span> <span class=\"py\">m</span> <span class=\"p\">=</span> <span class=\"n\">a</span> <span class=\"p\">%</span> <span class=\"n\">b</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"p\">*</span> <span class=\"n\">d</span> <span class=\"p\">+</span> <span class=\"n\">m</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>That has one important advantage: In case of failure now you get the descriptive behaviour your assertion library carefully provides. And one disadvantatge: it does not compile, because <code class=\"language-plaintext highlighter-rouge\">forAny</code> expects a function that returns a Boolean. Of course you could return <code class=\"language-plaintext highlighter-rouge\">true</code>, but that would be horrible. So let’s do something about it.</p>\n\n<p>Red:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testTestForAny</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"kd\">val</span> <span class=\"py\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Unit</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">i</span> <span class=\"p\">&lt;</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"k\">throw</span> <span class=\"nc\">AssertionError</span><span class=\"p\">(</span><span class=\"s\">\"$i\"</span><span class=\"p\">)</span>\n  <span class=\"p\">}</span>\n  <span class=\"kd\">var</span> <span class=\"py\">attempts</span> <span class=\"p\">=</span> <span class=\"mi\">0</span>\n  <span class=\"kd\">val</span> <span class=\"py\">failure</span> <span class=\"p\">=</span> <span class=\"n\">assertFailsWith</span><span class=\"p\">&lt;</span><span class=\"nc\">PropertyFailedException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nf\">testForAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"n\">attempts</span> <span class=\"p\">+=</span> <span class=\"mi\">1</span>\n      <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">it</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n  <span class=\"p\">}</span>\n  <span class=\"kd\">val</span> <span class=\"py\">failedSample</span> <span class=\"p\">=</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">sample</span> <span class=\"k\">as</span> <span class=\"nc\">Int</span>\n  <span class=\"nf\">assertTrue</span><span class=\"p\">(</span><span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">cause</span> <span class=\"k\">is</span> <span class=\"nc\">AssertionError</span><span class=\"p\">)</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"s\">\"$failedSample\"</span><span class=\"p\">,</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">cause</span><span class=\"o\">?.</span><span class=\"n\">message</span><span class=\"p\">)</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"n\">attempts</span><span class=\"p\">,</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">attempt</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Green:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">testForAny</span><span class=\"p\">(</span><span class=\"n\">aa</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Unit</span><span class=\"p\">)</span> <span class=\"p\">=</span>\n  <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">aa</span><span class=\"p\">,</span> <span class=\"n\">seed</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">a-</span><span class=\"p\">&gt;</span>\n    <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">)</span>\n    <span class=\"k\">true</span>\n  <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Refactor: I could reuse some lines between the two functions that test how the property based tests fail, but the resulting code is too much difficult to grasp.</p>\n\n<h2 id=\"having-fun-with-fun-interfaces\">Having fun with fun interfaces</h2>\n\n<p>One more thing… So far, every time we define a new instance of <code class=\"language-plaintext highlighter-rouge\">Arb</code> we go like this:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">float</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Float</span><span class=\"p\">&gt;</span>\n    <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Float</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">Float</span> <span class=\"p\">=</span> \n          <span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nf\">nextFloat</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But you may know Kotlin has this nice feature called <a href=\"https://kotlinlang.org/docs/fun-interfaces.html\">functional interfaces</a>. We only need to add the <code class=\"language-plaintext highlighter-rouge\">fun</code> keyword to our interface:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">interface</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">A</span>\n\n    <span class=\"k\">companion</span> <span class=\"k\">object</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>And we can now simplify all those <code class=\"language-plaintext highlighter-rouge\">object : Arb&lt;...&gt;</code> expressions like in the example below:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">float</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Float</span><span class=\"p\">&gt;</span>\n    <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"nc\">Arb</span> <span class=\"p\">{</span> <span class=\"n\">random</span> <span class=\"p\">-&gt;</span> <span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nf\">nextFloat</span><span class=\"p\">()</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"upgrading-gradle-and-libraries\">Upgrading Gradle and libraries</h2>\n\n<p>Finally, since it’s been quite long since I last worked on this library, some of its dependencies are a bit outdated. Let us fix that.</p>\n\n<p>I’ll start with Gradle. Acording to <code class=\"language-plaintext highlighter-rouge\">./gradlew --version</code>, the project is currently using Gradle 7.3.3. What version should we upgrade to? Let’s do some research:</p>\n\n<ul>\n  <li>The latest Gradle version at the time of writing is <a href=\"https://gradle.org/releases/\">8.5</a></li>\n  <li>The Kotlin Gradle Plugin latest supported Gradle version is 8.1.1 acording to <a href=\"https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin\">the documentation</a>.</li>\n  <li>But Ktor is using <a href=\"https://github.com/ktorio/ktor/pull/3802\">8.4</a></li>\n</ul>\n\n<p>So we’ll use 8.4.</p>\n\n<p>We could change files by hand, but there is already a Gradle task to upgrade the gradle wrapper:</p>\n\n<div class=\"language-shell highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nv\">$ </span>gradle wrapper <span class=\"nt\">--gradle-version</span> 8.4\n...\n<span class=\"nv\">$ </span>git status\n...\nChanges not staged <span class=\"k\">for </span>commit:\n        modified:   gradle/wrapper/gradle-wrapper.jar\n        modified:   gradle/wrapper/gradle-wrapper.properties\n        modified:   gradlew\n        modified:   gradlew.bat\n...\n<span class=\"nv\">$ </span>git commit <span class=\"nt\">-am</span> <span class=\"s2\">\"Upgrade Gradle to latest supported version\"</span>\n</code></pre></div></div>\n\n<p>Now we can upgrade the Kotlin Gradle Plugin to the <a href=\"https://plugins.gradle.org/plugin/org.jetbrains.kotlin.android/1.9.22\">latest version</a>. For that, we need to change the corresponding line in <code class=\"language-plaintext highlighter-rouge\">build.gradle.kts</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">kotlin</span><span class=\"p\">(</span><span class=\"s\">\"multiplatform\"</span><span class=\"p\">)</span> <span class=\"n\">version</span> <span class=\"s\">\"1.9.22\"</span>\n</code></pre></div></div>\n\n<p>But then, we’ll find our build fails and, when fixed, emits some warnings. Here are some changes we need to do to <code class=\"language-plaintext highlighter-rouge\">build.gradle.kts</code>:</p>\n\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">cssSupport.enabled = true</code> is not supported anymore. We need to replace it with <code class=\"language-plaintext highlighter-rouge\">cssSupport{enabled = true}</code></li>\n  <li>The Kotlin/JS Legacy compiler backend is deprecated. We need to replace <code class=\"language-plaintext highlighter-rouge\">js(LEGACY)</code> with <code class=\"language-plaintext highlighter-rouge\">js</code>.</li>\n  <li>Variable <code class=\"language-plaintext highlighter-rouge\">nativeTarget</code> is never used. I wanted a Kotlin multiplatform build so that the library can be used in any platform. But I don’t want to spend time configuring native builds now, so I’ll simply remove the build for those. We can add them later on if we want.</li>\n</ul>\n\n<p>Furthermore, Kotlin 1.9.20 brought us <a href=\"https://kotlinlang.org/docs/whatsnew1920.html#template-for-configuring-multiplatform-projects\">templates for multiplatform projects</a>. The neat result is that we can simply remove all the manual <code class=\"language-plaintext highlighter-rouge\">sourceSets</code> configuration we had and replace it with just the configuration of the dependencies we need:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">dependencies</span> <span class=\"p\">{</span>\n    <span class=\"nf\">commonTestImplementation</span><span class=\"p\">(</span><span class=\"nf\">kotlin</span><span class=\"p\">(</span><span class=\"s\">\"test\"</span><span class=\"p\">))</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"recap\">Recap</h2>\n\n<p>We made some maintenance tasks on our beloved Property Based Testing library. We reorganized packages to better distinguish between tests and examples. As a result of that, we improved some example tests and found a design failure that we fixed using TDD. We enhanced the usability of the library by adding explicit support to exceptions during tests. Finally, we upgraded both Gradle and Kotlin to the latest current versions.</p>\n\n<h2 id=\"all-articles-in-the-series\">All articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-10-04-writing-a-pbt-ibrary-1.html\">Writing a property based testing library, part 1</a></li>\n  <li><a href=\"./2022-10-14-writing-a-pbt-ibrary-2.html\">Writing a property based testing library, part 2</a></li>\n  <li><a href=\"./2022-10-25-writing-a-pbt-ibrary-3.html\">Writing a property based testing library, part 3</a></li>\n  <li><a href=\"./2024-01-12-writing-a-pbt-library-4-housekeeping.html\">Writing a property based testing library, part 4</a></li>\n</ol>\n",
            "url": "https://blog.agilogy.com/2024-01-12-writing-a-pbt-library-4-housekeeping.html",
            "date_published": "2024-01-12T00:00:00+01:00",
            "date_modified": "2024-01-12T00:00:00+01:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2023-03-17-writing-a-simple-jdb-library-in-java.html",
            "title": "Writing a simple JDBC library in Java",
            "content_text": "This time I’m in the mood for playing a bit with my good old friend Java. While preparing a kata for my students I wanted some simple database access library they could use without previous knowledge or experience. I could have looked at many alternatives, but I really wanted something simple.\n\nSimple like I’m assuming Java 11 or later here. As a reminder, 11 is the LTS that was released on 09/2018 and is planned to be supported through 2026. I will mostly need lambdas (which are around since Java 8, released on 3/2014 and supported through at least 2030).  You’ll see vars as well, which would require Java 11 (counting only LTSs), but they are easy to replace with their corresponding types if you are stuck with Java 8.:\n\nList&lt;User&gt;  users = tx.select(\n  \"select u.id, u.name, u.surname from users u \" +\n  \"where u.active = true amd u.role = ?\",\n  (rs) -&gt; new User(rs.getString(1), rs.getString(2), rs.getString(3)),\n  p(\"student\") // The parameter value for the ? in the query\n);\n\n\nSummarizing the idea:\n\n\n  The user writes Plain Old Sql (pos? posql?) her database will parse, interpret and execute. Not a fancy DSL hopefully translated to the correct sql her database wants.\n  The user writes a lambda to tell the library how each row is read. She does not need to handle ResultSet.next(), so there is no way she can fail to do so correctly.\n  The user passes arguments in a vararg with p(xxx) for any admissible value xxx where admissible means it must be a value of a type supported by the library.\n\n\nI’ve used this very same approach with Scala (I admit some implicits where used there) and Kotlin (look, ma! no implicits!). So let’s try my hand at Java.\n\nUnder the hood I’m using Jdbc. Yes, it blocks threads, but that may be solved sooner than anyone expected. And it throws ugly checked exceptions we will need to deal with. In fact, it very poorly handles errors in a non standard way. But other than that, it is fine and very well known.\n\nConnections and DataSources\n\nThe functions I will offer (like select, selectOne, update, etc.) will need a Connection. As per Jdbc itself, we need to be able to use the same Connection to invoke several database operations in a given transaction. So let’s use dependency injection! I could simply add a parameter to every funciton needing a Connection, but I prefer to create a class to represent the scope of a connection, a class where those fancy operations will live.\n\npublic class ConnectionScope {\n  private final Connection connection;\n\n  public ConnectionScope(Connection connection) {\n    this.connection = connection;\n  }\n\n  public &lt;A&gt; List&lt;A&gt; select(String sql, RowReader&lt;A&gt; reader, Param... params) {...}\n  public int update(String sql, Param... params) {...}\n  ...\n}\n\n\nSo now our beloved user needs a way to get her ConnectionScope. The standard way to get a Connection is a DataSource that will usually have a connection pool like HikariDb behind it. But the main problem with Connection and every other resource we use is that we need to remember to close it. Fortunately enough, we got Autocloseable long ago and its a bit easier. But you can still forget to use try-with-resources. So (inspired by the idea of Resource in Cats or Arrow) let’s try to build a simple, specific API to use connections without having to remember to close them. And let’s inject a DataSource to that function by injecing it to the class where the method is:\n\npublic final class Jdbc {\n\n  private final DataSource dataSource;\n\n  public Jdbc(DataSource dataSource) {\n    this.dataSource = dataSource;\n  }\n\n  public &lt;A&gt; A withConnection(Function1&lt;Connection, A&gt; f) {\n    try (Connection conn = dataSource.getConnection()) {\n      return f.apply(new ConnectionScope(conn));\n    }\n  }\n}\n\n\nThat way we can add other operations to Jdbc that use the very same DataSource, likeI could have used withConnection instead of duplicating the try-with-resources here.:\n\npublic &lt;A&gt; A inTransaction(Function&lt;ConnectionScope, A&gt; f) {\n  try (Connection conn = dataSource.getConnection()) {\n    conn.setAutoCommit(false);\n    var res = f.apply(new ConnectionScope(conn));\n    conn.commit();\n    return res;\n  } \n}\n\n\nNice, huh?\n\nDealing with SQLException\n\nWell, I’m not being totally honest with you…\n\n\n\nNo, you can’t call dataSource.getConnection() in your withConnection method because it throws the checked (and dreaded) exception SQLException. You need to either declare to also throw it or deal with it.\n\nBut the truth is I hate SQLException to be checked. Unless you know how to deal with them, exceptions should be unchecked. And:\n\n\n  There are very few occasions in which I actually deal with an exception thrown by Jdbc.\n  On those rare ocassions, I don’t actually know how to deal with it. Let’s say I want to handle duplicate key on insert? I Google that. And last time I tried (which I do every now and then) there is no standard way to do it. So you need to check some database vendor specific error code. Ugly.\n\n\nThis being just a litle game, I will simply embed that ugly exception in a RuntimeException and call it a day. If I ever want to recover from a duplicate key or something else I’ll go and figure out a solution. Future problem, YAGNI, KISS, etc I could use any other error handling mechanism (like an error monad), but I need this to be familiar to most Java programmers. So I’ll keep it simple familiar..\n\nSo:\n\npublic &lt;A&gt; A withConnection(Function&lt;Connection, A&gt; f) {\n  try (Connection conn = dataSource.getConnection()) {\n    return f.apply(new ConnectionScope(conn));\n  } catch (SQLException e) {\n    throw new RuntimeException(e);\n  }\n}\n\n\nThe very same happens when you call not only getConnection but also setAutocommit in inTransaction. So…\n\n  public &lt;A&gt; A inTransaction(Function&lt;ConnectionScope, A&gt; f) {\n    try (Connection conn = dataSource.getConnection()) {\n      conn.setAutoCommit(false);\n      var res = f.apply(new ConnectionScope(conn));\n      conn.commit();\n      return res;\n    } catch (SQLException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n\nThat may be starting to get unpleasant. DRY apart, I don’t like the verbose nature of try..catch. But let’s live with it. After all, this try...catch boilerplate is one Alt+Enter away in my IntelliJ. And we don’t have that many of those.\n\nNow our users can…\n\nvar jdbc = new Jdbc(dataSource);\nvar users = jdbc.inTransaction((tx) -&gt; ...use the ConnectionScope...));\n\n\nSelecting things\n\nLet’s get that one done. It’s something like…:\n\npublic class ConnectionScope {\n  private final Connection connection;\n\n  public &lt;A&gt; List&lt;A&gt; select(String sql, RowReader&lt;A&gt; reader, Object... params) {\n    try (var stmt = connection.prepareStatement(sql)) {\n      for (int i = 0; i &lt; params.length; i++) stmt.setObject(i + 1, params[i]);\n      try (var rs = stmt.executeQuery()) {\n        var res = new LinkedList&lt;A&gt;();\n       \tvar rsv = new ResultSetView(rs):\n        while (rs.next()) {\n          res.add(reader.apply(rsv));\n        }\n        return Collections.unmodifiableList(res);\n      }\n    } catch (SQLException ex) {\n      throw new RuntimeException(ex);\n    }\n  }\n  ...\n}\n\n\nDon’t worry about that RowReader&lt;A&gt; thing for a moment. I’m covering it later.\n\nSome notes here, just in case you are new to Jdbc or too old to remember that:\n\n\n  Yes, Connection needs to be closed. And PreparedStatement, and ResultSet need to be closed too. At least they are Autocloseable and they caused some of my first professional nightmares back in the 1990’s. So, I’ll close each of them.\n  You are using PreparedStatement.setXXX methods like I do here, right? Tell me you are not injecting values into the SQL query by concatenating Strings!\n  I return an unmodifiableList because this is as close as I can get to an immutable colleciton in the standard library. Not that it matters a lot here, since I’m returning a freshly created instance every time. But, you know, the older I get, the less I want to reason about mutability.\n\n\nParameters\n\nDid you see that ugly Object type? A signal of a disaster coming after me here… There are a thousand (painful) reasons I’m averse to things that could fail at compile time but fail at runtime. Did you say select(\"...\", ..., user1) and user1 is an instance of User, a class with 4 fields in it? No way. stmt.setObject won’t probably like that.\n\nSo let’s typesafe that. How? Ok, here is the (hopefully) cool idea I came with some time ago and I keep using everywhere I want some casual Jdbc:\n\n\n  A value is a valid argument for a PreparedStatement if its of a type X such that the API of PreparedStatement has a method void setX(int parameterIndex, X x). Boolean? Check! URL? Wut? Yes. User? Nope.\n  So any pair of a value of type X and one such method of a PreparedStatement would be a valid argument value. Why? Because the existence of such a method in PreparedStatement  proves… well, that we will be able to set the parameter value in the statement.\n  Let’s encode that idea. A  method  void setX(int parameterIndex, X x) in PreparedStatementcan be seen as a java.util.function.Consumer but with 3 parameters: TriConsumer&lt;PreparedStatement,Integer,X&gt; (a function from these 3 types to void)… Except Java has no TriConsumerclass. If it had one we could model, for example, Integer parameters as: If you are frowning at setInt  used with Integer… I know. I didn’t remember. Keep reading and I’ll fix it later.\n\n\npublic class IntParam{\n  private final Consumer3&lt;PreparedStatement, Integer, Integer&gt; \n    preparedStatementSetter;\n  private final Integer value;\n\n  public IntParam(Integer value){\n    this.preparedStatementSetter = PreparedStatement::setInt;\n    this.value = value;\n  }\n}\n\n\n\n  But… a pair of  TriConsumer&lt;PreparedStatement,Integer,X&gt; and a value of type X can be converted by currying the function. That is, we create a BiConsumer&lt;PreparedStatement, Integer&gt; where the third argument (of type X) is whatever value we wanted to set as a parameter:\n\n\npublic class IntParam{\n  private final BiConsumer&lt;PreparedStatement, Integer&gt; preparedStatementSetter;\n\n  public IntParam(Integer value){\n    this.preparedStatementSetter = (ps, index) -&gt; ps.setInt(index, value);\n  }\n}\n\n\n\n  And now, IntParam only needs the Integer value in its constructor and can be abstracted. If we squint, we can model that as an abstract class with one single method that, in fact, does not depend on Integer at all:\n\n\npublic abstract class Param {\n  // Define aan abstract method instead of a Consumer\n  public abstract void set(PreparedStatement ps, int column);\n}\n\n\n\n  Now that we no longer have a constructor, we need a function that, given a value, creates instances of Param. We could create a subclass for each type we support, but simply creating anonymous instances is easier:\n\n\npublic Param integerParam(Integer value) {\n  return new Param() {\n    public void set(PreparedStatement ps, int column){\n      ps.setInt(column, value);\n    }\n  };\n}\n\n\n\n  Finally, an abstract class with just one method… fits perfectly the idea of FunctionalInterface::\n\n\n@FunctionalInterface\npublic interface Param {\n  void set(PreparedStatement ps, int i)\n}\n\n\nNow I simply need more functions that, given a value, return an instance of  Param. And they will use a lambda to create the resulting instance.\n\nstatic Param p(Integer value) {\n  return (ps, i) -&gt; ps.setInt(i, value);\n}\n\nstatic Param p(String value) {\n  return (ps, i) -&gt; ps.setString(i, value);\n}\n\n\nI named all such funtions p so that the compiler, and not our user, gets to choose which one applies to the given parameter type. And all of a sudden my beloved user doesn’t need to remember what function to call, but just try p(x) for any x she wants passed as argument and only care about it if the compiler (rightfully) complains to not have any function p that takes values of such type as a parameter.\n\nNow our select function can use the Param instance to set the parameter in a typesafe way:\n\n  public &lt;A&gt; List&lt;A&gt; select(String sql, RowReader&lt;A&gt; reader, Param... params) {\n    try (var stmt = connection.prepareStatement(sql)) {\n      for (int i = 0; i &lt; params.length; i++) params[i].set(stmt, i + 1);\n      ...\n    }\n  }\n\n\nDealing with SQLException redux\n\nEverything is nice and fine. Except, of course, I’m lying. Again.\n\n\n\nNaturally, I could surrond every sinlge invocation of setXxxx methods with try...catch. But you know how many setXxx methods are there in PreparedStatement? 50. I counted them. I’ve been told DRY is abused often. But I’m not writing 6 extra lines of try...catch (including its braces) multiplied by 49 more times. Enough is enough.\n\nBut this time the solution is actually simple. Although BiConsumer can’t represent anything that throws checked exceptions, let’s simply admit our Param functional interface can throw SQLExceptions and, all of a sudden, you can use lambdas like there were no exceptions to be seen.\n\nJedi stuff. These aren’t the exceptions you are looking for.\n\n\n@FunctionalInterface\npublic interface Param {\n  void set(PreparedStatement ps, int i) throws SQLException;\n\n  static Param p(Integer value) {\n    return (ps, i) -&gt; ps.setInt(i, value);\n  }\n}\n\n\nIt may be no rocket science if you are really used to (modern-ish) Java. But in my opinion it shows the smarts of the designers of Java. setInt throws SQLException but it can be written in a Lambda because the FunctionalInterface you expect to return (Param) already declares the function to throw SQLException.\n\nNulls and autounboxing\n\nI’m just writing about the design and implementation of this toy library. But I’m fond of testing and, yes, I’m also testing it. So I’ve found a bug caused by my years away from Java.\n\nDid you spot it already? It is here:\n\nstatic Param p(Integer value) {\n  return (ps, i) -&gt; ps.setInt(i, value);\n}\n\n\nDid you guess it? Yes, ps.setInt takes an int value. When you pass an Integer value, it auto-unboxes. And if the value was null… Kaboom! NullPointerException. I could rewrite the previous section with String as the example and pretend I never did the mistake. But let’s be honest here. I did it. And now I’m fixing it:\n\nstatic Param p(final Integer value) {\n  return (ps, i) -&gt; ps.setObject(i, value, Types.INTEGER);\n}\n\nstatic Param p(final int value) {\n  return (ps, i) -&gt; ps.setInt(i, value);\n}\n\n\nReading rows\n\nLast… and, for once, possibly least. We want our user to read the rows in a ResultSet in such a way that:\n\n\n  She can’t possibly forget to close the ResultSet\n  She can’t possibly try to use the ResultSet after the Connection was closed (probably returned to the pool)\n  She does not need to worry about advancing the cursor with next()\n  She does not need to deal with primitive types and wasNull() (assuming we can live with wrapping every primitive value in nullable columns)\n\n\nFor that, we are asking our user to provide a lambda that we will execute to read each row. As we don’t want her to mess with next() we will handle her a trimmed-down ResultSet where she can only get results but not move the cursor. That class can also facilitate things when she deals with nulls and wrapper types:\n\npublic class ResultSetView {\n\n  private final ResultSet resultSet;\n  public ResultSetView(ResultSet resultSet) {\n    this.resultSet = resultSet;\n  }\n  \n  public String getString(int column) throws SQLException {\n      return resultSet.getString(column);\n  }\n  \n  public Boolean getBoolean(int column) throws SQLException{\n    var res = resultSet.getBoolean(column);\n    return resultSet.wasNull() ? null : res;\n  }\n  \n  public boolean getBool(int column) throws SQLException{\n    var res = resultSet.getBoolean(column);\n    if(resultSet.wasNull()) throw new NullPointerException(\"Column \" + column + \" is null\");\n    return res;\n  }\n  \n  ...\n}\n\n\nSelecting things, the final implementation\n\nFinally, we can close the loop:\n\nclass ConnectionScope {\n  ...\n  public &lt;A&gt; List&lt;A&gt; select(String sql, RowReader&lt;A&gt; reader, Param... params) {\n    try (var stmt = connection.prepareStatement(sql)) {\n      for (int i = 0; i &lt; params.length; i++) params[i].set(stmt, i + 1);\n      try (var rs = stmt.executeQuery()) {\n        var rsView = new ResultSetView(rs);\n        var res = new LinkedList&lt;A&gt;();\n        while (rs.next()) {\n          res.add(reader.apply(rsView));\n        }\n        return Collections.unmodifiableList(res);\n      }\n    } catch (SQLException ex) {\n      throw new RuntimeException(ex);\n    }\n  }\n}\n\n@FunctionalInterface\npublic interface RowReader&lt;A&gt; {\n  A apply(ResultSetView rs) throws SQLException;\n}\n\n\nSo, same Jedi trick here: RowReader is a functional interface that declares to throw SQLException. So users of select can simply pass a lambda whose contents throw SQLException happily. Which is what our getXxx methods in ResultSetView do:\n\nList&lt;User&gt;  users = tx.select(\n  \"select u.id, u.name, u.surname from users u \" +\n  \"where active = true amd u.role = ?\",\n  (rs) -&gt; new User(rs.getString(1), rs.getString(2), rs.getString(3)),\n  p(role)\n);\n\n\nSupport for differnt types\n\nOnce your users are using Param instead of PreparedStatement.setXxxx and  ResultSetView instead of ResultSet, you now can extends the capabilities of Jdbc with new types. In particular, I’ve always found Jdbc’s lack of support for Instant and java.net.URI disturbing, just to mention a couple examples:\n\n@FunctionalInterface\npublic interface Param {\n  ...\n  static Param p(URI value) {\n    return (ps, i) -&gt; ps.setString(i, value.toString());\n  }\n  static Param p(Instant value) {\n    return (ps, i) -&gt; ps.setTimestamp(i, java.sql.Timestamp.from(value));\n  }\n}\n\npublic class ResultSetView {\n\t...\n\tpublic URI getURI(int column) throws SQLException {\n    var res = resultSet.getString(column);\n    return res == null ? null : URI.create(res);\n  }\n  public Instant getInstant(int column) throws SQLException {\n    var res = resultSet.getTimestamp(column);\n    return res == null ? null : res.toInstant();\n  }\n}\n\n\nFurther than that, you can hide (by omiting them from your implementation), those types you don’t want your users to use directly. As an example, let’s say you have your issues with URL. You encourage your users to not use it by not implementing the p and getUrl methods.\n\nOther select and update methods\n\nOf course, I just implemented a couple simple methods that use Jdbc in some particular ways. But you can implement any other common usage of the api in order to simplify the scenarios you and your team use the most.\n\nLet’s see an example. Let’s say your database generates a surrogate key whenever you insert a new row in a given table. Do you know how to perform a Jdbc insert and get the generated key? It was something like:\n\npublic &lt;K&gt; K insertAndGetKey(String sql, RowReader&lt;K&gt; keyReader,  Param... params) {\n  try (var stmt = connection.prepareStatement(sql, RETURN_GENERATED_KEYS)) {\n    for (int i = 0; i &lt; params.length; i++) params[i].set(stmt, i + 1);\n    stmt.executeUpdate();\n    try(var keys = stmt.getGeneratedKeys()){\n      keys.next();\n      return keyReader.apply(new ResultSetView(keys));\n    }\n  } catch (SQLException ex) {\n    throw new RuntimeException(ex);\n  }\n}\n\n\nSo, one nice thing of our abstraction is that you can create a mehod for each typical use case. Once your users will use by simply providing lambdas for the parts they are interested in. It reminds me of the template pattern, if you want. But it is simpler with lambdas.\n\nRecap\n\nWe developed a small, lightway Jdbc helper library that:\n\n\n  Is under 300 lines of code, supporting many of the types supported by Jdbc. Probably under 500 lines if it supported all (the desirable) ones.\n  Is user friendly: easy to learn, typesafe, uniform (e.g. all parameters are passed the same)\n  Appropiately deals with null while reading / writing columns\n  Encodes correct Jdbc usage patterns. e.g. Users can’t forget to close Connection, PreparedStatement or ResultSet\n  Is extensible to more methods that use Jdbc in different ways (and encodes them as easy to use templates).\n  Is extensible to types not directly supported by Jdbc so that we don’t repeat the needed transformations everywhere (e.g. Instant or URI columns or parameters)\n  Can hide dangerous / unwanted Jdbc features (e.g. java.sql.Date, java.sql.Time or  java.net.URL columns or parameters)\n\n",
            "content_html": "<p>This time I’m in the mood for playing a bit with my good old friend Java. While preparing a kata for my students I wanted some <strong>simple</strong> database access library they could use without previous knowledge or experience. I could have looked at many alternatives, but I really wanted something simple.</p>\n\n<p>Simple <em class=\"sidenote-number\">like</em> <em class=\"sidenote\">I’m assuming Java 11 or later here. As a reminder, 11 is the LTS that was released on 09/2018 and is planned to be supported through 2026. I will mostly need lambdas (which are around since Java 8, released on 3/2014 and supported through at least 2030).  You’ll see <code class=\"language-plaintext highlighter-rouge\">var</code>s as well, which would require Java 11 (counting only LTSs), but they are easy to replace with their corresponding types if you are stuck with Java 8.</em>:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">List</span><span class=\"o\">&lt;</span><span class=\"nc\">User</span><span class=\"o\">&gt;</span>  <span class=\"n\">users</span> <span class=\"o\">=</span> <span class=\"n\">tx</span><span class=\"o\">.</span><span class=\"na\">select</span><span class=\"o\">(</span>\n  <span class=\"s\">\"select u.id, u.name, u.surname from users u \"</span> <span class=\"o\">+</span>\n  <span class=\"s\">\"where u.active = true amd u.role = ?\"</span><span class=\"o\">,</span>\n  <span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"k\">new</span> <span class=\"nc\">User</span><span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"mi\">1</span><span class=\"o\">),</span> <span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"mi\">2</span><span class=\"o\">),</span> <span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"mi\">3</span><span class=\"o\">)),</span>\n  <span class=\"n\">p</span><span class=\"o\">(</span><span class=\"s\">\"student\"</span><span class=\"o\">)</span> <span class=\"c1\">// The parameter value for the ? in the query</span>\n<span class=\"o\">);</span>\n</code></pre></div></div>\n\n<p>Summarizing the idea:</p>\n\n<ol>\n  <li>The user writes Plain Old Sql (pos? posql?) her database will parse, interpret and execute. Not a fancy DSL hopefully translated to the correct sql her database wants.</li>\n  <li>The user writes a lambda to tell the library how each row is read. She does not need to handle <code class=\"language-plaintext highlighter-rouge\">ResultSet.next()</code>, so there is no way she can fail to do so correctly.</li>\n  <li>The user passes arguments in a vararg with <code class=\"language-plaintext highlighter-rouge\">p(xxx)</code> for any admissible value <code class=\"language-plaintext highlighter-rouge\">xxx</code> where <em>admissible</em> means it must be a value of a type supported by the library.</li>\n</ol>\n\n<p>I’ve used this very same approach with Scala (I admit some implicits where used there) and Kotlin (look, ma! no implicits!). So let’s try my hand at Java.</p>\n\n<p>Under the hood I’m using Jdbc. Yes, it blocks threads, but that may be solved sooner than anyone expected. And it throws ugly checked exceptions we will need to deal with. In fact, it very poorly handles errors in a non standard way. But other than that, it is fine and very well known.</p>\n\n<h2 id=\"connections-and-datasources\">Connections and DataSources</h2>\n\n<p>The functions I will offer (like <code class=\"language-plaintext highlighter-rouge\">select</code>, <code class=\"language-plaintext highlighter-rouge\">selectOne</code>, <code class=\"language-plaintext highlighter-rouge\">update</code>, etc.) will need a <code class=\"language-plaintext highlighter-rouge\">Connection</code>. As per Jdbc itself, we need to be able to use the same <code class=\"language-plaintext highlighter-rouge\">Connection</code> to invoke several database operations in a given transaction. So let’s use dependency injection! I could simply add a parameter to every funciton needing a <code class=\"language-plaintext highlighter-rouge\">Connection</code>, but I prefer to create a class to represent the scope of a connection, a class where those fancy operations will live.</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"kd\">class</span> <span class=\"nc\">ConnectionScope</span> <span class=\"o\">{</span>\n  <span class=\"kd\">private</span> <span class=\"kd\">final</span> <span class=\"nc\">Connection</span> <span class=\"n\">connection</span><span class=\"o\">;</span>\n\n  <span class=\"kd\">public</span> <span class=\"nf\">ConnectionScope</span><span class=\"o\">(</span><span class=\"nc\">Connection</span> <span class=\"n\">connection</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">this</span><span class=\"o\">.</span><span class=\"na\">connection</span> <span class=\"o\">=</span> <span class=\"n\">connection</span><span class=\"o\">;</span>\n  <span class=\"o\">}</span>\n\n  <span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nc\">List</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nf\">select</span><span class=\"o\">(</span><span class=\"nc\">String</span> <span class=\"n\">sql</span><span class=\"o\">,</span> <span class=\"nc\">RowReader</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">reader</span><span class=\"o\">,</span> <span class=\"nc\">Param</span><span class=\"o\">...</span> <span class=\"n\">params</span><span class=\"o\">)</span> <span class=\"o\">{...}</span>\n  <span class=\"kd\">public</span> <span class=\"kt\">int</span> <span class=\"nf\">update</span><span class=\"o\">(</span><span class=\"nc\">String</span> <span class=\"n\">sql</span><span class=\"o\">,</span> <span class=\"nc\">Param</span><span class=\"o\">...</span> <span class=\"n\">params</span><span class=\"o\">)</span> <span class=\"o\">{...}</span>\n  <span class=\"o\">...</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>So now our beloved user needs a way to get her <code class=\"language-plaintext highlighter-rouge\">ConnectionScope</code>. The standard way to get a <code class=\"language-plaintext highlighter-rouge\">Connection</code> is a <code class=\"language-plaintext highlighter-rouge\">DataSource</code> that will usually have a connection pool like <a href=\"https://github.com/brettwooldridge/HikariCP\">HikariDb</a> behind it. But the main problem with <code class=\"language-plaintext highlighter-rouge\">Connection</code> and every other resource we use is that we need to remember to <code class=\"language-plaintext highlighter-rouge\">close</code> it. Fortunately enough, we got <code class=\"language-plaintext highlighter-rouge\">Autocloseable</code> long ago and its a bit easier. But you can still forget to use try-with-resources. So (inspired by the idea of <code class=\"language-plaintext highlighter-rouge\">Resource</code> in <a href=\"https://typelevel.org/cats-effect/docs/std/resource\">Cats</a> or <a href=\"https://arrow-kt.io/docs/apidocs/arrow-fx-coroutines/arrow.fx.coroutines/-resource/\">Arrow</a>) let’s try to build a simple, specific API to use connections without having to remember to close them. And let’s inject a <code class=\"language-plaintext highlighter-rouge\">DataSource</code> to that function by injecing it to the class where the method is:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"kd\">final</span> <span class=\"kd\">class</span> <span class=\"nc\">Jdbc</span> <span class=\"o\">{</span>\n\n  <span class=\"kd\">private</span> <span class=\"kd\">final</span> <span class=\"nc\">DataSource</span> <span class=\"n\">dataSource</span><span class=\"o\">;</span>\n\n  <span class=\"kd\">public</span> <span class=\"nf\">Jdbc</span><span class=\"o\">(</span><span class=\"nc\">DataSource</span> <span class=\"n\">dataSource</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">this</span><span class=\"o\">.</span><span class=\"na\">dataSource</span> <span class=\"o\">=</span> <span class=\"n\">dataSource</span><span class=\"o\">;</span>\n  <span class=\"o\">}</span>\n\n  <span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"no\">A</span> <span class=\"nf\">withConnection</span><span class=\"o\">(</span><span class=\"nc\">Function1</span><span class=\"o\">&lt;</span><span class=\"nc\">Connection</span><span class=\"o\">,</span> <span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">f</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"nc\">Connection</span> <span class=\"n\">conn</span> <span class=\"o\">=</span> <span class=\"n\">dataSource</span><span class=\"o\">.</span><span class=\"na\">getConnection</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n      <span class=\"k\">return</span> <span class=\"n\">f</span><span class=\"o\">.</span><span class=\"na\">apply</span><span class=\"o\">(</span><span class=\"k\">new</span> <span class=\"nc\">ConnectionScope</span><span class=\"o\">(</span><span class=\"n\">conn</span><span class=\"o\">));</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>That way we can add other operations to <code class=\"language-plaintext highlighter-rouge\">Jdbc</code> that use the very same <code class=\"language-plaintext highlighter-rouge\">DataSource</code>, <em class=\"sidenote-number\">like</em><em class=\"sidenote\">I could have used <code class=\"language-plaintext highlighter-rouge\">withConnection</code> instead of duplicating the <code class=\"language-plaintext highlighter-rouge\">try-with-resources</code> here.</em>:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"no\">A</span> <span class=\"nf\">inTransaction</span><span class=\"o\">(</span><span class=\"nc\">Function</span><span class=\"o\">&lt;</span><span class=\"nc\">ConnectionScope</span><span class=\"o\">,</span> <span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">f</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"nc\">Connection</span> <span class=\"n\">conn</span> <span class=\"o\">=</span> <span class=\"n\">dataSource</span><span class=\"o\">.</span><span class=\"na\">getConnection</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n    <span class=\"n\">conn</span><span class=\"o\">.</span><span class=\"na\">setAutoCommit</span><span class=\"o\">(</span><span class=\"kc\">false</span><span class=\"o\">);</span>\n    <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"n\">f</span><span class=\"o\">.</span><span class=\"na\">apply</span><span class=\"o\">(</span><span class=\"k\">new</span> <span class=\"nc\">ConnectionScope</span><span class=\"o\">(</span><span class=\"n\">conn</span><span class=\"o\">));</span>\n    <span class=\"n\">conn</span><span class=\"o\">.</span><span class=\"na\">commit</span><span class=\"o\">();</span>\n    <span class=\"k\">return</span> <span class=\"n\">res</span><span class=\"o\">;</span>\n  <span class=\"o\">}</span> \n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>Nice, huh?</p>\n\n<h2 id=\"dealing-with-sqlexception\">Dealing with SQLException</h2>\n\n<p>Well, I’m not being totally honest with you…</p>\n\n<p><img src=\"../assets/psGetConnectionThrows.png\" alt=\"image-20230303173817429\" style=\"zoom:50%;\" /></p>\n\n<p>No, you can’t call <code class=\"language-plaintext highlighter-rouge\">dataSource.getConnection()</code> in your <code class=\"language-plaintext highlighter-rouge\">withConnection</code> method because it throws the checked (and dreaded) exception <code class=\"language-plaintext highlighter-rouge\">SQLException</code>. You need to either declare to also throw it or deal with it.</p>\n\n<p>But the truth is I hate <code class=\"language-plaintext highlighter-rouge\">SQLException</code> to be checked. Unless you know how to deal with them, exceptions should be unchecked. And:</p>\n\n<ol>\n  <li>There are very few occasions in which I actually deal with an exception thrown by Jdbc.</li>\n  <li>On those rare ocassions, I don’t actually know how to deal with it. Let’s say I want to handle duplicate key on insert? I Google that. And last time I tried (which I do every now and then) there is no standard way to do it. So you need to check some database vendor specific error code. Ugly.</li>\n</ol>\n\n<p>This being just a litle game, I will simply embed that ugly exception in a <code class=\"language-plaintext highlighter-rouge\">RuntimeException</code> and call it a day. If I ever want to recover from a duplicate key or something else I’ll go and figure out a solution. Future problem, YAGNI, KISS, <em class=\"sidenote-number\">etc</em> <em class=\"sidenote\">I could use any other error handling mechanism (like an error monad), but I need this to be familiar to most Java programmers. So I’ll keep it <del>simple</del> <ins>familiar</ins>.</em>.</p>\n\n<p>So:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"no\">A</span> <span class=\"nf\">withConnection</span><span class=\"o\">(</span><span class=\"nc\">Function</span><span class=\"o\">&lt;</span><span class=\"nc\">Connection</span><span class=\"o\">,</span> <span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">f</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"nc\">Connection</span> <span class=\"n\">conn</span> <span class=\"o\">=</span> <span class=\"n\">dataSource</span><span class=\"o\">.</span><span class=\"na\">getConnection</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n    <span class=\"k\">return</span> <span class=\"n\">f</span><span class=\"o\">.</span><span class=\"na\">apply</span><span class=\"o\">(</span><span class=\"k\">new</span> <span class=\"nc\">ConnectionScope</span><span class=\"o\">(</span><span class=\"n\">conn</span><span class=\"o\">));</span>\n  <span class=\"o\">}</span> <span class=\"k\">catch</span> <span class=\"o\">(</span><span class=\"nc\">SQLException</span> <span class=\"n\">e</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nf\">RuntimeException</span><span class=\"o\">(</span><span class=\"n\">e</span><span class=\"o\">);</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>The very same happens when you call not only <code class=\"language-plaintext highlighter-rouge\">getConnection</code> but also <code class=\"language-plaintext highlighter-rouge\">setAutocommit</code> in <code class=\"language-plaintext highlighter-rouge\">inTransaction</code>. So…</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>  <span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"no\">A</span> <span class=\"nf\">inTransaction</span><span class=\"o\">(</span><span class=\"nc\">Function</span><span class=\"o\">&lt;</span><span class=\"nc\">ConnectionScope</span><span class=\"o\">,</span> <span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">f</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"nc\">Connection</span> <span class=\"n\">conn</span> <span class=\"o\">=</span> <span class=\"n\">dataSource</span><span class=\"o\">.</span><span class=\"na\">getConnection</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n      <span class=\"n\">conn</span><span class=\"o\">.</span><span class=\"na\">setAutoCommit</span><span class=\"o\">(</span><span class=\"kc\">false</span><span class=\"o\">);</span>\n      <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"n\">f</span><span class=\"o\">.</span><span class=\"na\">apply</span><span class=\"o\">(</span><span class=\"k\">new</span> <span class=\"nc\">ConnectionScope</span><span class=\"o\">(</span><span class=\"n\">conn</span><span class=\"o\">));</span>\n      <span class=\"n\">conn</span><span class=\"o\">.</span><span class=\"na\">commit</span><span class=\"o\">();</span>\n      <span class=\"k\">return</span> <span class=\"n\">res</span><span class=\"o\">;</span>\n    <span class=\"o\">}</span> <span class=\"k\">catch</span> <span class=\"o\">(</span><span class=\"nc\">SQLException</span> <span class=\"n\">e</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n      <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nf\">RuntimeException</span><span class=\"o\">(</span><span class=\"n\">e</span><span class=\"o\">);</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>That may be starting to get unpleasant. DRY apart, I don’t like the verbose nature of <code class=\"language-plaintext highlighter-rouge\">try..catch</code>. But let’s live with it. After all, this <code class=\"language-plaintext highlighter-rouge\">try...catch</code> boilerplate is one <code class=\"language-plaintext highlighter-rouge\">Alt+Enter</code> away in my IntelliJ. And we don’t have that many of those.</p>\n\n<p>Now our users can…</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kt\">var</span> <span class=\"n\">jdbc</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nc\">Jdbc</span><span class=\"o\">(</span><span class=\"n\">dataSource</span><span class=\"o\">);</span>\n<span class=\"kt\">var</span> <span class=\"n\">users</span> <span class=\"o\">=</span> <span class=\"n\">jdbc</span><span class=\"o\">.</span><span class=\"na\">inTransaction</span><span class=\"o\">((</span><span class=\"n\">tx</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"o\">...</span><span class=\"na\">use</span> <span class=\"n\">the</span> <span class=\"nc\">ConnectionScope</span><span class=\"o\">...));</span>\n</code></pre></div></div>\n\n<h2 id=\"selecting-things\">Selecting things</h2>\n\n<p>Let’s get that one done. It’s something like…:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"kd\">class</span> <span class=\"nc\">ConnectionScope</span> <span class=\"o\">{</span>\n  <span class=\"kd\">private</span> <span class=\"kd\">final</span> <span class=\"nc\">Connection</span> <span class=\"n\">connection</span><span class=\"o\">;</span>\n\n  <span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nc\">List</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nf\">select</span><span class=\"o\">(</span><span class=\"nc\">String</span> <span class=\"n\">sql</span><span class=\"o\">,</span> <span class=\"nc\">RowReader</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">reader</span><span class=\"o\">,</span> <span class=\"nc\">Object</span><span class=\"o\">...</span> <span class=\"n\">params</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"kt\">var</span> <span class=\"n\">stmt</span> <span class=\"o\">=</span> <span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"na\">prepareStatement</span><span class=\"o\">(</span><span class=\"n\">sql</span><span class=\"o\">))</span> <span class=\"o\">{</span>\n      <span class=\"k\">for</span> <span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"o\">;</span> <span class=\"n\">i</span> <span class=\"o\">&lt;</span> <span class=\"n\">params</span><span class=\"o\">.</span><span class=\"na\">length</span><span class=\"o\">;</span> <span class=\"n\">i</span><span class=\"o\">++)</span> <span class=\"n\">stmt</span><span class=\"o\">.</span><span class=\"na\">setObject</span><span class=\"o\">(</span><span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">,</span> <span class=\"n\">params</span><span class=\"o\">[</span><span class=\"n\">i</span><span class=\"o\">]);</span>\n      <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"kt\">var</span> <span class=\"n\">rs</span> <span class=\"o\">=</span> <span class=\"n\">stmt</span><span class=\"o\">.</span><span class=\"na\">executeQuery</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n        <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nc\">LinkedList</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;();</span>\n       \t<span class=\"kt\">var</span> <span class=\"n\">rsv</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nc\">ResultSetView</span><span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">):</span>\n        <span class=\"k\">while</span> <span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">next</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n          <span class=\"n\">res</span><span class=\"o\">.</span><span class=\"na\">add</span><span class=\"o\">(</span><span class=\"n\">reader</span><span class=\"o\">.</span><span class=\"na\">apply</span><span class=\"o\">(</span><span class=\"n\">rsv</span><span class=\"o\">));</span>\n        <span class=\"o\">}</span>\n        <span class=\"k\">return</span> <span class=\"nc\">Collections</span><span class=\"o\">.</span><span class=\"na\">unmodifiableList</span><span class=\"o\">(</span><span class=\"n\">res</span><span class=\"o\">);</span>\n      <span class=\"o\">}</span>\n    <span class=\"o\">}</span> <span class=\"k\">catch</span> <span class=\"o\">(</span><span class=\"nc\">SQLException</span> <span class=\"n\">ex</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n      <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nf\">RuntimeException</span><span class=\"o\">(</span><span class=\"n\">ex</span><span class=\"o\">);</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">}</span>\n  <span class=\"o\">...</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>Don’t worry about that <code class=\"language-plaintext highlighter-rouge\">RowReader&lt;A&gt;</code> thing for a moment. I’m covering it later.</p>\n\n<p>Some notes here, just in case you are new to Jdbc or too old to remember that:</p>\n\n<ol>\n  <li>Yes, <code class=\"language-plaintext highlighter-rouge\">Connection</code> needs to be closed. And <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code>, and <code class=\"language-plaintext highlighter-rouge\">ResultSet</code> need to be closed too. At least they are <code class=\"language-plaintext highlighter-rouge\">Autocloseable</code> and they caused some of my first professional nightmares back in the 1990’s. So, I’ll close each of them.</li>\n  <li>You are using <code class=\"language-plaintext highlighter-rouge\">PreparedStatement.setXXX</code> methods like I do here, right? <a href=\"https://en.wikipedia.org/wiki/SQL_injection\">Tell me you are not injecting values into the SQL query by concatenating Strings!</a></li>\n  <li>I return an <code class=\"language-plaintext highlighter-rouge\">unmodifiableList</code> because this is as close as I can get to an immutable colleciton in the standard library. Not that it matters a lot here, since I’m returning a freshly created instance every time. But, you know, the older I get, the less I want to reason about mutability.</li>\n</ol>\n\n<h2 id=\"parameters\">Parameters</h2>\n\n<p>Did you see that ugly <code class=\"language-plaintext highlighter-rouge\">Object</code> type? A signal of a disaster coming after me here… There are a thousand (painful) reasons I’m averse to things that could fail at compile time but fail at runtime. Did you say <code class=\"language-plaintext highlighter-rouge\">select(\"...\", ..., user1)</code> and <code class=\"language-plaintext highlighter-rouge\">user1</code> is an instance of <code class=\"language-plaintext highlighter-rouge\">User</code>, a class with 4 fields in it? No way. <code class=\"language-plaintext highlighter-rouge\">stmt.setObject</code> won’t probably like that.</p>\n\n<p>So let’s typesafe that. How? Ok, here is the (hopefully) cool idea I came with some time ago and I keep using everywhere I want some casual Jdbc:</p>\n\n<ul>\n  <li>A value is a valid argument for a <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code> if its of a type <code class=\"language-plaintext highlighter-rouge\">X </code>such that the API of <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code> has a method <code class=\"language-plaintext highlighter-rouge\">void setX(int parameterIndex, X x)</code>. Boolean? Check! URL? <a href=\"https://rules.sonarsource.com/java/RSPEC-2112\">Wut</a>? Yes. <code class=\"language-plaintext highlighter-rouge\">User</code>? Nope.</li>\n  <li>So any pair of a value of type X and one such method of a <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code> would be a valid argument value. Why? Because the existence of such a method in <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code>  proves… well, that we will be able to set the parameter value in the statement.</li>\n  <li>Let’s encode that idea. A  method  <code class=\"language-plaintext highlighter-rouge\">void setX(int parameterIndex, X x)</code> in <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code>can be seen as a <code class=\"language-plaintext highlighter-rouge\">java.util.function.Consumer</code> but with 3 parameters: <code class=\"language-plaintext highlighter-rouge\">TriConsumer&lt;PreparedStatement,Integer,X&gt;</code> (a function from these 3 types to void)… Except Java has no <code class=\"language-plaintext highlighter-rouge\">TriConsumer</code>class. If it had one we could model, for example, <code class=\"language-plaintext highlighter-rouge\">Integer</code> parameters <span class=\"sidenote-number\">as:</span> <em class=\"sidenote\">If you are frowning at <code class=\"language-plaintext highlighter-rouge\">setInt</code>  used with <code class=\"language-plaintext highlighter-rouge\">Integer</code>… I know. I didn’t remember. Keep reading and I’ll fix it later.</em></li>\n</ul>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"kd\">class</span> <span class=\"nc\">IntParam</span><span class=\"o\">{</span>\n  <span class=\"kd\">private</span> <span class=\"kd\">final</span> <span class=\"nc\">Consumer3</span><span class=\"o\">&lt;</span><span class=\"nc\">PreparedStatement</span><span class=\"o\">,</span> <span class=\"nc\">Integer</span><span class=\"o\">,</span> <span class=\"nc\">Integer</span><span class=\"o\">&gt;</span> \n    <span class=\"n\">preparedStatementSetter</span><span class=\"o\">;</span>\n  <span class=\"kd\">private</span> <span class=\"kd\">final</span> <span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">;</span>\n\n  <span class=\"kd\">public</span> <span class=\"nf\">IntParam</span><span class=\"o\">(</span><span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">){</span>\n    <span class=\"k\">this</span><span class=\"o\">.</span><span class=\"na\">preparedStatementSetter</span> <span class=\"o\">=</span> <span class=\"nl\">PreparedStatement:</span><span class=\"o\">:</span><span class=\"n\">setInt</span><span class=\"o\">;</span>\n    <span class=\"k\">this</span><span class=\"o\">.</span><span class=\"na\">value</span> <span class=\"o\">=</span> <span class=\"n\">value</span><span class=\"o\">;</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<ul>\n  <li>But… a pair of  <code class=\"language-plaintext highlighter-rouge\">TriConsumer&lt;PreparedStatement,Integer,X&gt;</code> and a value of type <code class=\"language-plaintext highlighter-rouge\">X</code> can be converted by currying the function. That is, we create a <code class=\"language-plaintext highlighter-rouge\">BiConsumer&lt;PreparedStatement, Integer&gt;</code> where the third argument (of type X) is whatever value we wanted to set as a parameter:</li>\n</ul>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"kd\">class</span> <span class=\"nc\">IntParam</span><span class=\"o\">{</span>\n  <span class=\"kd\">private</span> <span class=\"kd\">final</span> <span class=\"nc\">BiConsumer</span><span class=\"o\">&lt;</span><span class=\"nc\">PreparedStatement</span><span class=\"o\">,</span> <span class=\"nc\">Integer</span><span class=\"o\">&gt;</span> <span class=\"n\">preparedStatementSetter</span><span class=\"o\">;</span>\n\n  <span class=\"kd\">public</span> <span class=\"nf\">IntParam</span><span class=\"o\">(</span><span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">){</span>\n    <span class=\"k\">this</span><span class=\"o\">.</span><span class=\"na\">preparedStatementSetter</span> <span class=\"o\">=</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">index</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setInt</span><span class=\"o\">(</span><span class=\"n\">index</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">);</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<ul>\n  <li>And now, IntParam only needs the <code class=\"language-plaintext highlighter-rouge\">Integer</code> value in its constructor and can be abstracted. If we squint, we can model that as an abstract class with one single method that, in fact, does not depend on <code class=\"language-plaintext highlighter-rouge\">Integer</code> at all:</li>\n</ul>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"kd\">abstract</span> <span class=\"kd\">class</span> <span class=\"nc\">Param</span> <span class=\"o\">{</span>\n  <span class=\"c1\">// Define aan abstract method instead of a Consumer</span>\n  <span class=\"kd\">public</span> <span class=\"kd\">abstract</span> <span class=\"kt\">void</span> <span class=\"nf\">set</span><span class=\"o\">(</span><span class=\"nc\">PreparedStatement</span> <span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"kt\">int</span> <span class=\"n\">column</span><span class=\"o\">);</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<ul>\n  <li>Now that we no longer have a constructor, we need a function that, given a value, creates instances of <code class=\"language-plaintext highlighter-rouge\">Param</code>. We could create a subclass for each type we support, but simply creating anonymous instances is easier:</li>\n</ul>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"nc\">Param</span> <span class=\"nf\">integerParam</span><span class=\"o\">(</span><span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">return</span> <span class=\"k\">new</span> <span class=\"nf\">Param</span><span class=\"o\">()</span> <span class=\"o\">{</span>\n    <span class=\"kd\">public</span> <span class=\"kt\">void</span> <span class=\"nf\">set</span><span class=\"o\">(</span><span class=\"nc\">PreparedStatement</span> <span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"kt\">int</span> <span class=\"n\">column</span><span class=\"o\">){</span>\n      <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setInt</span><span class=\"o\">(</span><span class=\"n\">column</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">);</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">};</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<ul>\n  <li>Finally, an abstract class with just one method… fits perfectly the idea of <code class=\"language-plaintext highlighter-rouge\">FunctionalInterface</code>::</li>\n</ul>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@FunctionalInterface</span>\n<span class=\"kd\">public</span> <span class=\"kd\">interface</span> <span class=\"nc\">Param</span> <span class=\"o\">{</span>\n  <span class=\"kt\">void</span> <span class=\"nf\">set</span><span class=\"o\">(</span><span class=\"nc\">PreparedStatement</span> <span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"kt\">int</span> <span class=\"n\">i</span><span class=\"o\">)</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>Now I simply need more functions that, given a value, return an instance of  <code class=\"language-plaintext highlighter-rouge\">Param</code>. And they will use a lambda to create the resulting instance.</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setInt</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">);</span>\n<span class=\"o\">}</span>\n\n<span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"nc\">String</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setString</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">);</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>I named all such funtions <code class=\"language-plaintext highlighter-rouge\">p</code> so that the compiler, and not our user, gets to choose which one applies to the given parameter type. And all of a sudden my beloved user doesn’t need to remember what function to call, but just try <code class=\"language-plaintext highlighter-rouge\">p(x)</code> for any <code class=\"language-plaintext highlighter-rouge\">x</code> she wants passed as argument and only care about it if the compiler (rightfully) complains to not have any function <code class=\"language-plaintext highlighter-rouge\">p</code> that takes values of such type as a parameter.</p>\n\n<p>Now our select function can use the <code class=\"language-plaintext highlighter-rouge\">Param</code> instance to set the parameter in a typesafe way:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>  <span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nc\">List</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nf\">select</span><span class=\"o\">(</span><span class=\"nc\">String</span> <span class=\"n\">sql</span><span class=\"o\">,</span> <span class=\"nc\">RowReader</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">reader</span><span class=\"o\">,</span> <span class=\"nc\">Param</span><span class=\"o\">...</span> <span class=\"n\">params</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"kt\">var</span> <span class=\"n\">stmt</span> <span class=\"o\">=</span> <span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"na\">prepareStatement</span><span class=\"o\">(</span><span class=\"n\">sql</span><span class=\"o\">))</span> <span class=\"o\">{</span>\n      <span class=\"k\">for</span> <span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"o\">;</span> <span class=\"n\">i</span> <span class=\"o\">&lt;</span> <span class=\"n\">params</span><span class=\"o\">.</span><span class=\"na\">length</span><span class=\"o\">;</span> <span class=\"n\">i</span><span class=\"o\">++)</span> <span class=\"n\">params</span><span class=\"o\">[</span><span class=\"n\">i</span><span class=\"o\">].</span><span class=\"na\">set</span><span class=\"o\">(</span><span class=\"n\">stmt</span><span class=\"o\">,</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">);</span>\n      <span class=\"o\">...</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"dealing-with-sqlexception-redux\">Dealing with SQLException redux</h2>\n\n<p>Everything is nice and fine. Except, of course, I’m lying. Again.</p>\n\n<p><img src=\"../assets/psSetIntThrows.png\" alt=\"image-20230303181943679\" style=\"zoom:50%;\" /></p>\n\n<p>Naturally, I could surrond every sinlge invocation of <code class=\"language-plaintext highlighter-rouge\">setXxxx</code> methods with <code class=\"language-plaintext highlighter-rouge\">try...catch</code>. But you know how many <code class=\"language-plaintext highlighter-rouge\">setXxx</code> methods are there in <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code>? 50. I counted them. I’ve been told DRY is abused often. But I’m not writing 6 extra lines of <code class=\"language-plaintext highlighter-rouge\">try...catch</code> (including its braces) multiplied by 49 more times. Enough is enough.</p>\n\n<p>But this time the solution is actually simple. Although <code class=\"language-plaintext highlighter-rouge\">BiConsumer</code> can’t represent anything that throws checked exceptions, let’s simply admit our <code class=\"language-plaintext highlighter-rouge\">Param</code> functional interface can throw SQLExceptions and, all of a sudden, you can use lambdas like there were no exceptions to be seen.</p>\n\n<p>Jedi stuff. These aren’t the exceptions you are looking for.\n<img src=\"../assets/obi-wan-kenobi-these-are-not-the-droids.gif\" alt=\"Obi Wan Kenobi These Are Not The Droids GIF - Obi Wan Kenobi These Are Not The Droids Star Wars GIFs\" /></p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@FunctionalInterface</span>\n<span class=\"kd\">public</span> <span class=\"kd\">interface</span> <span class=\"nc\">Param</span> <span class=\"o\">{</span>\n  <span class=\"kt\">void</span> <span class=\"nf\">set</span><span class=\"o\">(</span><span class=\"nc\">PreparedStatement</span> <span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"kt\">int</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"kd\">throws</span> <span class=\"nc\">SQLException</span><span class=\"o\">;</span>\n\n  <span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setInt</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">);</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>It may be no rocket science if you are really used to (modern-ish) Java. But in my opinion it shows the smarts of the designers of Java. <code class=\"language-plaintext highlighter-rouge\">setInt</code> throws SQLException but it can be written in a Lambda because the <code class=\"language-plaintext highlighter-rouge\">FunctionalInterface</code> you expect to return (<code class=\"language-plaintext highlighter-rouge\">Param</code>) already declares the function to throw <code class=\"language-plaintext highlighter-rouge\">SQLException</code>.</p>\n\n<h2 id=\"nulls-and-autounboxing\">Nulls and autounboxing</h2>\n\n<p>I’m just writing about the design and implementation of this toy library. But <a href=\"https://blog.agilogy.com/series.html#introduction-to-testing\">I’m fond of testing</a> and, yes, I’m also testing it. So I’ve found a bug caused by my years away from Java.</p>\n\n<p>Did you spot it already? It is here:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setInt</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">);</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>Did you guess it? Yes, <code class=\"language-plaintext highlighter-rouge\">ps.setInt</code> takes an <code class=\"language-plaintext highlighter-rouge\">int</code> value. When you pass an <code class=\"language-plaintext highlighter-rouge\">Integer</code> value, it auto-unboxes. And if the value was null… Kaboom! <code class=\"language-plaintext highlighter-rouge\">NullPointerException</code>. I could rewrite the previous section with <code class=\"language-plaintext highlighter-rouge\">String</code> as the example and pretend I never did the mistake. But let’s be honest here. I did it. And now I’m fixing it:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"kd\">final</span> <span class=\"nc\">Integer</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setObject</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">,</span> <span class=\"nc\">Types</span><span class=\"o\">.</span><span class=\"na\">INTEGER</span><span class=\"o\">);</span>\n<span class=\"o\">}</span>\n\n<span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"kd\">final</span> <span class=\"kt\">int</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setInt</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">);</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"reading-rows\">Reading rows</h2>\n\n<p>Last… and, for once, possibly least. We want our user to read the rows in a <code class=\"language-plaintext highlighter-rouge\">ResultSet</code> in such a way that:</p>\n\n<ol>\n  <li>She can’t possibly forget to close the <code class=\"language-plaintext highlighter-rouge\">ResultSet</code></li>\n  <li>She can’t possibly try to use the <code class=\"language-plaintext highlighter-rouge\">ResultSet</code> after the <code class=\"language-plaintext highlighter-rouge\">Connection</code> was closed (probably returned to the pool)</li>\n  <li>She does not need to worry about advancing the cursor with <code class=\"language-plaintext highlighter-rouge\">next()</code></li>\n  <li>She does not need to deal with primitive types and <code class=\"language-plaintext highlighter-rouge\">wasNull()</code> (assuming we can live with wrapping every primitive value in nullable columns)</li>\n</ol>\n\n<p>For that, we are asking our user to provide a lambda that we will execute to read each row. As we don’t want her to mess with <code class=\"language-plaintext highlighter-rouge\">next()</code> we will handle her a trimmed-down <code class=\"language-plaintext highlighter-rouge\">ResultSet</code> where she can only get results but not move the cursor. That class can also facilitate things when she deals with nulls and wrapper types:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"kd\">class</span> <span class=\"nc\">ResultSetView</span> <span class=\"o\">{</span>\n\n  <span class=\"kd\">private</span> <span class=\"kd\">final</span> <span class=\"nc\">ResultSet</span> <span class=\"n\">resultSet</span><span class=\"o\">;</span>\n  <span class=\"kd\">public</span> <span class=\"nf\">ResultSetView</span><span class=\"o\">(</span><span class=\"nc\">ResultSet</span> <span class=\"n\">resultSet</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">this</span><span class=\"o\">.</span><span class=\"na\">resultSet</span> <span class=\"o\">=</span> <span class=\"n\">resultSet</span><span class=\"o\">;</span>\n  <span class=\"o\">}</span>\n  \n  <span class=\"kd\">public</span> <span class=\"nc\">String</span> <span class=\"nf\">getString</span><span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">column</span><span class=\"o\">)</span> <span class=\"kd\">throws</span> <span class=\"nc\">SQLException</span> <span class=\"o\">{</span>\n      <span class=\"k\">return</span> <span class=\"n\">resultSet</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"n\">column</span><span class=\"o\">);</span>\n  <span class=\"o\">}</span>\n  \n  <span class=\"kd\">public</span> <span class=\"nc\">Boolean</span> <span class=\"nf\">getBoolean</span><span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">column</span><span class=\"o\">)</span> <span class=\"kd\">throws</span> <span class=\"nc\">SQLException</span><span class=\"o\">{</span>\n    <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"n\">resultSet</span><span class=\"o\">.</span><span class=\"na\">getBoolean</span><span class=\"o\">(</span><span class=\"n\">column</span><span class=\"o\">);</span>\n    <span class=\"k\">return</span> <span class=\"n\">resultSet</span><span class=\"o\">.</span><span class=\"na\">wasNull</span><span class=\"o\">()</span> <span class=\"o\">?</span> <span class=\"kc\">null</span> <span class=\"o\">:</span> <span class=\"n\">res</span><span class=\"o\">;</span>\n  <span class=\"o\">}</span>\n  \n  <span class=\"kd\">public</span> <span class=\"kt\">boolean</span> <span class=\"nf\">getBool</span><span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">column</span><span class=\"o\">)</span> <span class=\"kd\">throws</span> <span class=\"nc\">SQLException</span><span class=\"o\">{</span>\n    <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"n\">resultSet</span><span class=\"o\">.</span><span class=\"na\">getBoolean</span><span class=\"o\">(</span><span class=\"n\">column</span><span class=\"o\">);</span>\n    <span class=\"k\">if</span><span class=\"o\">(</span><span class=\"n\">resultSet</span><span class=\"o\">.</span><span class=\"na\">wasNull</span><span class=\"o\">())</span> <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nc\">NullPointerException</span><span class=\"o\">(</span><span class=\"s\">\"Column \"</span> <span class=\"o\">+</span> <span class=\"n\">column</span> <span class=\"o\">+</span> <span class=\"s\">\" is null\"</span><span class=\"o\">);</span>\n    <span class=\"k\">return</span> <span class=\"n\">res</span><span class=\"o\">;</span>\n  <span class=\"o\">}</span>\n  \n  <span class=\"o\">...</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"selecting-things-the-final-implementation\">Selecting things, the final implementation</h2>\n\n<p>Finally, we can close the loop:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class</span> <span class=\"nc\">ConnectionScope</span> <span class=\"o\">{</span>\n  <span class=\"o\">...</span>\n  <span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nc\">List</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"nf\">select</span><span class=\"o\">(</span><span class=\"nc\">String</span> <span class=\"n\">sql</span><span class=\"o\">,</span> <span class=\"nc\">RowReader</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"n\">reader</span><span class=\"o\">,</span> <span class=\"nc\">Param</span><span class=\"o\">...</span> <span class=\"n\">params</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"kt\">var</span> <span class=\"n\">stmt</span> <span class=\"o\">=</span> <span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"na\">prepareStatement</span><span class=\"o\">(</span><span class=\"n\">sql</span><span class=\"o\">))</span> <span class=\"o\">{</span>\n      <span class=\"k\">for</span> <span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"o\">;</span> <span class=\"n\">i</span> <span class=\"o\">&lt;</span> <span class=\"n\">params</span><span class=\"o\">.</span><span class=\"na\">length</span><span class=\"o\">;</span> <span class=\"n\">i</span><span class=\"o\">++)</span> <span class=\"n\">params</span><span class=\"o\">[</span><span class=\"n\">i</span><span class=\"o\">].</span><span class=\"na\">set</span><span class=\"o\">(</span><span class=\"n\">stmt</span><span class=\"o\">,</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">);</span>\n      <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"kt\">var</span> <span class=\"n\">rs</span> <span class=\"o\">=</span> <span class=\"n\">stmt</span><span class=\"o\">.</span><span class=\"na\">executeQuery</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n        <span class=\"kt\">var</span> <span class=\"n\">rsView</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nc\">ResultSetView</span><span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">);</span>\n        <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"k\">new</span> <span class=\"nc\">LinkedList</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;();</span>\n        <span class=\"k\">while</span> <span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">next</span><span class=\"o\">())</span> <span class=\"o\">{</span>\n          <span class=\"n\">res</span><span class=\"o\">.</span><span class=\"na\">add</span><span class=\"o\">(</span><span class=\"n\">reader</span><span class=\"o\">.</span><span class=\"na\">apply</span><span class=\"o\">(</span><span class=\"n\">rsView</span><span class=\"o\">));</span>\n        <span class=\"o\">}</span>\n        <span class=\"k\">return</span> <span class=\"nc\">Collections</span><span class=\"o\">.</span><span class=\"na\">unmodifiableList</span><span class=\"o\">(</span><span class=\"n\">res</span><span class=\"o\">);</span>\n      <span class=\"o\">}</span>\n    <span class=\"o\">}</span> <span class=\"k\">catch</span> <span class=\"o\">(</span><span class=\"nc\">SQLException</span> <span class=\"n\">ex</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n      <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nf\">RuntimeException</span><span class=\"o\">(</span><span class=\"n\">ex</span><span class=\"o\">);</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n\n<span class=\"nd\">@FunctionalInterface</span>\n<span class=\"kd\">public</span> <span class=\"kd\">interface</span> <span class=\"nc\">RowReader</span><span class=\"o\">&lt;</span><span class=\"no\">A</span><span class=\"o\">&gt;</span> <span class=\"o\">{</span>\n  <span class=\"no\">A</span> <span class=\"nf\">apply</span><span class=\"o\">(</span><span class=\"nc\">ResultSetView</span> <span class=\"n\">rs</span><span class=\"o\">)</span> <span class=\"kd\">throws</span> <span class=\"nc\">SQLException</span><span class=\"o\">;</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>So, same Jedi trick here: <code class=\"language-plaintext highlighter-rouge\">RowReader</code> is a functional interface that declares to throw <code class=\"language-plaintext highlighter-rouge\">SQLException</code>. So users of <code class=\"language-plaintext highlighter-rouge\">select</code> can simply pass a lambda whose contents throw <code class=\"language-plaintext highlighter-rouge\">SQLException</code> happily. Which is what our <code class=\"language-plaintext highlighter-rouge\">getXxx</code> methods in <code class=\"language-plaintext highlighter-rouge\">ResultSetView</code> do:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">List</span><span class=\"o\">&lt;</span><span class=\"nc\">User</span><span class=\"o\">&gt;</span>  <span class=\"n\">users</span> <span class=\"o\">=</span> <span class=\"n\">tx</span><span class=\"o\">.</span><span class=\"na\">select</span><span class=\"o\">(</span>\n  <span class=\"s\">\"select u.id, u.name, u.surname from users u \"</span> <span class=\"o\">+</span>\n  <span class=\"s\">\"where active = true amd u.role = ?\"</span><span class=\"o\">,</span>\n  <span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"k\">new</span> <span class=\"nc\">User</span><span class=\"o\">(</span><span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"mi\">1</span><span class=\"o\">),</span> <span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"mi\">2</span><span class=\"o\">),</span> <span class=\"n\">rs</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"mi\">3</span><span class=\"o\">)),</span>\n  <span class=\"n\">p</span><span class=\"o\">(</span><span class=\"n\">role</span><span class=\"o\">)</span>\n<span class=\"o\">);</span>\n</code></pre></div></div>\n\n<h2 id=\"support-for-differnt-types\">Support for differnt types</h2>\n\n<p>Once your users are using <code class=\"language-plaintext highlighter-rouge\">Param</code> instead of <code class=\"language-plaintext highlighter-rouge\">PreparedStatement.setXxxx</code> and  <code class=\"language-plaintext highlighter-rouge\">ResultSetView</code> instead of <code class=\"language-plaintext highlighter-rouge\">ResultSet</code>, you now can extends the capabilities of Jdbc with new types. In particular, I’ve always found Jdbc’s lack of support for <code class=\"language-plaintext highlighter-rouge\">Instant</code> and <code class=\"language-plaintext highlighter-rouge\">java.net.URI</code> disturbing, just to mention a couple examples:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@FunctionalInterface</span>\n<span class=\"kd\">public</span> <span class=\"kd\">interface</span> <span class=\"nc\">Param</span> <span class=\"o\">{</span>\n  <span class=\"o\">...</span>\n  <span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"no\">URI</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setString</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">value</span><span class=\"o\">.</span><span class=\"na\">toString</span><span class=\"o\">());</span>\n  <span class=\"o\">}</span>\n  <span class=\"kd\">static</span> <span class=\"nc\">Param</span> <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"nc\">Instant</span> <span class=\"n\">value</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">return</span> <span class=\"o\">(</span><span class=\"n\">ps</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">ps</span><span class=\"o\">.</span><span class=\"na\">setTimestamp</span><span class=\"o\">(</span><span class=\"n\">i</span><span class=\"o\">,</span> <span class=\"n\">java</span><span class=\"o\">.</span><span class=\"na\">sql</span><span class=\"o\">.</span><span class=\"na\">Timestamp</span><span class=\"o\">.</span><span class=\"na\">from</span><span class=\"o\">(</span><span class=\"n\">value</span><span class=\"o\">));</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n\n<span class=\"kd\">public</span> <span class=\"kd\">class</span> <span class=\"nc\">ResultSetView</span> <span class=\"o\">{</span>\n\t<span class=\"o\">...</span>\n\t<span class=\"kd\">public</span> <span class=\"no\">URI</span> <span class=\"nf\">getURI</span><span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">column</span><span class=\"o\">)</span> <span class=\"kd\">throws</span> <span class=\"nc\">SQLException</span> <span class=\"o\">{</span>\n    <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"n\">resultSet</span><span class=\"o\">.</span><span class=\"na\">getString</span><span class=\"o\">(</span><span class=\"n\">column</span><span class=\"o\">);</span>\n    <span class=\"k\">return</span> <span class=\"n\">res</span> <span class=\"o\">==</span> <span class=\"kc\">null</span> <span class=\"o\">?</span> <span class=\"kc\">null</span> <span class=\"o\">:</span> <span class=\"no\">URI</span><span class=\"o\">.</span><span class=\"na\">create</span><span class=\"o\">(</span><span class=\"n\">res</span><span class=\"o\">);</span>\n  <span class=\"o\">}</span>\n  <span class=\"kd\">public</span> <span class=\"nc\">Instant</span> <span class=\"nf\">getInstant</span><span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">column</span><span class=\"o\">)</span> <span class=\"kd\">throws</span> <span class=\"nc\">SQLException</span> <span class=\"o\">{</span>\n    <span class=\"kt\">var</span> <span class=\"n\">res</span> <span class=\"o\">=</span> <span class=\"n\">resultSet</span><span class=\"o\">.</span><span class=\"na\">getTimestamp</span><span class=\"o\">(</span><span class=\"n\">column</span><span class=\"o\">);</span>\n    <span class=\"k\">return</span> <span class=\"n\">res</span> <span class=\"o\">==</span> <span class=\"kc\">null</span> <span class=\"o\">?</span> <span class=\"kc\">null</span> <span class=\"o\">:</span> <span class=\"n\">res</span><span class=\"o\">.</span><span class=\"na\">toInstant</span><span class=\"o\">();</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>Further than that, you can hide (by omiting them from your implementation), those types you don’t want your users to use directly. As an example, <a href=\"https://brian.pontarelli.com/2006/12/05/mr-gosling-why-did-you-make-url-equals-suck/\">let’s say you have your issues with URL</a>. You encourage your users to not use it by <strong>not</strong> implementing the <code class=\"language-plaintext highlighter-rouge\">p</code> and <code class=\"language-plaintext highlighter-rouge\">getUrl</code> methods.</p>\n\n<h2 id=\"other-select-and-update-methods\">Other select and update methods</h2>\n\n<p>Of course, I just implemented a couple simple methods that use Jdbc in some particular ways. But you can implement any other common usage of the api in order to simplify the scenarios you and your team use the most.</p>\n\n<p>Let’s see an example. Let’s say your database generates a surrogate key whenever you insert a new row in a given table. Do you know how to perform a Jdbc insert and get the generated key? It was something like:</p>\n\n<div class=\"language-java highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">public</span> <span class=\"o\">&lt;</span><span class=\"no\">K</span><span class=\"o\">&gt;</span> <span class=\"no\">K</span> <span class=\"nf\">insertAndGetKey</span><span class=\"o\">(</span><span class=\"nc\">String</span> <span class=\"n\">sql</span><span class=\"o\">,</span> <span class=\"nc\">RowReader</span><span class=\"o\">&lt;</span><span class=\"no\">K</span><span class=\"o\">&gt;</span> <span class=\"n\">keyReader</span><span class=\"o\">,</span>  <span class=\"nc\">Param</span><span class=\"o\">...</span> <span class=\"n\">params</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">try</span> <span class=\"o\">(</span><span class=\"kt\">var</span> <span class=\"n\">stmt</span> <span class=\"o\">=</span> <span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"na\">prepareStatement</span><span class=\"o\">(</span><span class=\"n\">sql</span><span class=\"o\">,</span> <span class=\"no\">RETURN_GENERATED_KEYS</span><span class=\"o\">))</span> <span class=\"o\">{</span>\n    <span class=\"k\">for</span> <span class=\"o\">(</span><span class=\"kt\">int</span> <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"mi\">0</span><span class=\"o\">;</span> <span class=\"n\">i</span> <span class=\"o\">&lt;</span> <span class=\"n\">params</span><span class=\"o\">.</span><span class=\"na\">length</span><span class=\"o\">;</span> <span class=\"n\">i</span><span class=\"o\">++)</span> <span class=\"n\">params</span><span class=\"o\">[</span><span class=\"n\">i</span><span class=\"o\">].</span><span class=\"na\">set</span><span class=\"o\">(</span><span class=\"n\">stmt</span><span class=\"o\">,</span> <span class=\"n\">i</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">);</span>\n    <span class=\"n\">stmt</span><span class=\"o\">.</span><span class=\"na\">executeUpdate</span><span class=\"o\">();</span>\n    <span class=\"k\">try</span><span class=\"o\">(</span><span class=\"kt\">var</span> <span class=\"n\">keys</span> <span class=\"o\">=</span> <span class=\"n\">stmt</span><span class=\"o\">.</span><span class=\"na\">getGeneratedKeys</span><span class=\"o\">()){</span>\n      <span class=\"n\">keys</span><span class=\"o\">.</span><span class=\"na\">next</span><span class=\"o\">();</span>\n      <span class=\"k\">return</span> <span class=\"n\">keyReader</span><span class=\"o\">.</span><span class=\"na\">apply</span><span class=\"o\">(</span><span class=\"k\">new</span> <span class=\"nc\">ResultSetView</span><span class=\"o\">(</span><span class=\"n\">keys</span><span class=\"o\">));</span>\n    <span class=\"o\">}</span>\n  <span class=\"o\">}</span> <span class=\"k\">catch</span> <span class=\"o\">(</span><span class=\"nc\">SQLException</span> <span class=\"n\">ex</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nf\">RuntimeException</span><span class=\"o\">(</span><span class=\"n\">ex</span><span class=\"o\">);</span>\n  <span class=\"o\">}</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>So, one nice thing of our abstraction is that you can create a mehod for each typical use case. Once your users will use by simply providing lambdas for the parts they are interested in. It reminds me of the template pattern, if you want. But it is simpler with lambdas.</p>\n\n<h2 id=\"recap\">Recap</h2>\n\n<p>We developed a small, lightway Jdbc helper library that:</p>\n\n<ul>\n  <li>Is under 300 lines of code, supporting many of the types supported by Jdbc. Probably under 500 lines if it supported all (the desirable) ones.</li>\n  <li>Is user friendly: easy to learn, typesafe, uniform (e.g. all parameters are passed the same)</li>\n  <li>Appropiately deals with <code class=\"language-plaintext highlighter-rouge\">null</code> while reading / writing columns</li>\n  <li>Encodes correct Jdbc usage patterns. e.g. Users can’t forget to close <code class=\"language-plaintext highlighter-rouge\">Connection</code>, <code class=\"language-plaintext highlighter-rouge\">PreparedStatement</code> or <code class=\"language-plaintext highlighter-rouge\">ResultSet</code></li>\n  <li>Is extensible to more methods that use Jdbc in different ways (and encodes them as easy to use templates).</li>\n  <li>Is extensible to types not directly supported by Jdbc so that we don’t repeat the needed transformations everywhere (e.g. Instant or URI columns or parameters)</li>\n  <li>Can hide dangerous / unwanted Jdbc features (e.g. java.sql.Date, java.sql.Time or  java.net.URL columns or parameters)</li>\n</ul>\n",
            "url": "https://blog.agilogy.com/2023-03-17-writing-a-simple-jdb-library-in-java.html",
            "date_published": "2023-03-17T00:00:00+01:00",
            "date_modified": "2023-03-17T00:00:00+01:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-12-16-writing-a-parser-combinator-library-2.html",
            "title": "Writing a Parser Combinator Library in Scala 3.<br> Part 2: Choices and repetitions",
            "content_text": "In our previous post we created a small Scala parser capable only of parsing empty Json arrays with possible whitespace. While doing so we designed a parser to be a function that takes an input and an index within that input and returns some result of a given type A or fails with a ParseError:\n\ntype Parser[A] = (String, Int) =&gt; Either[ParseError, A]\n\n\nWe then saw that we can create values of type Parser[A] and functions that, given some argument, return parsers:\n\nval whitespace: Parser[Int] = ...\nval array: Parser[JsonArray] = ...\ndef string(token: String): Parser[Int] = ...\n\n\nFinally we created a couple of combinators: sequence (aka **) takes 2 parsers of type Parser[Int] (where the Int represents the position after parsing something) and it returns a parser that applies both parsers in sequence and returns the last result, the position after parsing both; and map  takes a Parser[A] and a function A =&gt; B and returns a Parser[B].\n\nThat allowed us to create a parser like this:\n\nval array: Parser[JsonArray] =\n  (string(\"[\") ** whitespace ** string(\"]\")).map(_ =&gt; JsonArray(List.empty))\n\n\nIn this post we will explore the parsing of other Json elements that will give us new parser combinators.\n\nParsing JsonBoolean\n\nA boolean in Json is simply either true or false. We already know how to build a Parser that parses such strings:\n\nval jsonTrue: Parser[JsonBoolean] = \n  string(\"true\").map(_ =&gt; JsonBoolean(true))\nval jsonFalse: Parser[JsonBoolean] = \n  string(\"false\").map(_ =&gt; JsonBoolean(false))\n\n\nBut we want a parser of JsonBoolean that is able to parser any of these 2 values:\n\n  test(\"Parse boolean\") {\n    assert(boolean(\"true\", 0) == Right(JsonBoolean(true)))\n    assert(boolean(\"false\", 0) == Right(JsonBoolean(false)))\n  }\n\n\n🔴\n\nWe can implement a parser for Json booleans trying to parse true first. If that fails it will simply try to parse false at the same position. This is doable with the orElse member of Either that returns the this if its a Right or returns its argument, which is another (lasyly evaluated) Either:\n\nval boolean: Parser[JsonBoolean] = (s, position) =&gt;\n  jsonTrue(s, i) orElse jsonFalse(s, position)\n\n\n✅ We try to parse a true and if we succeed, we call it a day. If we don’t succeed, orElse will return the result of trying to parse a false.\n\n♻️ (refactor) In the solution above, like we did in the previous post, we are programming what the parser does by hand, dealing with the s and position parameters of parsers. But we would like to abstract those into a combinator of parsers:\n\nextension [A](self: Parser[A])\n  def |(other: Parser[A]): Parser[A] = (s, position) =&gt;\n    self(s, position) orElse other(s,position)  \n\nval boolean: Parser[JsonBoolean] = jsonTrue | jsonFalse\n\n\n✅ Great!\n\nBut what about failure? We would like to get an error that tells we were expecting either true or false:\n\ntest(\"Parse boolean failure\") {\n  val input = \"notABoolean\"\n  assert(boolean(input, 0) == Left(ParseError(input, 0, List(\"true\", \"false\"))))\n}\n\n\n🔴 Compilation error. Our current ParseError class can only hold one expected String and we now want a List of them. Let’s change that class and fix all the compilation issues and we are still in red:\n\nLeft(ParseError(\"notABoolean\", 0, List(\"false\"))) did not equal Left(ParseError(\"notABoolean\", 0, List(\"true\", \"false\")))\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at (JsonParserTest.scala:45)\n\n\nWhen it fails to parse, our solution so far only keeps the last alternative it evaluated and complains about expecting only that last option. Let’s try to fix that:\n\nextension [A](self: Parser[A])\n  def |(other: Parser[A]): Parser[A] = (s, position) =&gt;\n    self(s, position) match\n      case Right(a) =&gt; Right(a)\n      case Left(e1) =&gt; other(s, position) match\n        case Right(a) =&gt; Right(a)\n        case Left(e2) =&gt; Left(e2.copy(expected = e1.expected ++ e2.expected))\n\n\n✅\n\nParsing arrays… of 2 boolean values\n\nOk, I’m feeling lucky! Let’s try to parse something more difficult. What about [true, false] or the other combinations of an array of two boolean values?\n\ntest(\"Parse array of true values\") {\n  assert(booleanArray(\"[true,false]\", 0) == \n    Right(JsonArray(List(JsonBoolean(true), JsonBoolean(false))))\n  )\n}\n\n\n🔴, of course.\n\nLet’s implement booleanArray like we only cared about arrays of 2 booleans, for now:\n\n  val booleanArray: Parser[JsonArray] =\n    string(\"[\") ** jsonBoolean ** string(\",\") ** jsonBoolean ** string(\"]\")\n\n\nThe first issue is we don’t have a sequencing combinator (**) for parsers other than Parser[Int].  Let’s try to fix that. We want to generalize ` sequence (**`) to any kind of parsers.\n\nextension [A](self: Parser[A])\n\tinfix def sequence[B](other: Parser[B]): Parser[???] = ...\n\n\nFirst question arised. What should we return when we parse an A and then a B? It seems only natural to return the tuple of both values:\n\nextension [A](self: Parser[A])\n  infix def sequence[B](other: Parser[B]): Parser[(A,B)] = (s, position) =&gt;\n    for\n      a &lt;- self(s, position)\n      b &lt;- other(s, ???)\n    yield (a,b)\n\n\nBut now we have another issue. We implemented sequence for parsers that returned the position after parsing. But we now have parsers that already return a meaningful value (a JsonBoolean) and we need to know the position after parsing so that we can combine them with other parsers in sequence.\n\nOne solution is to redefine our Parser type. We git stash save wip our changes and:\n\ntype Parser[A] = (String, Int) =&gt; Either[ParseError, (A, Int)]\n\n\n🔴 Lots of things are broken, because the new Parser type is not comptaible with the old one.\n\nLet’s just fix them. Some examples:\n\ndef string(token: String): Parser[Unit] = (s, position) =&gt;\n  if (s.startsWith(token, position)) Right(() -&gt; (position + token.length))\n  else Left(ParseError(s, position, List(token)))\n\nextension [A](self: Parser[A])\n  def map[B](f: A =&gt; B): Parser[B] = (s, position) =&gt;\n    self(s, position).map((a, finalPosition) =&gt; f(a) -&gt; finalPosition)\n\n\nIn particular, let’s see how sequence ends up implementedIt seems the bug that makes destructuring not possible in for comprehensions, which is an old friend of mine, is still around in Scala 3. That was not expected. Oh, it seems to be resolved… in the nightly build of upcoming Scala 3.3.:\n\nextension[A](self: Parser[A])\n  infix def sequence[B](other: Parser[B]): Parser[(A, B)] = (s, position) =&gt;\n    for\n      aI0 &lt;- self(s, position)\n      (a, i0) = aI0\n      bI1 &lt;- other(s, i0)\n      (b, i1) = bI1\n    yield (a -&gt; b) -&gt; i1\n\n\nAnd our tests for successful parsings need to be rewritten to add the position after parsing:\n\ntest(\"Parse empty array\") {\n  assert(array(\"[]\", 0) == Right(JsonArray(List.empty),2))\n}\n\n\n✅ Green! ♻️ But those tests are starting to be unconvenient. All of our tests try to parse at position 0, like the end users of our parsers will do. And they tend to not care about what the final position of the parsing is. Let’s add another apply for that:\n\nextension[A](self: Parser[A])\n  def apply(s: String): Either[ParseError, A] = self(s, 0).map(_._1)\n\n\nSo our tests are now simpler:\n\ntest(\"Parse empty array\") {\n  assert(array(\"[]\") == Right(JsonArray(List.empty)))\n}\n\n\n✅ But with one concern. We expect the end user parser to fail if we encounter unexpected content after parsing a json value:\n\ntest(\"Parse empty array failure, unexpected content\") {\n  val input = \"[]wut?\"\n  assert(array(input) == Left(ParseError(input, 2, List(\"end of input\"))))\n}\n\n\n🔴 Right(JsonArray(List())) did not equal Left(ParseError(\"[]wut?\", 2, List(\"end of input\")))\n\nLet’s fix it:\n\ndef apply(s: String): Either[ParseError, A] =\n  self(s, 0) match\n    case Right((_, endPosition)) if endPosition &lt; s.length =&gt;\n      Left(ParseError(s, endPosition, List(\"end of input\")))\n    case r =&gt; r.map(_._1)\n\n\n✅  Good!\n\n♻️ But now, when a parser error says it was expecting end of input does it mean the end of the input or the string \"end of input\"? Let’s put all other string between quotes to distinguish that:\n\ntest(\"Parse empty array failure, missing ]\") {\n  val input = \"[\"\n  assert(array(input) == Left(ParseError(input, 1, List(\"\\\"]\\\"\"))))\n}\n\ntest(\"Parse empty array failure, unexpected content\") {\n  val input = \"[]wut?\"\n  assert(array(input) == Left(ParseError(input, 2, List(\"end of input\"))))\n}\n\n\nNow we can git stash pop our parser of arrays of two booleans and finish it:\n\nval booleanArray: Parser[JsonArray] =\n  (string(\"[\") ** boolean ** string(\",\") ** boolean ** string(\"]\"))\n    .map { case ((((_, b1), _), b2), _) =&gt; JsonArray(List(b1, b2)) }\n\n\n✅! ♻️ But that destructured argument to map was ugly. Let’s try to fix it with some more sugar. My idea is that whenever we sequence a parser of Unit and any other parser of any type A, we don’t care about the Unit value and we just want the A, not a Pair&lt;Unit,A&gt;. I’ll create an extension for Parser[Unit] where sequence ignores the Unit and I’ll add a sequence version taking a Parser[Unit] that ignores that other Unit. As I’ll need the original sequence in multiple places, I define it at the root level:\n\ndef _sequence[A, B](a: Parser[A], b: Parser[B]): Parser[(A, B)] = ... \n\nextension (self: Parser[Unit])\n\n  infix def sequence[B](other: Parser[B]): Parser[B] = _sequence(self, other).map(_._2)\n  def **[B](other: Parser[B]): Parser[B] = _sequence(self, other).map(_._2)\n\nend extension\n\nextension [A](self: Parser[A])\n\n  infix def sequence[B](other: Parser[B]): Parser[(A, B)] = _sequence(self, other)\n  @targetName(\"sequenceUnit\")\n  infix def sequence(other: Parser[Unit]): Parser[A] = _sequence(self, other).map(_._1)\n\n  def **[B](other: Parser[B]): Parser[(A, B)] = sequence(other)\n  @targetName(\"starStarUnit\")\n  def **(other: Parser[Unit]): Parser[A] = sequence(other)\n\nend extension\n\n\n\nNow our array parser is:\n\nval booleanArray: Parser[JsonArray] =\n  (string(\"[\") ** boolean ** string(\",\") ** boolean ** string(\"]\"))\n    .map { case (b1, b2) =&gt; JsonArray(List(b1, b2)) }\n\n\nParsing arrays of booleans\n\nLet’s say we want to parse arrays (of booleans) of any length, now:\n\ntest(\"Parse array of boolean values\") {\n  val length = random.between(3, 5)\n  val booleans = (0 until length).map(_ =&gt; random.nextBoolean()).toList\n  assert(booleanArray(s\"[${booleans.map(_.toString).mkString(\",\")}]\") ==\n    Right(JsonArray(booleans.map(JsonBoolean)))\n  )\n}\n\n\n🔴 After the second boolean it expects ] but we give it more booleans.\n\nThis time, we will start by solving the problem with some combinators and invent new ones whenever we need them:\n\nstring(\"[\") **\n   ((boolean ** (string(\",\") ** boolean).repeated) | empty) ** \nstring(\"]\")\n\n\nThe idea is to have [, then the array contents and then ]. The array contents may be empty or they may be a boolean followed by 0 or more times the combination of a comma and a boolean. But now we want our types to fit in this idea. Let’s see that in detail:\n\nWe already know that (string(\",\") ** boolean) is of type JsonBoolean\n\np.repeated is intended to represent a parser that parses whatever p parses any number of times, including 0. If p is of type A, then it will parse any number of chunks as instances of type A, giving us a list of values of type A:\n\nextension [A](self: Parser[A])\n  def repeated: Parser[List[A]] = ???\n\n\nTherefore, (string(\",\") ** boolean).repeated gives us a List[JsonBoolean]. And (boolean ** (string(\",\") ** boolean).repeated, is of type  (JsonBoolean,List[JsonBoolean]). If we want all in a JsonArray, we must map that parser. The empty parser returns whatever value we want; and we want an empty JsonArray.\n\nval booleanArray: Parser[Json] =\n  string(\"[\") ** (\n      (boolean ** (string(\",\") ** boolean).repeated).map { case (b, l) =&gt; JsonArray(b :: l)} | \n      empty(JsonArray(List.empty))\n    ) ** string(\"]\")\n\n\n\nRepetition… by self-recursion! How cool is that?\n\nNow we need to implement repeated. Here is one fancy way with just the combinators we already have and a recursive definition:\n\nWe can define a parser repeated that, when needed, tries to parse some content with repeated itself. Like a function calling itself but with parsers.\n\nLet’s see how that turns out:\n\ndef repeated: Parser[List[A]] = (self ** repeated).map(_ :: _) | empty(List.empty)\n\n\nIt compiles! Let’s run our tests:\n\nAn exception or error caused a run to abort. \njava.lang.StackOverflowError\n\tat com.agilogy.wapl.Parser$package$ParserOps.repeated(Parser.scala:54)\n\tat com.agilogy.wapl.Parser$package$ParserOps.repeated(Parser.scala:54)\n\n\n🔴 Ops! When defining repeated it calls repeated. StackOverflowError.\n\nBut we may use some lazyness here. After all, sequence (or **) won’t need the second parser unless the first one succeeds. It seems only natural for it (and its variants) to evaluate that second parser lazyly:\n\ndef _sequence[A, B](a: Parser[A], b: =&gt; Parser[B]): Parser[(A, B)] = ...\n\nextension (self: Parser[Unit])\n\n  infix def sequence[B](other: =&gt; Parser[B]): Parser[B] = _sequence(self, other).map(_._2)\n  def **[B](other: =&gt; Parser[B]): Parser[B] = _sequence(self, other).map(_._2)\n\nend extension\n\nextension [A](self: Parser[A])\n\n  infix def sequence[B](other: =&gt; Parser[B]): Parser[(A, B)] = _sequence(self, other)\n  @targetName(\"sequenceUnit\")\n  infix def sequence(other: =&gt; Parser[Unit]): Parser[A] = _sequence(self, other).map(_._1)\n  def **[B](other: =&gt; Parser[B]): Parser[(A, B)] = _sequence(other)\n  @targetName(\"starStarUnit\")\n  def **(other: Parser[Unit]): Parser[A] = _sequence(other)\n\nend extension\n\n\n✅ ! But… What about long arrays. Let’s change our test to generate arrays of length random.between(10000, 10005):\n\nAn exception or error caused a run to abort. \njava.lang.StackOverflowError\n\tat scala.runtime.BoxesRunTime.boxToInteger(BoxesRunTime.java:63)\n\tat com.agilogy.wapl.Parser$package$ParserOps.map$$anonfun$1(Parser.scala:37)\n\n\n🔴 Ouch! This time the cause is not an infinite recursion, but simply one too deep. So let’s be a bit less fancy and implement repeated by hand. That is, we run a tailrec loop where we try to parse the content with the parser we want repeatedly applied. If it doesn’t parse, we stop repeating and return the accumulated list of parsed values so far (which may be empty). If it does parse, we repeat at the new position.\n\ndef repeated: Parser[List[A]] = (s, position) =&gt;\n  @tailrec\n  def loop(acc: List[A], pos: Int): (List[A],Int) =\n    self(s, pos) match\n      case Left(_) =&gt; (acc.reverse, pos)\n      case Right(a, newPos) =&gt; loop(a::acc, newPos)\n  Right(loop(List.empty, position))\n\n\n✅ !\n\n♻️ Let’s refactor a bit… We now have 2 array parsers: an array parser that only accepts whitespace and a booleanArray parser that only accepts booleans. Let’s remove the former and make the later accept whitespace by using whitespaceI should, in fact, allow whitespace in many other places, like between the \",\" and the next boolean. But let me add that to the backlog and keep going. instead of empty:\n\nval array: Parser[Json] =\n  string(\"[\") **\n    ((boolean ** (string(\",\") ** boolean).repeated).map {\n      case (b, l) =&gt; JsonArray(b :: l)\n    } | whitespace.map(_ =&gt; JsonArray(List.empty)))\n    ** string(\"]\")\n\n\n✅\n\nOther primitives\n\nLet me continue with the parsing of other primitive values. Let’s start with Json numbers. The grammar for Json numbers occupies some space of your screen but it is not complex:\n\n\n\nWe chose to represent JsonNumber by its internal string representation instead of trying to represent it with a numeric Scala or Java value. That allows us to just focus on Json and let our users treat that number however they wantJson numbers are decimal numbers without any bound. Int, Long and any other integer primitive type won’t be able to hold values if they are out of the allowed range of values. And Float and Double types, being floating point representations, won’t be able to correctly represent some decimal values. Still, in many occasions, a Long or a Double may suffice if you know your Json use case is not amongst those that cause issues. We could use something like a BigDecimal, but I prefer to simply give our user the String and let them decide how to use them.. Now we won’t try to normalize parsed numbers, just parse them and return their string representation.\n\ntest(\"Parse json numbers\") {\n  assert(number(\"1\") == Right(JsonNumber(\"1\")))\n  assert(number(\"0.1\") == Right(JsonNumber(\"0.1\")))\n  assert(number(\"-0.1\") == Right(JsonNumber(\"-0.1\")))\n  assert(number(\"-0.1\") == Right(JsonNumber(\"-0.1\")))\n  assert(number(\"-0.1e2\") == Right(JsonNumber(\"-0.1e2\")))\n  assert(number(\"-0.1e+2\") == Right(JsonNumber(\"-0.1e+2\")))\n  assert(number(\"-0.1e-2\") == Right(JsonNumber(\"-0.1e-2\")))\n}\n\n\n🔴 because it doesn’t compile and 🔴 once we write number to return ???.\n\nWe could parse numbers by hand with our current combinators, probably. But them being tokens, it seems easier to just use a Regex:\n\nval number: Parser[JsonNumber] =\n  regex(\"number\", \"-?([1-9][0-9]*|0)(\\\\.[0-9]+)?([eE][\\\\-+]?[0-9]+)?\".r).map(JsonNumber.apply)\n\n\nWhere:\n\ndef regex(label: String, regex: Regex): Parser[String] = (s, position) =&gt;\n  regex.findPrefixOf(s.substring(position))\n    .map(m =&gt; Right(m, position + m.length))\n    .getOrElse(Left(ParseError(s, position, List(label))))\n\n\n✅ All tests green.\n\nWhat about Json strings? The full grammar is:\n\nstring\n    '\"' characters '\"'\ncharacters\n    \"\"\n    character characters\ncharacter\n    '0020' .. '10FFFF' - '\"' - '\\'\n    '\\' escape\n\n\nLet me implement just a simplified version where we don’t have escape characters. We can implement them fully later. To test valid characters I’ll test the two edge values. The char 10FFFF can be encoded in UTF-16 as 0xDBFF 0xDFFF. So:\n\ntest(\"Parse json strings\") {\n  assert(string(\"\\\"\\\"\") == Right(JsonString(\"\")))\n  assert(string(\"\\\"Json\\\"\") == Right(JsonString(\"Json\")))\n  assert(string(\"\\\"No només ASCII\\\"\") == Right(JsonString(\"No només ASCII\")))\n  assert(string(\"\\\"\\u0020\\udbff\\udfff\\\"\") == Right(JsonString(\"\\u0020\\udbff\\udfff\")))\n}\n\n\n🔴 In fact, I find I used the name string for generic parsers and now I want to use it for JsonParser. I don’t like the mess I get where I need to import the correct one, so I rename the generic parsers string to token and add a string parser to JsonParser. Now it compiles, let’s implement it so it passes the tests.\n\nAs I’m just implementing a simplified version without escape chars, I’ll just use another regex to accept any char that is not a \":\n\nval string: Parser[JsonString] = regex(\"string\", \"\\\"[^\\\"]*\\\"\".r)\n  .map(s =&gt;  JsonString(s.substring(1, s.length - 1)))\n\n\n✅ Done!\n\nParsing Json arrays, at last… (without objects)\n\nNow I can close the circle and try to implement arrays of arbitrary Json values… except objects which I don’t have implemented yet.\n\n  test(\"Parse array of values and arrays\") {\n    assert(array(\"[1,false,\\\"hello\\\",[true,3]]\") ==\n      Right(JsonArray(List(\n        JsonNumber(\"1\"),\n        JsonBoolean(false),\n        JsonString(\"hello\"),\n        JsonArray(List(JsonBoolean(true), JsonNumber(\"3\")))\n      ))))\n  }\n\n\n🔴 This time it compiles, but the test fails with:\n\nExpected :Right(...)\nActual   :Left(ParseError(\"[1,false,\"hello\",[true,3]]\", 1, List(\"\"]\"\")))\n\n\nI don’t like that error message very much. That’s my fault, as I have paid no attention to error messages for many commits now. But I’m in the midle of a Red-Green-Refactor cycle, so this is not the moment. Let’s add that to a backlog. And now let’s focus on the task at hand. My approach is to finally parse any Json value we support so far:\n\nval json: Parser[Json] = boolean | string | number | array\n\n\nAnd now array can contain json values instead of just boolean values:\n\nval array: Parser[Json] =\n  token(\"[\") ** (\n      (json ** (token(\",\") ** json).repeated).map { case (b, l) =&gt; JsonArray(b :: l) } | \n      whitespace(JsonArray(List.empty))\n  ) ** token(\"]\")\n\n\nMy IntelliJ warns me that referring json, which I have defined after array, is a suspicious forward reference. Furthermore, the reference is circular, because array uses json and json uses array.  But let’s just run the tests and see what happens…\n\n✅ Wow! How that even worked? Remember we defined **’s second parameter to be lazyly evaluated and, therefore,  json wont’t get immediately evaluated when defining array. It is no longer using a forward reference before that reference takes a value. And there is no more a problematic circular reference: when defining array it won’t use json right away, then json will get defined and, finally, by when we use the array parser, json will have been already evaluated.\n\n♻️ Refactor? There may be many options. I’ll peek some:\n\n\n  \n    Make |’s second parameter lazyly evaluated like we do in **. After all, the second argument to | will only be needed if the first argument fails to parse.\n  \n  \n    Sort the tests so all Json primitive tests go first and all array tests come later.\n  \n  \n    Mark parsers not representing json types private: whitespace, jsonTrue, jsonFalse\n  \n  \n    Add a helper function for the usual case where we map to some value ignoring the current value ( e.g. p.map(_ =&gt; JsonBoolean(true))): p.as(JsonBoolean(true)).\n  \n\n\nParsing objects\n\nAnd now, objects! Let’s go directly to the TDD cycle:\n\ntest(\"Parse object\") {\n  val input = \"{\\\"a\\\":23,\\\"b\\\":[{\\\"c\\\":null}]}\"\n  val expected = JsonObject(Map(\n    \"a\" -&gt; JsonNumber(\"23\"),\n    \"b\" -&gt; JsonArray(List(JsonObject(Map(\"c\" -&gt; JsonNull))))\n  ))\n  assert(json(input) == Right(expected))\n}\n\n\n🔴 Red, of course.\n\nLet’s just copy the array solution but parse object members (a key, \":\" and a value) instead of just values:\n\nval member: Parser[(String, Json)] = string.map(_.value) ** token(\":\") ** json\n\nval obj: Parser[Json] =\n  token(\"{\") ** (\n    (member ** (token(\",\") ** member).repeated).map { case (b, l) =&gt; JsonObject((b :: l).toMap) } | \n    whitespace.as(JsonObject(Map.empty))\n  ) ** token(\"}\")\n\nval json: Parser[Json] = boolean | string | number | array | obj\n\n\n🔴 What!?\n\nExpected :Right(JsonObject(Map(\"a\" -&gt; JsonNumber(\"23\"), \"b\" -&gt; JsonArray(List(JsonObject(Map(\"c\" -&gt; JsonNull)))))))\nActual   :Left(ParseError(\"{\"a\":23,\"b\":[{\"c\":null}]}\", 7, List(\"\"true\"\", \"\"false\"\", \"string\", \"number\", \"\"[\"\", \"\"}\"\")))\n\n\nWhy on earth is it complaining about position 7? What is to be found there is clearly a member \"b\":[{\"c\":null}]…\n\nAfter actually spending a lot of minutes trying to figure out here it is: json does not yet support nulls. That is of course my fault for using null in my test when I don’t yet support it. But, why such an ugly error message?? Let me add that to the backlog too and fix the issue now that we know what it was.\n\nval jsonNull: Parser[JsonNull.type]  = \"null\".as(JsonNull)\nval json: Parser[Json] = boolean | string | number | jsonNull | array | obj\n\n\n✅ Wa yeah!\n\nOur parsing library so far\n\nThe current version of our parser library so far has these functions:\n\ntype Parser[A] = (String, Int) =&gt; Either[ParseError, (A, Int)]\n\ndef token(token: String): Parser[Unit] = (s, position) =&gt; ...\ndef empty[A](value: A): Parser[A] = (_, position) =&gt; ...\ndef sequence[A, B](a: Parser[A], b: =&gt; Parser[B]): Parser[(A, B)] = \n  (s, position) =&gt; ...\ndef regex(label: String, regex: Regex): Parser[String] = (s, position) =&gt; ...\n\nextension (self: Parser[Unit])\n\n  infix def sequence[B](other: =&gt; Parser[B]): Parser[B] = ...\n  def **[B](other: =&gt; Parser[B]): Parser[B] = ...\n\nend extension\n\nextension [A](self: Parser[A])\n\n  def apply(s: String): Either[ParseError, A] = ...\n  def map[B](f: A =&gt; B): Parser[B] = (s, position) =&gt; ...\n  def as[B](b: B): Parser[B] = ...\n  def |(other: =&gt; Parser[A]): Parser[A] = (s, position) =&gt; ...\n  infix def sequence[B](other: =&gt; Parser[B]): Parser[(A, B)] = ...\n  infix def sequence(other: =&gt; Parser[Unit]): Parser[A] = ...\n  def **[B](other: =&gt; Parser[B]): Parser[(A, B)] = ...\n  def **(other: Parser[Unit]): Parser[A] = ...\n  def repeated: Parser[List[A]] = (s, position) =&gt; ...\n\nend extension\n\n\nIf we examine the functions returning Parser carefully we’ll see that most of them are defined by the implementation of the actual parser, where we receive the string and the position and return the parse result. We’ll call those, primitives. But some others, like as, are derived from the primitives; we don’t implement them by saying how they handle the string and the position to return a parse result but we derive them from some other(s) parser(s) and applying functions on them.\n\nWe can, in fact, further refactor our current solution to discover more useful derived functions.\n\nOne of them may be useful to represent the repetition of values with some separator:\n\ndef separatedBy(separator: Parser[Unit]): Parser[List[A]] =\n  (self ** (separator ** self).repeated).map { case (h, t) =&gt; h :: t } | empty(List.empty) \n\n\nAnd now we can simplify a couple of definitions in JsonParser:\n\nval array: Parser[Json] =\n  token(\"[\") ** whitespace ** \n    json.separatedBy(token(\",\")).map(JsonArray.apply) \n    ** token(\"]\")\nval obj: Parser[Json] =\n  token(\"{\") **\n    member.separatedBy(token(\",\")).map(members =&gt; JsonObject(members.toMap))\n    ** token(\"}\")\n\n\nThis being Scala (3) we could add some more sugar. Those token(\"foo\") could be replaced with their string value directly:\n\ngiven Conversion[String, Parser[Unit]] with\n  def apply(str: String): Parser[Unit] = token(str)\n\n\nSo now we can write parsers like these:\n\nval array: Parser[Json] =\n  \"[\" ** whitespace ** json.separatedBy(\",\").map(JsonArray.apply) ** token(\"]\")\nval obj: Parser[Json] =\n  \"{\" ** member.separatedBy(\",\").map(members =&gt; JsonObject(members.toMap)) ** \"}\"\n\n\nOur Json parser so far\n\nWe have now a quite capable Json parser. Some known limitations we may want to overcome:\n\n\n  It can’t parse Json with whitespace properly\n  It can’t parse strings with escape sequences\n  It has very limited error handling capabilities\n\n\nConclusions\n\nAfter the very limited but promising features developed in the first part of the series, we developed an almost complete Json parser using a TDD aproach. At the same time, at each “refactor” phase, we abstracted a bunch of useful parser combinator functions, therefore developing a parser combinator library, as we intended.\n\nBeyond the (known) limitations of our Json parser, we now have a quite capable parser combinator library… although we only tested one example grammar we developed with it. And this is one of the drawbacks of this approach compared to the approach in the Red book. We now have a parser combinator library but we don’t have any tests of the library itself, but just tests of one example parser we implemented with it.\n\nYou can see the complete source code of this post here: https://github.com/agile-jordi/writingAParserLibrary/tree/part2.\n\nAll articles in the series\n\n\n  Writing a Parser Combinator Library in Scala 3. Part 1: Introduction to Parsing\n  Writing a parser library in Scala. Part 2: Choices and repetitions\n\n\n",
            "content_html": "<p>In <a href=\"/2022-11-11-writing-a-parser-combinator-library-1.html\">our previous post</a> we created a small Scala parser capable only of parsing empty Json arrays with possible whitespace. While doing so we designed a parser to be a function that takes an input and an index within that input and returns some result of a given type <code class=\"language-plaintext highlighter-rouge\">A</code> or fails with a <code class=\"language-plaintext highlighter-rouge\">ParseError</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">type</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"nc\">String</span><span class=\"o\">,</span> <span class=\"nc\">Int</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">A</span><span class=\"o\">]</span>\n</code></pre></div></div>\n\n<p>We then saw that we can create values of type <code class=\"language-plaintext highlighter-rouge\">Parser[A]</code> and functions that, given some argument, return parsers:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">whitespace</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n<span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n<span class=\"k\">def</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n</code></pre></div></div>\n\n<p>Finally we created a couple of combinators: <code class=\"language-plaintext highlighter-rouge\">sequence</code> (aka <code class=\"language-plaintext highlighter-rouge\">**</code>) takes 2 parsers of type <code class=\"language-plaintext highlighter-rouge\">Parser[Int]</code> (where the <code class=\"language-plaintext highlighter-rouge\">Int</code> represents the position after parsing something) and it returns a parser that applies both parsers in sequence and returns the last result, the position after parsing both; and <code class=\"language-plaintext highlighter-rouge\">map</code>  takes a <code class=\"language-plaintext highlighter-rouge\">Parser[A]</code> and a function <code class=\"language-plaintext highlighter-rouge\">A =&gt; B</code> and returns a <code class=\"language-plaintext highlighter-rouge\">Parser[B]</code>.</p>\n\n<p>That allowed us to create a parser like this:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">whitespace</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>In this post we will explore the parsing of other Json elements that will give us new parser combinators.</p>\n\n<h2 id=\"parsing-jsonboolean\">Parsing JsonBoolean</h2>\n\n<p>A boolean in Json is simply either <code class=\"language-plaintext highlighter-rouge\">true</code> or <code class=\"language-plaintext highlighter-rouge\">false</code>. We already know how to build a <code class=\"language-plaintext highlighter-rouge\">Parser</code> that parses such strings:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">jsonTrue</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonBoolean</span><span class=\"o\">]</span> <span class=\"k\">=</span> \n  <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"true\"</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">true</span><span class=\"o\">))</span>\n<span class=\"k\">val</span> <span class=\"nv\">jsonFalse</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonBoolean</span><span class=\"o\">]</span> <span class=\"k\">=</span> \n  <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"false\"</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">false</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>But we want a parser of JsonBoolean that is able to parser any of these 2 values:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>  <span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse boolean\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">boolean</span><span class=\"o\">(</span><span class=\"s\">\"true\"</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">true</span><span class=\"o\">)))</span>\n    <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">boolean</span><span class=\"o\">(</span><span class=\"s\">\"false\"</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">false</span><span class=\"o\">)))</span>\n  <span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴</p>\n\n<p>We can implement a parser for Json booleans trying to parse <code class=\"language-plaintext highlighter-rouge\">true</code> first. If that fails it will simply try to parse <code class=\"language-plaintext highlighter-rouge\">false</code> at the same position. This is doable with the <code class=\"language-plaintext highlighter-rouge\">orElse</code> member of <code class=\"language-plaintext highlighter-rouge\">Either</code> that returns the <code class=\"language-plaintext highlighter-rouge\">this</code> if its a <code class=\"language-plaintext highlighter-rouge\">Right</code> or returns its argument, which is another (lasyly evaluated) <code class=\"language-plaintext highlighter-rouge\">Either</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">boolean</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonBoolean</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nf\">jsonTrue</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">i</span><span class=\"o\">)</span> <span class=\"n\">orElse</span> <span class=\"nf\">jsonFalse</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>✅ We try to parse a <code class=\"language-plaintext highlighter-rouge\">true</code> and if we succeed, we call it a day. If we don’t succeed, <code class=\"language-plaintext highlighter-rouge\">orElse</code> will return the result of trying to parse a <code class=\"language-plaintext highlighter-rouge\">false</code>.</p>\n\n<p>♻️ (refactor) In the solution above, like we did in the previous post, we are programming what the parser does by hand, dealing with the <code class=\"language-plaintext highlighter-rouge\">s</code> and <code class=\"language-plaintext highlighter-rouge\">position</code> parameters of parsers. But we would like to abstract those into a combinator of parsers:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"k\">def</span> <span class=\"nf\">|</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"n\">orElse</span> <span class=\"nf\">other</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span><span class=\"n\">position</span><span class=\"o\">)</span>  \n\n<span class=\"k\">val</span> <span class=\"nv\">boolean</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonBoolean</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"n\">jsonTrue</span> <span class=\"o\">|</span> <span class=\"n\">jsonFalse</span>\n</code></pre></div></div>\n\n<p>✅ Great!</p>\n\n<p>But what about failure? We would like to get an error that tells we were expecting either <code class=\"language-plaintext highlighter-rouge\">true</code> or <code class=\"language-plaintext highlighter-rouge\">false</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse boolean failure\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"notABoolean\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">boolean</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">,</span> <span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"s\">\"true\"</span><span class=\"o\">,</span> <span class=\"s\">\"false\"</span><span class=\"o\">))))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 Compilation error. Our current <code class=\"language-plaintext highlighter-rouge\">ParseError</code> class can only hold one expected <code class=\"language-plaintext highlighter-rouge\">String</code> and we now want a <code class=\"language-plaintext highlighter-rouge\">List</code> of them. Let’s change that class and fix all the compilation issues and we are still in red:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"notABoolean\"</span>, 0, List<span class=\"o\">(</span><span class=\"s2\">\"false\"</span><span class=\"o\">)))</span> did not equal Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"notABoolean\"</span>, 0, List<span class=\"o\">(</span><span class=\"s2\">\"true\"</span>, <span class=\"s2\">\"false\"</span><span class=\"o\">)))</span>\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at <span class=\"o\">(</span>JsonParserTest.scala:45<span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>When it fails to parse, our solution so far only keeps the last alternative it evaluated and complains about expecting only that last option. Let’s try to fix that:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"k\">def</span> <span class=\"nf\">|</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">match</span>\n      <span class=\"k\">case</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">)</span>\n      <span class=\"k\">case</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"n\">e1</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nf\">other</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">match</span>\n        <span class=\"k\">case</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">)</span>\n        <span class=\"k\">case</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"n\">e2</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nv\">e2</span><span class=\"o\">.</span><span class=\"py\">copy</span><span class=\"o\">(</span><span class=\"n\">expected</span> <span class=\"k\">=</span> <span class=\"nv\">e1</span><span class=\"o\">.</span><span class=\"py\">expected</span> <span class=\"o\">++</span> <span class=\"nv\">e2</span><span class=\"o\">.</span><span class=\"py\">expected</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>✅</p>\n\n<h2 id=\"parsing-arrays-of-2-boolean-values\">Parsing arrays… of 2 boolean values</h2>\n\n<p>Ok, I’m feeling lucky! Let’s try to parse something more difficult. What about <code class=\"language-plaintext highlighter-rouge\">[true, false]</code> or the other combinations of an array of two boolean values?</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse array of true values\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">booleanArray</span><span class=\"o\">(</span><span class=\"s\">\"[true,false]\"</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> \n    <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">true</span><span class=\"o\">),</span> <span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">false</span><span class=\"o\">))))</span>\n  <span class=\"o\">)</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴, of course.</p>\n\n<p>Let’s implement <code class=\"language-plaintext highlighter-rouge\">booleanArray</code> like we only cared about arrays of 2 booleans, for now:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>  <span class=\"k\">val</span> <span class=\"nv\">booleanArray</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n    <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">jsonBoolean</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">jsonBoolean</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>The first issue is we don’t have a sequencing combinator (<code class=\"language-plaintext highlighter-rouge\">**</code>) for parsers other than <code class=\"language-plaintext highlighter-rouge\">Parser[Int]</code>.  Let’s try to fix that. We want to generalize ` sequence<code class=\"language-plaintext highlighter-rouge\"> (</code>**`) to any kind of parsers.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n\t<span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">???</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n</code></pre></div></div>\n\n<p>First question arised. What should we return when we parse an <code class=\"language-plaintext highlighter-rouge\">A</code> and then a <code class=\"language-plaintext highlighter-rouge\">B</code>? It seems only natural to return the tuple of both values:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>,<span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"k\">for</span>\n      <span class=\"n\">a</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n      <span class=\"n\">b</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">other</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"o\">???)</span>\n    <span class=\"nf\">yield</span> <span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">,</span><span class=\"n\">b</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>But now we have another issue. We implemented <code class=\"language-plaintext highlighter-rouge\">sequence</code> for parsers that returned the position after parsing. But we now have parsers that already return a meaningful value (a <code class=\"language-plaintext highlighter-rouge\">JsonBoolean</code>) and we need to know the position after parsing so that we can combine them with other parsers in sequence.</p>\n\n<p>One solution is to redefine our <code class=\"language-plaintext highlighter-rouge\">Parser</code> type. We <code class=\"language-plaintext highlighter-rouge\">git stash save wip</code> our changes and:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">type</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"nc\">String</span><span class=\"o\">,</span> <span class=\"nc\">Int</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"o\">(</span><span class=\"kt\">A</span>, <span class=\"kt\">Int</span><span class=\"o\">)]</span>\n</code></pre></div></div>\n\n<p>🔴 Lots of things are broken, because the new <code class=\"language-plaintext highlighter-rouge\">Parser</code> type is not comptaible with the old one.</p>\n\n<p>Let’s just fix them. Some examples:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">startsWith</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">))</span> <span class=\"nc\">Right</span><span class=\"o\">(()</span> <span class=\"o\">-&gt;</span> <span class=\"o\">(</span><span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"nv\">token</span><span class=\"o\">.</span><span class=\"py\">length</span><span class=\"o\">))</span>\n  <span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">,</span> <span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"o\">)))</span>\n\n<span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"k\">def</span> <span class=\"nf\">map</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">f</span><span class=\"k\">:</span> <span class=\"kt\">A</span> <span class=\"o\">=&gt;</span> <span class=\"n\">B</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">((</span><span class=\"n\">a</span><span class=\"o\">,</span> <span class=\"n\">finalPosition</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nf\">f</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">finalPosition</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>In particular, let’s see how <code class=\"language-plaintext highlighter-rouge\">sequence</code> ends up <em class=\"sidenote-number\">implemented</em><em class=\"sidenote\">It seems the bug that makes destructuring not possible in for comprehensions, which is <a href=\"https://contributors.scala-lang.org/t/pre-sip-improve-for-comprehensions-functionality/3509\">an old friend of mine</a>, is still around in Scala 3. That was not expected. Oh, it seems to be resolved… <a href=\"https://dotty.epfl.ch/docs/reference/changed-features/pattern-bindings.html#pattern-bindings-in-for-expressions\">in the nightly build of upcoming Scala 3.3</a>.</em>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"k\">for</span>\n      <span class=\"n\">aI0</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n      <span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">,</span> <span class=\"n\">i0</span><span class=\"o\">)</span> <span class=\"k\">=</span> <span class=\"n\">aI0</span>\n      <span class=\"n\">bI1</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">other</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">i0</span><span class=\"o\">)</span>\n      <span class=\"o\">(</span><span class=\"n\">b</span><span class=\"o\">,</span> <span class=\"n\">i1</span><span class=\"o\">)</span> <span class=\"k\">=</span> <span class=\"n\">bI1</span>\n    <span class=\"nf\">yield</span> <span class=\"o\">(</span><span class=\"n\">a</span> <span class=\"o\">-&gt;</span> <span class=\"n\">b</span><span class=\"o\">)</span> <span class=\"o\">-&gt;</span> <span class=\"n\">i1</span>\n</code></pre></div></div>\n\n<p>And our tests for successful parsings need to be rewritten to add the position after parsing:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"s\">\"[]\"</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">),</span><span class=\"mi\">2</span><span class=\"o\">))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>✅ Green! ♻️ But those tests are starting to be unconvenient. All of our tests try to parse at position 0, like the end users of our parsers will do. And they tend to not care about what the final position of the parsing is. Let’s add another <code class=\"language-plaintext highlighter-rouge\">apply</code> for that:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"k\">def</span> <span class=\"nf\">apply</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_1</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>So our tests are now simpler:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"s\">\"[]\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>✅ But with one concern. We expect the end user parser to fail if we encounter unexpected content after parsing a json value:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array failure, unexpected content\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"[]wut?\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">2</span><span class=\"o\">,</span> <span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"s\">\"end of input\"</span><span class=\"o\">))))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 <code class=\"language-plaintext highlighter-rouge\">Right(JsonArray(List())) did not equal Left(ParseError(\"[]wut?\", 2, List(\"end of input\")))</code></p>\n\n<p>Let’s fix it:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">apply</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"k\">match</span>\n    <span class=\"k\">case</span> <span class=\"nc\">Right</span><span class=\"o\">((</span><span class=\"k\">_</span><span class=\"o\">,</span> <span class=\"n\">endPosition</span><span class=\"o\">))</span> <span class=\"k\">if</span> <span class=\"n\">endPosition</span> <span class=\"o\">&lt;</span> <span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">length</span> <span class=\"k\">=&gt;</span>\n      <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">endPosition</span><span class=\"o\">,</span> <span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"s\">\"end of input\"</span><span class=\"o\">)))</span>\n    <span class=\"k\">case</span> <span class=\"n\">r</span> <span class=\"k\">=&gt;</span> <span class=\"nv\">r</span><span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_1</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>✅  Good!</p>\n\n<p>♻️ But now, when a parser error says it was expecting <code class=\"language-plaintext highlighter-rouge\">end of input</code> does it mean the end of the input or the string <code class=\"language-plaintext highlighter-rouge\">\"end of input\"</code>? Let’s put all other string between quotes to distinguish that:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array failure, missing ]\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"[\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">1</span><span class=\"o\">,</span> <span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"s\">\"\\\"]\\\"\"</span><span class=\"o\">))))</span>\n<span class=\"o\">}</span>\n\n<span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array failure, unexpected content\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"[]wut?\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">2</span><span class=\"o\">,</span> <span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"s\">\"end of input\"</span><span class=\"o\">))))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>Now we can <code class=\"language-plaintext highlighter-rouge\">git stash pop</code> our parser of arrays of two booleans and finish it:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">booleanArray</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">boolean</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">boolean</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">))</span>\n    <span class=\"o\">.</span><span class=\"py\">map</span> <span class=\"o\">{</span> <span class=\"nf\">case</span> <span class=\"o\">((((</span><span class=\"k\">_</span><span class=\"o\">,</span> <span class=\"n\">b1</span><span class=\"o\">),</span> <span class=\"k\">_</span><span class=\"o\">),</span> <span class=\"n\">b2</span><span class=\"o\">),</span> <span class=\"k\">_</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"n\">b1</span><span class=\"o\">,</span> <span class=\"n\">b2</span><span class=\"o\">))</span> <span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>✅! ♻️ But that destructured argument to <code class=\"language-plaintext highlighter-rouge\">map</code> was ugly. Let’s try to fix it with some more sugar. My idea is that whenever we sequence a parser of <code class=\"language-plaintext highlighter-rouge\">Unit</code> and any other parser of any type <code class=\"language-plaintext highlighter-rouge\">A</code>, we don’t care about the <code class=\"language-plaintext highlighter-rouge\">Unit</code> value and we just want the <code class=\"language-plaintext highlighter-rouge\">A</code>, not a <code class=\"language-plaintext highlighter-rouge\">Pair&lt;Unit,A&gt;</code>. I’ll create an extension for <code class=\"language-plaintext highlighter-rouge\">Parser[Unit]</code> where <code class=\"language-plaintext highlighter-rouge\">sequence</code> ignores the <code class=\"language-plaintext highlighter-rouge\">Unit</code> and I’ll add a <code class=\"language-plaintext highlighter-rouge\">sequence</code> version taking a <code class=\"language-plaintext highlighter-rouge\">Parser[Unit]</code> that ignores that other <code class=\"language-plaintext highlighter-rouge\">Unit</code>. As I’ll need the original <code class=\"language-plaintext highlighter-rouge\">sequence</code> in multiple places, I define it at the root level:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">_sequence</span><span class=\"o\">[</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">a</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">],</span> <span class=\"n\">b</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"o\">...</span> \n\n<span class=\"nf\">extension</span> <span class=\"o\">(</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span>\n\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_2</span><span class=\"o\">)</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_2</span><span class=\"o\">)</span>\n\n<span class=\"n\">end</span> <span class=\"n\">extension</span>\n\n<span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">)</span>\n  <span class=\"nd\">@targetName</span><span class=\"o\">(</span><span class=\"s\">\"sequenceUnit\"</span><span class=\"o\">)</span>\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_1</span><span class=\"o\">)</span>\n\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"o\">)</span>\n  <span class=\"nd\">@targetName</span><span class=\"o\">(</span><span class=\"s\">\"starStarUnit\"</span><span class=\"o\">)</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"o\">)</span>\n\n<span class=\"n\">end</span> <span class=\"n\">extension</span>\n\n</code></pre></div></div>\n\n<p>Now our array parser is:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">booleanArray</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">boolean</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">boolean</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">))</span>\n    <span class=\"o\">.</span><span class=\"py\">map</span> <span class=\"o\">{</span> <span class=\"nf\">case</span> <span class=\"o\">(</span><span class=\"n\">b1</span><span class=\"o\">,</span> <span class=\"n\">b2</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"n\">b1</span><span class=\"o\">,</span> <span class=\"n\">b2</span><span class=\"o\">))</span> <span class=\"o\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"parsing-arrays-of-booleans\">Parsing arrays of booleans</h2>\n\n<p>Let’s say we want to parse arrays (of booleans) of any length, now:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse array of boolean values\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">length</span> <span class=\"k\">=</span> <span class=\"nv\">random</span><span class=\"o\">.</span><span class=\"py\">between</span><span class=\"o\">(</span><span class=\"mi\">3</span><span class=\"o\">,</span> <span class=\"mi\">5</span><span class=\"o\">)</span>\n  <span class=\"k\">val</span> <span class=\"nv\">booleans</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"mi\">0</span> <span class=\"n\">until</span> <span class=\"n\">length</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nv\">random</span><span class=\"o\">.</span><span class=\"py\">nextBoolean</span><span class=\"o\">()).</span><span class=\"py\">toList</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">booleanArray</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"s\">\"[${booleans.map(_.toString).mkString(\"</span><span class=\"o\">,</span><span class=\"s\">\")}]\"</span><span class=\"o\">)</span> <span class=\"o\">==</span>\n    <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">booleans</span><span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nc\">JsonBoolean</span><span class=\"o\">)))</span>\n  <span class=\"o\">)</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 After the second boolean it expects <code class=\"language-plaintext highlighter-rouge\">]</code> but we give it more booleans.</p>\n\n<p>This time, we will start by solving the problem with some combinators and <em>invent</em> new ones whenever we need them:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span>\n   <span class=\"o\">((</span><span class=\"n\">boolean</span> <span class=\"o\">**</span> <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">boolean</span><span class=\"o\">).</span><span class=\"py\">repeated</span><span class=\"o\">)</span> <span class=\"o\">|</span> <span class=\"n\">empty</span><span class=\"o\">)</span> <span class=\"o\">**</span> \n<span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>The idea is to have <code class=\"language-plaintext highlighter-rouge\">[</code>, then the array contents and then <code class=\"language-plaintext highlighter-rouge\">]</code>. The array contents may be empty or they may be a boolean followed by 0 or more times the combination of a comma and a boolean. But now we want our types to fit in this idea. Let’s see that in detail:</p>\n\n<p>We already know that <code class=\"language-plaintext highlighter-rouge\">(string(\",\") ** boolean)</code> is of type <code class=\"language-plaintext highlighter-rouge\">JsonBoolean</code></p>\n\n<p><code class=\"language-plaintext highlighter-rouge\">p.repeated</code> is intended to represent a parser that parses whatever <code class=\"language-plaintext highlighter-rouge\">p</code> parses any number of times, including 0. If <code class=\"language-plaintext highlighter-rouge\">p</code> is of type <code class=\"language-plaintext highlighter-rouge\">A</code>, then it will parse any number of chunks as instances of type <code class=\"language-plaintext highlighter-rouge\">A</code>, giving us a list of values of type <code class=\"language-plaintext highlighter-rouge\">A</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"k\">def</span> <span class=\"nf\">repeated</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]]</span> <span class=\"k\">=</span> <span class=\"o\">???</span>\n</code></pre></div></div>\n\n<p>Therefore, <code class=\"language-plaintext highlighter-rouge\">(string(\",\") ** boolean).repeated</code> gives us a <code class=\"language-plaintext highlighter-rouge\">List[JsonBoolean]</code>. And <code class=\"language-plaintext highlighter-rouge\">(boolean ** (string(\",\") ** boolean).repeated</code>, is of type  <code class=\"language-plaintext highlighter-rouge\">(JsonBoolean,List[JsonBoolean])</code>. If we want all in a <code class=\"language-plaintext highlighter-rouge\">JsonArray</code>, we must map that parser. The <code class=\"language-plaintext highlighter-rouge\">empty</code> parser returns whatever value we want; and we want an empty <code class=\"language-plaintext highlighter-rouge\">JsonArray</code>.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">booleanArray</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"o\">(</span>\n      <span class=\"o\">(</span><span class=\"n\">boolean</span> <span class=\"o\">**</span> <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">boolean</span><span class=\"o\">).</span><span class=\"py\">repeated</span><span class=\"o\">).</span><span class=\"py\">map</span> <span class=\"o\">{</span> <span class=\"nf\">case</span> <span class=\"o\">(</span><span class=\"n\">b</span><span class=\"o\">,</span> <span class=\"n\">l</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"n\">b</span> <span class=\"o\">::</span> <span class=\"n\">l</span><span class=\"o\">)}</span> <span class=\"o\">|</span> \n      <span class=\"nf\">empty</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n    <span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p class=\"figcaption\"><img src=\"../assets/recursiveRepetition.gif\" alt=\"repetition\" /></p>\n<p><em class=\"figcaption\">Repetition… by self-recursion! How cool is that?</em></p>\n\n<p>Now we need to implement <code class=\"language-plaintext highlighter-rouge\">repeated</code>. Here is one fancy way with just the combinators we already have and a recursive definition:</p>\n\n<p>We can define a parser <code class=\"language-plaintext highlighter-rouge\">repeated</code> that, when needed, tries to parse some content with <code class=\"language-plaintext highlighter-rouge\">repeated</code> itself. Like a function calling itself but with parsers.</p>\n\n<p>Let’s see how that turns out:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">repeated</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">self</span> <span class=\"o\">**</span> <span class=\"n\">repeated</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"o\">::</span> <span class=\"k\">_</span><span class=\"o\">)</span> <span class=\"o\">|</span> <span class=\"nf\">empty</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>It compiles! Let’s run our tests:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>An exception or error caused a run to abort. \njava.lang.StackOverflowError\n\tat com.agilogy.wapl.Parser<span class=\"nv\">$package$ParserOps</span>.repeated<span class=\"o\">(</span>Parser.scala:54<span class=\"o\">)</span>\n\tat com.agilogy.wapl.Parser<span class=\"nv\">$package$ParserOps</span>.repeated<span class=\"o\">(</span>Parser.scala:54<span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>🔴 Ops! When defining <code class=\"language-plaintext highlighter-rouge\">repeated</code> it calls <code class=\"language-plaintext highlighter-rouge\">repeated</code>. <code class=\"language-plaintext highlighter-rouge\">StackOverflowError</code>.</p>\n\n<p>But we may use some lazyness here. After all, <code class=\"language-plaintext highlighter-rouge\">sequence</code> (or <code class=\"language-plaintext highlighter-rouge\">**</code>) won’t need the second parser unless the first one succeeds. It seems only natural for it (and its variants) to evaluate that second parser lazyly:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">_sequence</span><span class=\"o\">[</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">a</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">],</span> <span class=\"n\">b</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n\n<span class=\"nf\">extension</span> <span class=\"o\">(</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span>\n\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_2</span><span class=\"o\">)</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_2</span><span class=\"o\">)</span>\n\n<span class=\"n\">end</span> <span class=\"n\">extension</span>\n\n<span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">)</span>\n  <span class=\"nd\">@targetName</span><span class=\"o\">(</span><span class=\"s\">\"sequenceUnit\"</span><span class=\"o\">)</span>\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"o\">,</span> <span class=\"n\">other</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">_1</span><span class=\"o\">)</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"o\">)</span>\n  <span class=\"nd\">@targetName</span><span class=\"o\">(</span><span class=\"s\">\"starStarUnit\"</span><span class=\"o\">)</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">_sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"o\">)</span>\n\n<span class=\"n\">end</span> <span class=\"n\">extension</span>\n</code></pre></div></div>\n\n<p>✅ ! But… What about long arrays. Let’s change our test to generate arrays of length <code class=\"language-plaintext highlighter-rouge\">random.between(10000, 10005)</code>:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>An exception or error caused a run to abort. \njava.lang.StackOverflowError\n\tat scala.runtime.BoxesRunTime.boxToInteger<span class=\"o\">(</span>BoxesRunTime.java:63<span class=\"o\">)</span>\n\tat com.agilogy.wapl.Parser<span class=\"nv\">$package$ParserOps</span>.map<span class=\"nv\">$$</span>anonfun<span class=\"nv\">$1</span><span class=\"o\">(</span>Parser.scala:37<span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>🔴 Ouch! This time the cause is not an infinite recursion, but simply one too deep. So let’s be a bit less fancy and implement <code class=\"language-plaintext highlighter-rouge\">repeated</code> by hand. That is, we run a tailrec loop where we try to parse the content with the parser we want repeatedly applied. If it doesn’t parse, we stop repeating and return the accumulated list of parsed values so far (which may be empty). If it does parse, we repeat at the new position.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">repeated</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nd\">@tailrec</span>\n  <span class=\"k\">def</span> <span class=\"nf\">loop</span><span class=\"o\">(</span><span class=\"n\">acc</span><span class=\"k\">:</span> <span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">],</span> <span class=\"n\">pos</span><span class=\"k\">:</span> <span class=\"kt\">Int</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"o\">(</span><span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">],</span><span class=\"nc\">Int</span><span class=\"o\">)</span> <span class=\"k\">=</span>\n    <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">pos</span><span class=\"o\">)</span> <span class=\"k\">match</span>\n      <span class=\"k\">case</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"k\">_</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">(</span><span class=\"nv\">acc</span><span class=\"o\">.</span><span class=\"py\">reverse</span><span class=\"o\">,</span> <span class=\"n\">pos</span><span class=\"o\">)</span>\n      <span class=\"k\">case</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">,</span> <span class=\"n\">newPos</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nf\">loop</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"o\">::</span><span class=\"n\">acc</span><span class=\"o\">,</span> <span class=\"n\">newPos</span><span class=\"o\">)</span>\n  <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nf\">loop</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>✅ !</p>\n\n<p>♻️ Let’s refactor a bit… We now have 2 array parsers: an <code class=\"language-plaintext highlighter-rouge\">array</code> parser that only accepts whitespace and a <code class=\"language-plaintext highlighter-rouge\">booleanArray</code> parser that only accepts booleans. Let’s remove the former and make the later accept whitespace by using <code class=\"language-plaintext sidenote-number highlighter-rouge\">whitespace</code><em class=\"sidenote\">I should, in fact, allow whitespace in many other places, like between the <code class=\"language-plaintext highlighter-rouge\">\",\"</code> and the next boolean. But let me add that to the backlog and keep going.</em> instead of <code class=\"language-plaintext highlighter-rouge\">empty</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span>\n    <span class=\"o\">((</span><span class=\"n\">boolean</span> <span class=\"o\">**</span> <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">boolean</span><span class=\"o\">).</span><span class=\"py\">repeated</span><span class=\"o\">).</span><span class=\"py\">map</span> <span class=\"o\">{</span>\n      <span class=\"nf\">case</span> <span class=\"o\">(</span><span class=\"n\">b</span><span class=\"o\">,</span> <span class=\"n\">l</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"n\">b</span> <span class=\"o\">::</span> <span class=\"n\">l</span><span class=\"o\">)</span>\n    <span class=\"o\">}</span> <span class=\"o\">|</span> <span class=\"nv\">whitespace</span><span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)))</span>\n    <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>✅</p>\n\n<h2 id=\"other-primitives\">Other primitives</h2>\n\n<p>Let me continue with the parsing of other primitive values. Let’s start with Json numbers. The grammar for Json numbers occupies some space of your screen but it is not complex:</p>\n\n<p><img src=\"../assets/json-number.png\" alt=\"img\" style=\"zoom:33%;\" /></p>\n\n<p>We chose to represent <code class=\"language-plaintext highlighter-rouge\">JsonNumber</code> by its internal string representation instead of trying to represent it with a numeric Scala or Java value. That allows us to just focus on <code class=\"language-plaintext highlighter-rouge\">Json</code> and let our users treat that number however <em class=\"sidenote-number\">they want</em><em class=\"sidenote\">Json numbers are decimal numbers without any bound. <code class=\"language-plaintext highlighter-rouge\">Int</code>, <code class=\"language-plaintext highlighter-rouge\">Long</code> and any other integer primitive type won’t be able to hold values if they are out of the allowed range of values. And <code class=\"language-plaintext highlighter-rouge\">Float</code> and <code class=\"language-plaintext highlighter-rouge\">Double</code> types, being floating point representations, won’t be able to correctly represent some decimal values. Still, in many occasions, a <code class=\"language-plaintext highlighter-rouge\">Long</code> or a <code class=\"language-plaintext highlighter-rouge\">Double</code> may suffice if you know your <code class=\"language-plaintext highlighter-rouge\">Json</code> use case is not amongst those that cause issues. We could use something like a BigDecimal, but I prefer to simply give our user the <code class=\"language-plaintext highlighter-rouge\">String</code> and let them decide how to use them.</em>. Now we won’t try to normalize parsed numbers, just parse them and return their string representation.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse json numbers\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">number</span><span class=\"o\">(</span><span class=\"s\">\"1\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"1\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">number</span><span class=\"o\">(</span><span class=\"s\">\"0.1\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"0.1\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">number</span><span class=\"o\">(</span><span class=\"s\">\"-0.1\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"-0.1\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">number</span><span class=\"o\">(</span><span class=\"s\">\"-0.1\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"-0.1\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">number</span><span class=\"o\">(</span><span class=\"s\">\"-0.1e2\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"-0.1e2\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">number</span><span class=\"o\">(</span><span class=\"s\">\"-0.1e+2\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"-0.1e+2\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">number</span><span class=\"o\">(</span><span class=\"s\">\"-0.1e-2\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"-0.1e-2\"</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 because it doesn’t compile and 🔴 once we write <code class=\"language-plaintext highlighter-rouge\">number</code> to return <code class=\"language-plaintext highlighter-rouge\">???</code>.</p>\n\n<p>We could parse numbers by hand with our current combinators, probably. But them being tokens, it seems easier to just use a Regex:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">number</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonNumber</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">regex</span><span class=\"o\">(</span><span class=\"s\">\"number\"</span><span class=\"o\">,</span> <span class=\"s\">\"-?([1-9][0-9]*|0)(\\\\.[0-9]+)?([eE][\\\\-+]?[0-9]+)?\"</span><span class=\"o\">.</span><span class=\"py\">r</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">JsonNumber</span><span class=\"o\">.</span><span class=\"py\">apply</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>Where:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">regex</span><span class=\"o\">(</span><span class=\"n\">label</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">,</span> <span class=\"n\">regex</span><span class=\"k\">:</span> <span class=\"kt\">Regex</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">String</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nv\">regex</span><span class=\"o\">.</span><span class=\"py\">findPrefixOf</span><span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">substring</span><span class=\"o\">(</span><span class=\"n\">position</span><span class=\"o\">))</span>\n    <span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"n\">m</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">m</span><span class=\"o\">,</span> <span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"nv\">m</span><span class=\"o\">.</span><span class=\"py\">length</span><span class=\"o\">))</span>\n    <span class=\"o\">.</span><span class=\"py\">getOrElse</span><span class=\"o\">(</span><span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">,</span> <span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"n\">label</span><span class=\"o\">))))</span>\n</code></pre></div></div>\n\n<p>✅ All tests green.</p>\n\n<p>What about <code class=\"language-plaintext highlighter-rouge\">Json</code> strings? The full grammar is:</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>string\n    '\"' characters '\"'\ncharacters\n    \"\"\n    character characters\ncharacter\n    '0020' .. '10FFFF' - '\"' - '\\'\n    '\\' escape\n</code></pre></div></div>\n\n<p>Let me implement just a simplified version where we don’t have escape characters. We can implement them fully later. To test valid characters I’ll test the two edge values. The char <code class=\"language-plaintext highlighter-rouge\">10FFFF</code> can be encoded in UTF-16 as <code class=\"language-plaintext highlighter-rouge\">0xDBFF 0xDFFF</code>. So:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse json strings\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"\\\"\\\"\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonString</span><span class=\"o\">(</span><span class=\"s\">\"\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"\\\"Json\\\"\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonString</span><span class=\"o\">(</span><span class=\"s\">\"Json\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"\\\"No només ASCII\\\"\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonString</span><span class=\"o\">(</span><span class=\"s\">\"No només ASCII\"</span><span class=\"o\">)))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"\\\"\\u0020\\udbff\\udfff\\\"\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonString</span><span class=\"o\">(</span><span class=\"s\">\"\\u0020\\udbff\\udfff\"</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 In fact, I find I used the name <code class=\"language-plaintext highlighter-rouge\">string</code> for generic parsers and now I want to use it for <code class=\"language-plaintext highlighter-rouge\">JsonParser</code>. I don’t like the mess I get where I need to import the correct one, so I rename the generic parsers <code class=\"language-plaintext highlighter-rouge\">string</code> to <code class=\"language-plaintext highlighter-rouge\">token</code> and add a <code class=\"language-plaintext highlighter-rouge\">string</code> parser to <code class=\"language-plaintext highlighter-rouge\">JsonParser</code>. Now it compiles, let’s implement it so it passes the tests.</p>\n\n<p>As I’m just implementing a simplified version without escape chars, I’ll just use another regex to accept any char that is not a <code class=\"language-plaintext highlighter-rouge\">\"</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">string</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonString</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nf\">regex</span><span class=\"o\">(</span><span class=\"s\">\"string\"</span><span class=\"o\">,</span> <span class=\"s\">\"\\\"[^\\\"]*\\\"\"</span><span class=\"o\">.</span><span class=\"py\">r</span><span class=\"o\">)</span>\n  <span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"n\">s</span> <span class=\"k\">=&gt;</span>  <span class=\"nc\">JsonString</span><span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">substring</span><span class=\"o\">(</span><span class=\"mi\">1</span><span class=\"o\">,</span> <span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">length</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"o\">)))</span>\n</code></pre></div></div>\n\n<p>✅ Done!</p>\n\n<h2 id=\"parsing-json-arrays-at-last-without-objects\">Parsing Json arrays, at last… (without objects)</h2>\n\n<p>Now I can close the circle and try to implement arrays of arbitrary Json values… except objects which I don’t have implemented yet.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>  <span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse array of values and arrays\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n    <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"s\">\"[1,false,\\\"hello\\\",[true,3]]\"</span><span class=\"o\">)</span> <span class=\"o\">==</span>\n      <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nc\">List</span><span class=\"o\">(</span>\n        <span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"1\"</span><span class=\"o\">),</span>\n        <span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">false</span><span class=\"o\">),</span>\n        <span class=\"nc\">JsonString</span><span class=\"o\">(</span><span class=\"s\">\"hello\"</span><span class=\"o\">),</span>\n        <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"nc\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kc\">true</span><span class=\"o\">),</span> <span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"3\"</span><span class=\"o\">)))</span>\n      <span class=\"o\">))))</span>\n  <span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 This time it compiles, but the test fails with:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Expected :Right<span class=\"o\">(</span>...<span class=\"o\">)</span>\nActual   :Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"[1,false,\"</span>hello<span class=\"s2\">\",[true,3]]\"</span>, 1, List<span class=\"o\">(</span><span class=\"s2\">\"\"</span><span class=\"o\">]</span><span class=\"s2\">\"\"</span><span class=\"o\">)))</span>\n</code></pre></div></div>\n\n<p>I don’t like that error message very much. That’s my fault, as I have paid no attention to error messages for many commits now. But I’m in the midle of a Red-Green-Refactor cycle, so this is not the moment. Let’s add that to a backlog. And now let’s focus on the task at hand. My approach is to finally parse any <code class=\"language-plaintext highlighter-rouge\">Json</code> value we support so far:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">json</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"n\">boolean</span> <span class=\"o\">|</span> <span class=\"n\">string</span> <span class=\"o\">|</span> <span class=\"n\">number</span> <span class=\"o\">|</span> <span class=\"n\">array</span>\n</code></pre></div></div>\n\n<p>And now <code class=\"language-plaintext highlighter-rouge\">array</code> can contain <code class=\"language-plaintext highlighter-rouge\">json</code> values instead of just <code class=\"language-plaintext highlighter-rouge\">boolean</code> values:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"o\">(</span>\n      <span class=\"o\">(</span><span class=\"n\">json</span> <span class=\"o\">**</span> <span class=\"o\">(</span><span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">json</span><span class=\"o\">).</span><span class=\"py\">repeated</span><span class=\"o\">).</span><span class=\"py\">map</span> <span class=\"o\">{</span> <span class=\"nf\">case</span> <span class=\"o\">(</span><span class=\"n\">b</span><span class=\"o\">,</span> <span class=\"n\">l</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"n\">b</span> <span class=\"o\">::</span> <span class=\"n\">l</span><span class=\"o\">)</span> <span class=\"o\">}</span> <span class=\"o\">|</span> \n      <span class=\"nf\">whitespace</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n  <span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>My IntelliJ warns me that referring <code class=\"language-plaintext highlighter-rouge\">json</code>, which I have defined after <code class=\"language-plaintext highlighter-rouge\">array</code>, is a suspicious forward reference. Furthermore, the reference is circular, because <code class=\"language-plaintext highlighter-rouge\">array</code> uses <code class=\"language-plaintext highlighter-rouge\">json</code> and <code class=\"language-plaintext highlighter-rouge\">json</code> uses <code class=\"language-plaintext highlighter-rouge\">array</code>.  But let’s just run the tests and see what happens…</p>\n\n<p>✅ Wow! How that even worked? Remember we defined <code class=\"language-plaintext highlighter-rouge\">**</code>’s second parameter to be lazyly evaluated and, therefore,  <code class=\"language-plaintext highlighter-rouge\">json</code> wont’t get immediately evaluated when defining <code class=\"language-plaintext highlighter-rouge\">array</code>. It is no longer using a forward reference before that reference takes a value. And there is no more a problematic circular reference: when defining <code class=\"language-plaintext highlighter-rouge\">array</code> it won’t use <code class=\"language-plaintext highlighter-rouge\">json</code> right away, then <code class=\"language-plaintext highlighter-rouge\">json</code> will get defined and, finally, by when we use the <code class=\"language-plaintext highlighter-rouge\">array</code> parser, <code class=\"language-plaintext highlighter-rouge\">json</code> will have been already evaluated.</p>\n\n<p>♻️ Refactor? There may be many options. I’ll peek some:</p>\n\n<ul>\n  <li>\n    <p>Make <code class=\"language-plaintext highlighter-rouge\">|</code>’s second parameter lazyly evaluated like we do in <code class=\"language-plaintext highlighter-rouge\">**</code>. After all, the second argument to <code class=\"language-plaintext highlighter-rouge\">|</code> will only be needed if the first argument fails to parse.</p>\n  </li>\n  <li>\n    <p>Sort the tests so all Json primitive tests go first and all array tests come later.</p>\n  </li>\n  <li>\n    <p>Mark parsers not representing json types private: <code class=\"language-plaintext highlighter-rouge\">whitespace</code>, <code class=\"language-plaintext highlighter-rouge\">jsonTrue</code>, <code class=\"language-plaintext highlighter-rouge\">jsonFalse</code></p>\n  </li>\n  <li>\n    <p>Add a helper function for the usual case where we map to some value ignoring the current value ( e.g. <code class=\"language-plaintext highlighter-rouge\">p.map(_ =&gt; JsonBoolean(true))</code>): <code class=\"language-plaintext highlighter-rouge\">p.as(JsonBoolean(true))</code>.</p>\n  </li>\n</ul>\n\n<h2 id=\"parsing-objects\">Parsing objects</h2>\n\n<p>And now, objects! Let’s go directly to the TDD cycle:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse object\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"{\\\"a\\\":23,\\\"b\\\":[{\\\"c\\\":null}]}\"</span>\n  <span class=\"k\">val</span> <span class=\"nv\">expected</span> <span class=\"k\">=</span> <span class=\"nc\">JsonObject</span><span class=\"o\">(</span><span class=\"nc\">Map</span><span class=\"o\">(</span>\n    <span class=\"s\">\"a\"</span> <span class=\"o\">-&gt;</span> <span class=\"nc\">JsonNumber</span><span class=\"o\">(</span><span class=\"s\">\"23\"</span><span class=\"o\">),</span>\n    <span class=\"s\">\"b\"</span> <span class=\"o\">-&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nc\">List</span><span class=\"o\">(</span><span class=\"nc\">JsonObject</span><span class=\"o\">(</span><span class=\"nc\">Map</span><span class=\"o\">(</span><span class=\"s\">\"c\"</span> <span class=\"o\">-&gt;</span> <span class=\"nc\">JsonNull</span><span class=\"o\">))))</span>\n  <span class=\"o\">))</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">json</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">expected</span><span class=\"o\">))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 Red, of course.</p>\n\n<p>Let’s just copy the <code class=\"language-plaintext highlighter-rouge\">array</code> solution but parse object members (a key, <code class=\"language-plaintext highlighter-rouge\">\":\"</code> and a value) instead of just values:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">member</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">String</span>, <span class=\"kt\">Json</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"nv\">string</span><span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">_</span><span class=\"o\">.</span><span class=\"py\">value</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\":\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">json</span>\n\n<span class=\"k\">val</span> <span class=\"nv\">obj</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"{\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"o\">(</span>\n    <span class=\"o\">(</span><span class=\"n\">member</span> <span class=\"o\">**</span> <span class=\"o\">(</span><span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">member</span><span class=\"o\">).</span><span class=\"py\">repeated</span><span class=\"o\">).</span><span class=\"py\">map</span> <span class=\"o\">{</span> <span class=\"nf\">case</span> <span class=\"o\">(</span><span class=\"n\">b</span><span class=\"o\">,</span> <span class=\"n\">l</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonObject</span><span class=\"o\">((</span><span class=\"n\">b</span> <span class=\"o\">::</span> <span class=\"n\">l</span><span class=\"o\">).</span><span class=\"py\">toMap</span><span class=\"o\">)</span> <span class=\"o\">}</span> <span class=\"o\">|</span> \n    <span class=\"nv\">whitespace</span><span class=\"o\">.</span><span class=\"py\">as</span><span class=\"o\">(</span><span class=\"nc\">JsonObject</span><span class=\"o\">(</span><span class=\"nv\">Map</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n  <span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"}\"</span><span class=\"o\">)</span>\n\n<span class=\"k\">val</span> <span class=\"nv\">json</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"n\">boolean</span> <span class=\"o\">|</span> <span class=\"n\">string</span> <span class=\"o\">|</span> <span class=\"n\">number</span> <span class=\"o\">|</span> <span class=\"n\">array</span> <span class=\"o\">|</span> <span class=\"n\">obj</span>\n</code></pre></div></div>\n\n<p>🔴 What!?</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Expected :Right<span class=\"o\">(</span>JsonObject<span class=\"o\">(</span>Map<span class=\"o\">(</span><span class=\"s2\">\"a\"</span> -&gt; JsonNumber<span class=\"o\">(</span><span class=\"s2\">\"23\"</span><span class=\"o\">)</span>, <span class=\"s2\">\"b\"</span> -&gt; JsonArray<span class=\"o\">(</span>List<span class=\"o\">(</span>JsonObject<span class=\"o\">(</span>Map<span class=\"o\">(</span><span class=\"s2\">\"c\"</span> -&gt; JsonNull<span class=\"o\">)))))))</span>\nActual   :Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"{\"</span>a<span class=\"s2\">\":23,\"</span>b<span class=\"s2\">\":[{\"</span>c<span class=\"s2\">\":null}]}\"</span>, 7, List<span class=\"o\">(</span><span class=\"s2\">\"\"</span><span class=\"nb\">true</span><span class=\"s2\">\"\"</span>, <span class=\"s2\">\"\"</span><span class=\"nb\">false</span><span class=\"s2\">\"\"</span>, <span class=\"s2\">\"string\"</span>, <span class=\"s2\">\"number\"</span>, <span class=\"s2\">\"\"</span><span class=\"o\">[</span><span class=\"s2\">\"\"</span>, <span class=\"s2\">\"\"</span><span class=\"o\">}</span><span class=\"s2\">\"\"</span><span class=\"o\">)))</span>\n</code></pre></div></div>\n\n<p>Why on earth is it complaining about position 7? What is to be found there is clearly a member <code class=\"language-plaintext highlighter-rouge\">\"b\":[{\"c\":null}]</code>…</p>\n\n<p>After actually spending a lot of minutes trying to figure out here it is: <code class=\"language-plaintext highlighter-rouge\">json</code> does not yet support nulls. That is of course my fault for using <code class=\"language-plaintext highlighter-rouge\">null</code> in my test when I don’t yet support it. But, why such an ugly error message?? Let me add that to the backlog too and fix the issue now that we know what it was.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">jsonNull</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonNull.</span><span class=\"k\">type</span><span class=\"o\">]</span>  <span class=\"k\">=</span> <span class=\"s\">\"null\"</span><span class=\"o\">.</span><span class=\"py\">as</span><span class=\"o\">(</span><span class=\"nc\">JsonNull</span><span class=\"o\">)</span>\n<span class=\"k\">val</span> <span class=\"nv\">json</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"n\">boolean</span> <span class=\"o\">|</span> <span class=\"n\">string</span> <span class=\"o\">|</span> <span class=\"n\">number</span> <span class=\"o\">|</span> <span class=\"n\">jsonNull</span> <span class=\"o\">|</span> <span class=\"n\">array</span> <span class=\"o\">|</span> <span class=\"n\">obj</span>\n</code></pre></div></div>\n\n<p>✅ Wa yeah!</p>\n\n<h2 id=\"our-parsing-library-so-far\">Our parsing library so far</h2>\n\n<p>The current version of our parser library so far has these functions:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">type</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"nc\">String</span><span class=\"o\">,</span> <span class=\"nc\">Int</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"o\">(</span><span class=\"kt\">A</span>, <span class=\"kt\">Int</span><span class=\"o\">)]</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">...</span>\n<span class=\"k\">def</span> <span class=\"nf\">empty</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">value</span><span class=\"k\">:</span> <span class=\"kt\">A</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"k\">_</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">...</span>\n<span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">a</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">],</span> <span class=\"n\">b</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> \n  <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">...</span>\n<span class=\"k\">def</span> <span class=\"nf\">regex</span><span class=\"o\">(</span><span class=\"n\">label</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">,</span> <span class=\"n\">regex</span><span class=\"k\">:</span> <span class=\"kt\">Regex</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">String</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">...</span>\n\n<span class=\"nf\">extension</span> <span class=\"o\">(</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span>\n\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n\n<span class=\"n\">end</span> <span class=\"n\">extension</span>\n\n<span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n\n  <span class=\"k\">def</span> <span class=\"nf\">apply</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">map</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">f</span><span class=\"k\">:</span> <span class=\"kt\">A</span> <span class=\"o\">=&gt;</span> <span class=\"n\">B</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">as</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">b</span><span class=\"k\">:</span> <span class=\"kt\">B</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">|</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">...</span>\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"o\">=&gt;</span> <span class=\"nc\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[(</span><span class=\"kt\">A</span>, <span class=\"kt\">B</span><span class=\"o\">)]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">repeated</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"o\">...</span>\n\n<span class=\"n\">end</span> <span class=\"n\">extension</span>\n</code></pre></div></div>\n\n<p>If we examine the functions returning <code class=\"language-plaintext highlighter-rouge\">Parser</code> carefully we’ll see that most of them are defined by the implementation of the actual parser, where we receive the string and the position and return the parse result. We’ll call those, primitives. But some others, like <code class=\"language-plaintext highlighter-rouge\">as</code>, are derived from the primitives; we don’t implement them by saying how they handle the string and the position to return a parse result but we derive them from some other(s) parser(s) and applying functions on them.</p>\n\n<p>We can, in fact, further refactor our current solution to discover more useful derived functions.</p>\n\n<p>One of them may be useful to represent the repetition of values with some separator:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">separatedBy</span><span class=\"o\">(</span><span class=\"n\">separator</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]]</span> <span class=\"k\">=</span>\n  <span class=\"o\">(</span><span class=\"n\">self</span> <span class=\"o\">**</span> <span class=\"o\">(</span><span class=\"n\">separator</span> <span class=\"o\">**</span> <span class=\"n\">self</span><span class=\"o\">).</span><span class=\"py\">repeated</span><span class=\"o\">).</span><span class=\"py\">map</span> <span class=\"o\">{</span> <span class=\"nf\">case</span> <span class=\"o\">(</span><span class=\"n\">h</span><span class=\"o\">,</span> <span class=\"n\">t</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"n\">h</span> <span class=\"o\">::</span> <span class=\"n\">t</span> <span class=\"o\">}</span> <span class=\"o\">|</span> <span class=\"nf\">empty</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span> \n</code></pre></div></div>\n\n<p>And now we can simplify a couple of definitions in <code class=\"language-plaintext highlighter-rouge\">JsonParser</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">whitespace</span> <span class=\"o\">**</span> \n    <span class=\"nv\">json</span><span class=\"o\">.</span><span class=\"py\">separatedBy</span><span class=\"o\">(</span><span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">JsonArray</span><span class=\"o\">.</span><span class=\"py\">apply</span><span class=\"o\">)</span> \n    <span class=\"o\">**</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)</span>\n<span class=\"k\">val</span> <span class=\"nv\">obj</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"{\"</span><span class=\"o\">)</span> <span class=\"o\">**</span>\n    <span class=\"nv\">member</span><span class=\"o\">.</span><span class=\"py\">separatedBy</span><span class=\"o\">(</span><span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">)).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"n\">members</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonObject</span><span class=\"o\">(</span><span class=\"nv\">members</span><span class=\"o\">.</span><span class=\"py\">toMap</span><span class=\"o\">))</span>\n    <span class=\"o\">**</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"}\"</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>This being Scala (3) we could add some more sugar. Those <code class=\"language-plaintext highlighter-rouge\">token(\"foo\")</code> could be replaced with their string value directly:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">given</span> <span class=\"nc\">Conversion</span><span class=\"o\">[</span><span class=\"kt\">String</span>, <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">]]</span> <span class=\"k\">with</span>\n  <span class=\"k\">def</span> <span class=\"nf\">apply</span><span class=\"o\">(</span><span class=\"n\">str</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"n\">str</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>So now we can write parsers like these:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"s\">\"[\"</span> <span class=\"o\">**</span> <span class=\"n\">whitespace</span> <span class=\"o\">**</span> <span class=\"nv\">json</span><span class=\"o\">.</span><span class=\"py\">separatedBy</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"nv\">JsonArray</span><span class=\"o\">.</span><span class=\"py\">apply</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"nf\">token</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)</span>\n<span class=\"k\">val</span> <span class=\"nv\">obj</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"s\">\"{\"</span> <span class=\"o\">**</span> <span class=\"nv\">member</span><span class=\"o\">.</span><span class=\"py\">separatedBy</span><span class=\"o\">(</span><span class=\"s\">\",\"</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"n\">members</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonObject</span><span class=\"o\">(</span><span class=\"nv\">members</span><span class=\"o\">.</span><span class=\"py\">toMap</span><span class=\"o\">))</span> <span class=\"o\">**</span> <span class=\"s\">\"}\"</span>\n</code></pre></div></div>\n\n<h2 id=\"our-json-parser-so-far\">Our Json parser so far</h2>\n\n<p>We have now a quite capable Json parser. Some known limitations we may want to overcome:</p>\n\n<ul>\n  <li>It can’t parse Json with whitespace properly</li>\n  <li>It can’t parse strings with escape sequences</li>\n  <li>It has very limited error handling capabilities</li>\n</ul>\n\n<h2 id=\"conclusions\">Conclusions</h2>\n\n<p>After the very limited but promising features developed in the first part of the series, we developed an almost complete Json parser using a TDD aproach. At the same time, at each “refactor” phase, we abstracted a bunch of useful parser combinator functions, therefore developing a parser combinator library, as we intended.</p>\n\n<p>Beyond the (known) limitations of our Json parser, we now have a quite capable parser combinator library… although we only tested one example grammar we developed with it. And this is one of the drawbacks of this approach compared to the approach in the <a href=\"https://www.manning.com/books/functional-programming-in-scala\">Red book</a>. We now have a parser combinator library but we don’t have any tests of the library itself, but just tests of one example parser we implemented with it.</p>\n\n<p>You can see the complete source code of this post here: https://github.com/agile-jordi/writingAParserLibrary/tree/part2.</p>\n\n<h2 id=\"all-articles-in-the-series\">All articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-11-11-writing-a-parser-combinator-library-1.html\">Writing a Parser Combinator Library in Scala 3. Part 1: Introduction to Parsing</a></li>\n  <li><a href=\"./2022-12-16-writing-a-parser-combinator-library-2.html\">Writing a parser library in Scala. Part 2: Choices and repetitions</a></li>\n</ol>\n\n",
            "url": "https://blog.agilogy.com/2022-12-16-writing-a-parser-combinator-library-2.html",
            "date_published": "2022-12-16T00:00:00+01:00",
            "date_modified": "2022-12-16T00:00:00+01:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-11-11-writing-a-parser-combinator-library-1.html",
            "title": "Writing a Parser Combinator Library in Scala 3.<br> Part 1: Introduction to Parsing",
            "content_text": "You know I like to write libraries from scratch. I find this to be a longer but better kata, where you implement something you could actually use. And, who knows, after the zombie apocalypse, once we recover from everything else, you may need a parsers library and all the good old ones are gone forever. So, let’s survive the apocalypse by writing one ourselves.\n\nTo do so I’ll use the perfect excuse. I want to write yet another Json parser. I want it to be reasonable fast but, above everything else, I want it to be crystal clear when it comes to report errors. At least as good as  those of most Json parsers I use, or better. Because if we are going to write a library from scracth let’s make it professional grade at least in one aspect.\n\nDisclaimer 1: Scala 3 and my experience with it (or lack of thereof)\n\nThis time I’ll use Scala. I’ve been blogging about Kotlin recently but I’ve been a Scala developer for years and I use both now. And I’ll be writing Scala 3 for the first time (not counting some small divertimentos), so be patient and kind if something I write is not completely idiomatic in Scala 3 or if the library we end up with does not take advantage of every single Scala 3 wonderful new feature.\n\nDisclaimer 2: Inspiration and destination\n\nOk, I’ll admit it up front. I will end up writing a parser combinator library. And it so happens that the language (Scala) and example (Json) I have chosen are the same the famous Red book uses. Why write about it, then, if you can read Paul Chiusano and Runar Bjarnason? First of all, no matter what, you must read the red book if you haven’t yetYou probably can read it again if you already have and you will probably still learn a ton of things..  But I’ll try my best at a different approach to the parser combinator library. Instead of applying algebraic design, I’ll use a classical TDD approach.\n\n\n\nThere are a couple of points I’d like to make with this:\n\n\n  You can design something like parser combinators using TDD; algebraic design is just one way, not the only way. Applying TDD like I’ll do is not without drawbacks but it may work for you.\n  You don’t need to know obscure mathematics and the terrible M word to design a parser combinator library. Or, to put it another way, monads are not your enemy and they aren’t something you should be afraid of… when they excel at the job at hand. You may have ended designing a similar solution without being a fan of monads. What is more, you may have designed a much less elegant solution if you were to design it from scracth without monads.\n\n\nParsing what?\n\nLet’s parse Json. For that, let’s write a Json type:\n\nenum Json:\n  case JsonString(value: String)\n  case JsonNumber(value: String)\n  case JsonBoolean(value: Boolean)\n  case JsonNull\n  case JsonArray(value: List[Json])\n  case JsonObject(value: Map[String, Json])\n\n\nYou may think JsonNumber(value: String) is an odd choice. I’ll talk about this in the future. Trust me with that one. But in any case, for the matter of this series, it doesn’t matter that much if you prefer to model them as JsonNumber(value: Double) or something else.\n\nDone. Now the parser…\n\nWhat is a parser?\n\nLet me try to answer this question with some requirements…\n\nLet’s start by just parsing something simple, like an empty array. Acording to json.org an array is:\n\n\n\nHere whitespace represents any number of whitespace characters. It may be the empty string.\n\nSo, setting aside the parsing of values inside the array, we want a function that given the String \"[ ]\" returns JsonArray(List.empty) (for any number and type of whitespace characters between the brackets).\n\nLet’s do it TDD style:\n\ntest(\"Parse empty array\") {\n  assert(parseArray(\"[]\") == JsonArray(List.empty))\n}\n\n\n🔴 Red. Easy peasy:\n\nobject JsonParser:\n  def parseArray(s: String): JsonArray = JsonArray(List.empty)\n\n\n✅ Green!\n\nLet’s delay the implementation of whitespace. What else do we need? Here is what: What do we want the parser to do if feeded only with \"[\"? We expect it to fail. The failure should tell us where it failed and what was expected. That is, we failed at the second character (s[1]) where we expected ] but we found the end of the string.\n\nWe can deal with errors with exceptions, with Try, with Either or with a custom type. Let’s try using Either:\n\ntest(\"Parse empty array\") {\n  assert(parseArray(\"[]\") == Right(JsonArray(List.empty)))\n}\n\ntest(\"Parse empty array failure\") {\n  val input = \"[\"\n  assert(parseArray(input) == Left(ParseError(input, 1, expected = \"]\")))\n}\n\n\n🔴 It does not even compile. Let’s create the ParseError class and change the parseArray signature:\n\ncase class ParseError(input: String, position: Int, expected: String)\n\nobject JsonParser:\n  def parseArray(s: String): Either[ParseError, JsonArray] = Right(JsonArray(List.empty))\n\n\n🔴 It now compiles but…\n\nRight(JsonArray(List())) did not equal Left(ParseError(\"[\", 1, \"]\"))\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at (JsonParserTest.scala:17)\nExpected :Left(ParseError(\"[\", 1, \"]\"))\nActual   :Right(JsonArray(List()))\n\n\nNow what? We could DTSTTCPW and just implement parseArray to return this particular error when the input string is \"[\". But this is not a bad TDD training Just in case: I’m not saying TDD is bad at all, of course. Neither I’m saying training people in TDD with really small steps is bad. I’m just making a joke about confusing baby steps with implementing each test case with an if/else branch. Even though I’m making a bit of a pun to code without designing, which should be the opposite of TDD.. So let’s think a bit and design a solution.\n\nLooking at the json.org diagram above, we see [ and ] are different nodes in the grammar chart. Maybe our mission of parsing just the empty array was more than we can chew now, afer all. Let’s try something simpler. Let’s try to parse the [ token. So let’s git stash save wip or comment out our failing test We are doing TDD right, no? And we are in the midle of a red. So let’s go back to green, make an increment, and we will retake what we where doing when in green again.and start anew. Parsing a token, when it succeeds, can only do so in one way. When succeeding, therefore, we only need the Unit value as a return:\n\ntest(\"Parse start array token\") {\n  assert(parseStartArrayToken(\"[\") == Right(()))\n}\n\ntest(\"Parse start array token failure\") {\n  val input = \"notTheStartArrayToken\"\n  assert(parseStartArrayToken(input) == Left(ParseError(input, 0, expected = \"[\")))\n}\n\n\n🔴 Does not compile. Let’s go directly to green:\n\ndef parseStartArrayToken(s: String): Either[ParseError, Unit] =\n\tif (s == \"[\") Right(()) else Left(ParseError(s, 0, \"[\"))\n\n\n✅ Now refactor ♻️. You see, I’m going to try to parse the ] token. So it seems we are going to parse tokens in general. Let’s refactor that:\n\ndef parseToken(s: String, token: String): Either[ParseError, Unit] =\n  if (s == token) Right(()) else Left(ParseError(s, 0, token))\n\n\nMmmm… 🤔 I prefer the token to be the first argument… and the string to be a second argument list:\n\ndef parseToken(token: String)(s: String): Either[ParseError, Unit] = ...\n\n\nAnd our tests are now:\n\ntest(\"Parse token\") {\n  assert(parseToken(\"[\")(\"[\") == Right(()))\n}\n\ntest(\"Parse token failure\") {\n  val input = \"notTheStartArrayToken\"\n  assert(parseToken(\"[\")(input) == Left(ParseError(input, 0, expected = \"[\")))\n}\n\n\nGreat!\n\nNow we want to parse the token [ and then the token ]. That’s the question. And here is a simple idea: we want our token parser to be able to parse any string that starts with that token:\n\ndef parseToken(token: String)(s: String): Either[ParseError, Unit] =\n  if (s.startsWith(token)) Right(()) else Left(ParseError(s, 0, token))\n\n\nAfter parsing [ in \"[]\" we now know that the string starts with [ and that we can continue to parse ]… after the [. I could play with our current design like this:\n\ndef parseArray(s: String): Either[ParseError, JsonArray] =\n  parseToken(\"[\")(s) match\n    case Right(()) =&gt;\n      parseToken(\"]\")(s.substring(1)) match {\n        case Right(()) =&gt; Right(JsonArray(List.empty))\n        case Left(e) =&gt; Left(e)\n      }\n    case Left(e) =&gt; Left(e)\n\n\nOr, monadically idiomatically:\n\ndef parseArray(s: String): Either[ParseError, JsonArray] =\n  for\n    _ &lt;- parseToken(\"[\")(s)\n    _ &lt;- parseToken(\"]\")(s.substring(1))\n  yield JsonArray(List.empty)\n\n\n✅! But if you now git stash pop or uncomment our \"Parse empty array failure\" test:\n\ntest(\"Parse empty array failure\") {\n  val input = \"[\"\n  assert(parseArray(input) == Left(ParseError(input, 1, expected = \"]\")))\n}\n\n\n🔴 The test fails:\n\nLeft(ParseError(\"\", 0, \"]\")) did not equal Left(ParseError(\"[\", 1, \"]\"))\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at (JsonParserTest.scala:17)\nExpected :Left(ParseError(\"[\", 1, \"]\"))\nActual   :Left(ParseError(\"\", 0, \"]\"))\n\n\nSo, the parser correctly fails to parse, but it is telling us that it expected \"]\" at position 0 (where we have \"[\") instead of telling us it expected it at position 1. And it tells us the string that failed to compile is \"\" when it should complain about the actual string it got: \"[\". Why? As we passed the substring(1) to the second parseToken, the input and position values of the resulting error are wrong. We want the error to contain the entire string and the position to be a position of that string, so we will need them in our parseArray function. And once we have the original input and the position we want to parse at, we no longer need the substring. We can simply check whether the string starts with the token at that index:Yes, there is a version of startsWith that takes an index. No, I didn’t know either.\n\ndef parseToken(token: String)(s: String, position: Int): Either[ParseError, Unit] =\n  if (s.startsWith(token, position)) Right(()) else Left(ParseError(s, position, token))\n\nSo now:\ndef parseArray(s: String): Either[ParseError, JsonArray] =\n  for\n    _ &lt;- parseToken(\"[\")(s, 0)\n    _ &lt;- parseToken(\"]\")(s, 1)\n  yield JsonArray(List.empty)\n\n\nAnd after fixing the compilation errors of adding a new parameter… ✅ Green!\n\n🤔 Do you remember what this section was about? The question was: “What is a parser”? Looking at our parseToken we have one possible answerMind the gap. We will refine this answer later in the series. now: A parser is a function that given a String input and a position in that string either returns a parsed value (like the empty array above) or a parse failure:\n\ntype Parser[A] = (String, Int) =&gt; Either[ParseError, A]\n\n\n♻️ We ended our previous TDD cycle with green. A refactor is due. But what are we going to refactor? 🤔\n\nWith that definition you don’t even need to squint too hard to see that parseToken can be seen as a function that given a String (the token) returns a parser:\n\ndef parseToken(token: String): Parser[Unit] = (s, position) =&gt;\n  if (s.startsWith(token, position)) Right(()) else Left(ParseError(s, position, token))\n\n\nAs parseToken it is no longer parsing any token but returning a parser of strings, maybe we better call it string:\n\ndef string(token: String): Parser[Unit] = (s, position) =&gt;\n  if (s.startsWith(token, position)) Right(()) else Left(ParseError(s, position, token))\n\n\nNow, why not make our parseArray a parser too?\n\ndef parseArray(): Parser[JsonArray] = (s, position) =&gt;\n  for\n    _ &lt;- string(\"[\")(s, position)\n    _ &lt;- string(\"]\")(s, position + 1)\n  yield JsonArray(List.empty)\n\n\nAnd as it is not taking arguments, why not make it a value?:\n\nobject JsonParser:\n  val array: Parser[JsonArray] = (s, position) =&gt;\n    for\n      _ &lt;- string(\"[\")(s, position)\n      _ &lt;- string(\"]\")(s, position + 1)\n    yield JsonArray(List.empty)\n\n\n\nAnd our tests:\n\ntest(\"Parse empty array\") {\n  assert(array(\"[]\", 0) == Right(JsonArray(List.empty)))\n}\n\ntest(\"Parse empty array failure\") {\n  val input = \"[\"\n  assert(array(input, 0) == Left(ParseError(input, 1, expected = \"]\")))\n}\n\n\nCombining parsers\n\nLet’s now imagine you want to accept the next kind of empty arrays. Those with some whitespace within.\n\nprivate val random = new Random()\n\ntest(\"Parse empty array with whitespace\") {\n  val ws = \" \" * random.between(1, 5)\n  assert(array(s\"[$ws]\", 0) == Right(JsonArray(List.empty)))\n}\n\n\n🔴:\n\nLeft(ParseError(\"[  ]\", 1, \"]\")) did not equal Right(JsonArray(List()))\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at (JsonParserTest.scala:21)\nExpected :Right(JsonArray(List()))\nActual   :Left(ParseError(\"[  ]\", 1, \"]\"))\n\n\nWe will need a parser for whitespace.\n\n\n\nAcording to the Json grammar this should parse 0 or more whitespace characters. It can’t fail. If our string starts with whitespace in the given index, it succeeds. If it doesn’t it also succeeds. So we don’t even need tests for that one. Which is already suspicious. We may be missing something….\n\nval whitespace: Parser[Unit] = (_, _) =&gt; Right(())\n\n\nLet’s try now to rewrite our array parser:\n\nval array: Parser[JsonArray] = (s, position) =&gt;\n  for\n    _ &lt;- string(\"[\")(s, position)\n    _ &lt;- whitespace(s, position + 1)\n    _ &lt;- string(\"]\")(s, ???)\n  yield JsonArray(List.empty)\n\n\nAnd here it is. The bit we were missing. After parsing some whitespace we need to know how many whitespace characters there were. We could solve that one ad hoc by stating that whitespace is a Parser[Int], which returns the number of whitespace characters it found:\n\nprivate val whiteSpaceChars = Set(' ', '\\n', '\\r', '\\t')\n\nval whitespace: Parser[Int] = (s, position) =&gt;\n  Right(s.substring(position).takeWhile(c =&gt; whiteSpaceChars.contains(c)).length)\n\nval array: Parser[JsonArray] = (s, position) =&gt;\n  for\n    _ &lt;- string(\"[\")(s, position)\n    whiteSpaceCount &lt;- whitespace(s, position + 1)\n    _ &lt;- string(\"]\")(s, position + 1 + whiteSpaceCount)\n  yield JsonArray(List.empty)\n\n\n✅!\n\n♻️ I start to be fed up with the position arithmetics in our array parser. In the second step of our for comprehension we pass position + 1 because what the first step parsed occupies 1 character. Then in the third step we pass position + 1 + whitesSpaceCount because the previous 2 steps parsed 1 + whitesSpaceCount characters. Every step needs to add the number of parsed characters by the previous steps. It is not nice. What about our steps all returned the position at which they stopped parsing?\n\nval whitespace: Parser[Int] = (s, position) =&gt;\n  Right(position + s.substring(position).takeWhile(c =&gt; whiteSpaceChars.contains(c)).length)\n\nval array: Parser[JsonArray] = (s, position) =&gt;\n  for\n    i0 &lt;- string(\"[\")(s, position)\n    i1 &lt;- whitespace(s, i0)\n    _ &lt;- string(\"]\")(s, i1)\n  yield JsonArray(List.empty)\n\ndef string(token: String): Parser[Int] = (s, position) =&gt;\n  if (s.startsWith(token, position)) Right(position + token.length) \n\telse Left(ParseError(s, position, token))\n\n\nMuch better! Now I need to remember which one of the i{n} variables to pass, but I don’t need to be calculating the next position to pass by hand. And after some adjusting of the expected result of parsing in the tests we are still green.\n\nAnd now, try to honor this section name It seems to be a recurrent theme. I name a section “X” and then I spend lines and more lines without any mention to “X”, until I remember what I was talking about. Sorry not sorry. 😙. Our array parser is combining the parseToken(\"[\"), whitespace and parseToken(\"]\") parsers by hand. That is, it is implementing a parser that, given the string and the position, uses those parsers. But we could just build the new parser by combining the existing parsers before we actually run the parser. Let’s first forget about the whitespace for a moment:\n\nval array: Parser[JsonArray] = (s, position) =&gt;\n  for\n    i0 &lt;- string(\"[\")(s, position)\n    _ &lt;- string(\"]\")(s, i0)\n  yield JsonArray(List.empty)\n\n\nI’m proposing a function that given 2 parsers (namely string(\"[\") and  string(\"]\") ) returns a parser that internally does what the code above does:\n\ndef sequence(a: Parser[Int], b: Parser[Int]): Parser[Int] = ???\n\n\nAs all our parsers here return the position after parsing what they parse, I’m assuming we want to sequence this kind of parsers. And I’m assuming we want to return the position after parsing the combination:\n\ndef sequence(a: Parser[Int], b: Parser[Int]): Parser[Int] = (s, position) =&gt;\n  for\n    ia &lt;- a(s, position)\n    ib &lt;- b(s, ia)\n  yield ib\n\n\nAnd now, our simplified array parser without whitespaces is:\n\nval array: Parser[JsonArray] = \n  sequence(string(\"[\"), string(\"]\"))\n\n\n🔴 Ops! That does not compile. We have a parser that returns Int but we need a JsonArray. So let’s fix that:\n\nval array: Parser[JsonArray] = (s, position) =&gt;\n  for\n    _ &lt;- sequence(string(\"[\"), string(\"]\"))(s, position)\n  yield JsonArray(List.empty)\n\n\nOr, if you prefer:\n\nval array: Parser[JsonArray] = (s, position) =&gt;\n  sequence(string(\"[\"), string(\"]\"))(s, position)\n\t\t.map(_ =&gt; JsonArray(List.empty))\n\n\n✅ (except our whitespace test, of course)\n\nBut before recovering our whitespace, let’s dig a bit deeper in this idea. We tried to combine the parsers to get a parser before actually running the resulting parser. Let’s say we apply the same idea to that .map. We may want to be able to transform the parser we got by combining parseToken(\"[\") and  parseToken(\"]\"), which was a Parser[Int] by transforming it into a Parser[JsonArray]. We need a function… let’s call it map, of course:\n\ndef map[A,B](p: Parser[A])(f: A =&gt; B): Parser[B] = (s, position) =&gt;\n  p(s, position).map(f)\n\n\nAnd now:\n\nval array: Parser[JsonArray] =\n  map(sequence(string(\"[\"), string(\"]\")))(_ =&gt; JsonArray(List.empty))\n\n\n✅ (again, without the whitespace stuff)\n\nThis is Scala. Let’s add some sugar.\n\nimplicit class ParserOps[A](self: Parser[A]):\n  def map[B](f: A =&gt; B): Parser[B] = (s, position) =&gt;\n    self(s, position).map(f)  \n\nval array: Parser[JsonArray] =\n  sequence(string(\"[\"), string(\"]\")).map(_ =&gt; JsonArray(List.empty))\n\n\nOps! That was the Scala 2 way of having extension methods. It all changed in Scala 3 and I didn’t remember In fact, if you were to look at the companion repository in github and followed the commits along, I realized about that while finishing the writing of the second part of this series. I prefer to correct it here, though, to avoid the confusion of mixing Scala 2 and Scala 3 features.. So:\n\nextension [A](self: Parser[A])\n  def map[B](f: A =&gt; B): Parser[B] = (s, position) =&gt;\n    self(s, position).map(f)\n\n\nMore sugar!\n\nextension(self: Parser[Int])\n  infix def sequence(other: Parser[Int]): Parser[Int] = (s, position) =&gt;\n    for\n      ia &lt;- self(s, position)\n      ib &lt;- other(s, ia)\n    yield ib\n\nval array: Parser[JsonArray] =\n  (string(\"[\") sequence string(\"]\")).map(_ =&gt; JsonArray(List.empty))\n\n\nOr, if you prefer operators:\n\nextension(self: Parser[Int])\n\n  infix def sequence(other: Parser[Int]): Parser[Int] = ...\n  def **(other: Parser[Int]): Parser[Int] = sequence(other)\n\nend extension\n\nval array: Parser[JsonArray] =\n  (string(\"[\") ** string(\"]\")).map(_ =&gt; JsonArray(List.empty))\n\n\nAnd now, let’s recover our whitespace parsing:\n\nval array: Parser[JsonArray] =\n  (string(\"[\") ** whitespace ** string(\"]\"))\n    .map(_ =&gt; JsonArray(List.empty))\n\n\n✅✅ Everything green again. Including our JsonArray with whitespace test.\n\nConclusions\n\nWe applied TDD to implement a parser capable of parsing… just empty Json arrays with or without whitespace in between. Even though their capability is very limited, this exercise served the purpose of defining our design for a parser  type Parser[A] = (String, Int) =&gt; Either[ParseError, A]. Then we discovered that instead of having functions that happen to parse what we want, we can haver functions that return parsers and values of type parser. Finally we found a way of combining 2 or more of these parsers to build a new parser without actually programming what the parser does when it receives the String and Int arguments, but designing how it is a sequence of 2 other parsers.\n\nYou can see the companion repository to this series at https://github.com/agile-jordi/writingAParserLibrary/tree/part1.\n\nAll articles in the series\n\n\n  Writing a Parser Combinator Library in Scala 3. Part 1: Introduction to Parsing\n  Writing a parser library in Scala. Part 2: Choices and repetitions\n\n",
            "content_html": "<p>You know I like to write libraries from scratch. I find this to be a longer but better kata, where you implement something you could actually use. And, who knows, after the zombie apocalypse, once we recover from everything else, you may need a parsers library and all the good old ones are gone forever. So, let’s survive the apocalypse by writing one ourselves.</p>\n\n<p>To do so I’ll use the perfect excuse. I want to write yet another Json parser. I want it to be reasonable fast but, above everything else, I want it to be crystal clear when it comes to report errors. At least as good as  those of most Json parsers I use, or better. Because if we are going to write a library from scracth let’s make it professional grade at least in one aspect.</p>\n\n<h2 id=\"disclaimer-1-scala-3-and-my-experience-with-it-or-lack-of-thereof\">Disclaimer 1: Scala 3 and my experience with it (or lack of thereof)</h2>\n\n<p>This time I’ll use Scala. I’ve been blogging about Kotlin recently but I’ve been a Scala developer for years and I use both now. And I’ll be writing Scala 3 for the first time (not counting some small divertimentos), so be patient and kind if something I write is not completely idiomatic in Scala 3 or if the library we end up with does not take advantage of every single Scala 3 wonderful new feature.</p>\n\n<h2 id=\"disclaimer-2-inspiration-and-destination\">Disclaimer 2: Inspiration and destination</h2>\n\n<p>Ok, I’ll admit it up front. I will end up writing a parser combinator library. And it so happens that the language (Scala) and example (Json) I have chosen are the same the famous <a href=\"https://www.manning.com/books/functional-programming-in-scala\">Red book</a> uses. Why write about it, then, if you can read <a href=\"https://twitter.com/pchiusano\">Paul Chiusano</a> and <a href=\"https://twitter.com/runarorama\">Runar Bjarnason</a>? First of all, no matter what, you must read the red book <em class=\"sidenote-number\">if you haven’t yet</em><em class=\"sidenote\">You probably can read it again if you already have and you will probably still learn a ton of things.</em>.  But I’ll try my best at a different approach to the parser combinator library. Instead of applying algebraic design, I’ll use a classical TDD approach.</p>\n\n<p><img src=\"../assets/scalaAndTdd.png\" alt=\"scalaAndTdd\" /></p>\n\n<p>There are a couple of points I’d like to make with this:</p>\n\n<ul>\n  <li>You can design something like parser combinators using TDD; algebraic design is just one way, not the only way. Applying TDD like I’ll do is not without drawbacks but it may work for you.</li>\n  <li>You don’t need to know obscure mathematics and the terrible M word to design a parser combinator library. Or, to put it another way, monads are not your enemy and they aren’t something you should be afraid of… when they excel at the job at hand. You may have ended designing a similar solution without being a fan of monads. What is more, you may have designed a much less elegant solution if you were to design it from scracth without monads.</li>\n</ul>\n\n<h2 id=\"parsing-what\">Parsing what?</h2>\n\n<p>Let’s parse <a href=\"https://json.org\">Json</a>. For that, let’s write a Json type:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">enum</span> <span class=\"nc\">Json</span><span class=\"k\">:</span>\n  <span class=\"kt\">case</span> <span class=\"kt\">JsonString</span><span class=\"o\">(</span><span class=\"kt\">value:</span> <span class=\"kt\">String</span><span class=\"o\">)</span>\n  <span class=\"kt\">case</span> <span class=\"kt\">JsonNumber</span><span class=\"o\">(</span><span class=\"kt\">value:</span> <span class=\"kt\">String</span><span class=\"o\">)</span>\n  <span class=\"kt\">case</span> <span class=\"kt\">JsonBoolean</span><span class=\"o\">(</span><span class=\"kt\">value:</span> <span class=\"kt\">Boolean</span><span class=\"o\">)</span>\n  <span class=\"kt\">case</span> <span class=\"kt\">JsonNull</span>\n  <span class=\"k\">case</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"n\">value</span><span class=\"k\">:</span> <span class=\"kt\">List</span><span class=\"o\">[</span><span class=\"kt\">Json</span><span class=\"o\">])</span>\n  <span class=\"k\">case</span> <span class=\"nc\">JsonObject</span><span class=\"o\">(</span><span class=\"n\">value</span><span class=\"k\">:</span> <span class=\"kt\">Map</span><span class=\"o\">[</span><span class=\"kt\">String</span>, <span class=\"kt\">Json</span><span class=\"o\">])</span>\n</code></pre></div></div>\n\n<p>You may think <code class=\"language-plaintext highlighter-rouge\">JsonNumber(value: String)</code> is an odd choice. I’ll talk about this in the future. Trust me with that one. But in any case, for the matter of this series, it doesn’t matter that much if you prefer to model them as <code class=\"language-plaintext highlighter-rouge\">JsonNumber(value: Double)</code> or something else.</p>\n\n<p>Done. Now the parser…</p>\n\n<h2 id=\"what-is-a-parser\">What is a parser?</h2>\n\n<p>Let me try to answer this question with some requirements…</p>\n\n<p>Let’s start by just parsing something simple, like an empty array. Acording to <a href=\"https://json.org\">json.org</a> an array is:</p>\n\n<p><img src=\"../assets/json-array.png\" alt=\"img\" style=\"zoom: 33%;\" /></p>\n\n<p>Here <code class=\"language-plaintext highlighter-rouge\">whitespace</code> represents any number of whitespace characters. It may be the empty string.</p>\n\n<p>So, setting aside the parsing of values inside the array, we want a function that given the <code class=\"language-plaintext highlighter-rouge\">String</code> <code class=\"language-plaintext highlighter-rouge\">\"[ ]\"</code> returns <code class=\"language-plaintext highlighter-rouge\">JsonArray(List.empty)</code> (for any number and type of whitespace characters between the brackets).</p>\n\n<p>Let’s do it TDD style:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseArray</span><span class=\"o\">(</span><span class=\"s\">\"[]\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 Red. Easy peasy:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">object</span> <span class=\"nc\">JsonParser</span><span class=\"k\">:</span>\n  <span class=\"kt\">def</span> <span class=\"kt\">parseArray</span><span class=\"o\">(</span><span class=\"kt\">s:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"kt\">:</span> <span class=\"kt\">JsonArray</span> <span class=\"o\">=</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>✅ Green!</p>\n\n<p>Let’s delay the implementation of whitespace. What else do we need? Here is what: What do we want the parser to do if feeded only with <code class=\"language-plaintext highlighter-rouge\">\"[\"</code>? We expect it to fail. The failure should tell us where it failed and what was expected. That is, we failed at the second character (<code class=\"language-plaintext highlighter-rouge\">s[1]</code>) where we expected <code class=\"language-plaintext highlighter-rouge\">]</code> but we found the end of the string.</p>\n\n<p>We can deal with errors with exceptions, with <code class=\"language-plaintext highlighter-rouge\">Try</code>, with <code class=\"language-plaintext highlighter-rouge\">Either</code> or with a custom type. Let’s try using <code class=\"language-plaintext highlighter-rouge\">Either</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseArray</span><span class=\"o\">(</span><span class=\"s\">\"[]\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n\n<span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array failure\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"[\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseArray</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">1</span><span class=\"o\">,</span> <span class=\"n\">expected</span> <span class=\"k\">=</span> <span class=\"s\">\"]\"</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 It does not even compile. Let’s create the <code class=\"language-plaintext highlighter-rouge\">ParseError</code> class and change the <code class=\"language-plaintext highlighter-rouge\">parseArray</code> signature:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">case</span> <span class=\"k\">class</span> <span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"k\">:</span> <span class=\"kt\">Int</span><span class=\"o\">,</span> <span class=\"n\">expected</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span>\n\n<span class=\"k\">object</span> <span class=\"nc\">JsonParser</span><span class=\"k\">:</span>\n  <span class=\"kt\">def</span> <span class=\"kt\">parseArray</span><span class=\"o\">(</span><span class=\"kt\">s:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"kt\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>🔴 It now compiles but…</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Right<span class=\"o\">(</span>JsonArray<span class=\"o\">(</span>List<span class=\"o\">()))</span> did not equal Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"[\"</span>, 1, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span>\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at <span class=\"o\">(</span>JsonParserTest.scala:17<span class=\"o\">)</span>\nExpected :Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"[\"</span>, 1, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span>\nActual   :Right<span class=\"o\">(</span>JsonArray<span class=\"o\">(</span>List<span class=\"o\">()))</span>\n</code></pre></div></div>\n\n<p>Now what? We could <a href=\"http://wiki.c2.com/?DoTheSimplestThingThatCouldPossiblyWork=\">DTSTTCPW</a> and just implement <code class=\"language-plaintext highlighter-rouge\">parseArray</code> to return this particular error when the input string is <code class=\"language-plaintext highlighter-rouge\">\"[\"</code>. But this is not a <em class=\"sidenote-number\">bad TDD training</em> <em class=\"sidenote\">Just in case: I’m not saying TDD is bad at all, of course. Neither I’m saying training people in TDD with really small steps is bad. I’m just making a joke about confusing baby steps with implementing each test case with an if/else branch. Even though I’m making a bit of a pun to code without designing, which should be the opposite of TDD.</em>. So let’s think a bit and design a solution.</p>\n\n<p>Looking at the json.org diagram above, we see <code class=\"language-plaintext highlighter-rouge\">[</code> and <code class=\"language-plaintext highlighter-rouge\">]</code> are different nodes in the grammar chart. Maybe our mission of parsing just the empty array was <a href=\"https://www.youtube.com/watch?v=U_-nHeIenBM\">more than we can chew</a> now, afer all. Let’s try something simpler. Let’s try to parse the <code class=\"language-plaintext highlighter-rouge\">[</code> token. So let’s <code class=\"language-plaintext highlighter-rouge\">git stash save wip</code> or comment out our <em class=\"sidenote-number\">failing test</em> <em class=\"sidenote\">We are doing TDD right, no? And we are in the midle of a red. So let’s go back to green, make an increment, and we will retake what we where doing when in green again.</em>and start anew. Parsing a token, when it succeeds, can only do so <strong>in one way</strong>. When succeeding, therefore, we only need the <code class=\"language-plaintext highlighter-rouge\">Unit</code> value as a return:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse start array token\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseStartArrayToken</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(()))</span>\n<span class=\"o\">}</span>\n\n<span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse start array token failure\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"notTheStartArrayToken\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseStartArrayToken</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">,</span> <span class=\"n\">expected</span> <span class=\"k\">=</span> <span class=\"s\">\"[\"</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 Does not compile. Let’s go directly to green:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseStartArrayToken</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n\t<span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"n\">s</span> <span class=\"o\">==</span> <span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">,</span> <span class=\"s\">\"[\"</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>✅ Now refactor ♻️. You see, I’m going to try to parse the <code class=\"language-plaintext highlighter-rouge\">]</code> token. So it seems we are going to parse tokens in general. Let’s refactor that:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">,</span> <span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"n\">s</span> <span class=\"o\">==</span> <span class=\"n\">token</span><span class=\"o\">)</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">,</span> <span class=\"n\">token</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>Mmmm… 🤔 I prefer the token to be the first argument… and the string to be a second argument list:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n</code></pre></div></div>\n\n<p>And our tests are now:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse token\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(()))</span>\n<span class=\"o\">}</span>\n\n<span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse token failure\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"notTheStartArrayToken\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">,</span> <span class=\"n\">expected</span> <span class=\"k\">=</span> <span class=\"s\">\"[\"</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>Great!</p>\n\n<p>Now we want to parse the token <code class=\"language-plaintext highlighter-rouge\">[</code> and then the token <code class=\"language-plaintext highlighter-rouge\">]</code>. That’s the question. And here is a simple idea: we want our token parser to be able to parse any string that starts with that token:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">startsWith</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"o\">))</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">,</span> <span class=\"n\">token</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>After parsing <code class=\"language-plaintext highlighter-rouge\">[</code> in <code class=\"language-plaintext highlighter-rouge\">\"[]\"</code> we now know that the string starts with <code class=\"language-plaintext highlighter-rouge\">[</code> and that we can continue to parse <code class=\"language-plaintext highlighter-rouge\">]</code>… <strong>after the [</strong>. I could play with our current design like this:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseArray</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">)</span> <span class=\"k\">match</span>\n    <span class=\"k\">case</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">=&gt;</span>\n      <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">substring</span><span class=\"o\">(</span><span class=\"mi\">1</span><span class=\"o\">))</span> <span class=\"k\">match</span> <span class=\"o\">{</span>\n        <span class=\"k\">case</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n        <span class=\"k\">case</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"n\">e</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"n\">e</span><span class=\"o\">)</span>\n      <span class=\"o\">}</span>\n    <span class=\"k\">case</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"n\">e</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"n\">e</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>Or, <del>monadically</del> <ins>idiomatically</ins>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseArray</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"k\">for</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">substring</span><span class=\"o\">(</span><span class=\"mi\">1</span><span class=\"o\">))</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>✅! But if you now <code class=\"language-plaintext highlighter-rouge\">git stash pop</code> or uncomment our <code class=\"language-plaintext highlighter-rouge\">\"Parse empty array failure\"</code> test:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array failure\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"[\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">parseArray</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">1</span><span class=\"o\">,</span> <span class=\"n\">expected</span> <span class=\"k\">=</span> <span class=\"s\">\"]\"</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴 The test fails:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"\"</span>, 0, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span> did not equal Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"[\"</span>, 1, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span>\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at <span class=\"o\">(</span>JsonParserTest.scala:17<span class=\"o\">)</span>\nExpected :Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"[\"</span>, 1, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span>\nActual   :Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"\"</span>, 0, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>So, the parser correctly fails to parse, but it is telling us that it expected <code class=\"language-plaintext highlighter-rouge\">\"]\"</code> at position 0 (where we have <code class=\"language-plaintext highlighter-rouge\">\"[\"</code>) instead of telling us it expected it at position 1. And it tells us the string that failed to compile is <code class=\"language-plaintext highlighter-rouge\">\"\"</code> when it should complain about the actual string it got: <code class=\"language-plaintext highlighter-rouge\">\"[\"</code>. Why? As we passed the <code class=\"language-plaintext highlighter-rouge\">substring(1)</code> to the second <code class=\"language-plaintext highlighter-rouge\">parseToken</code>, the <code class=\"language-plaintext highlighter-rouge\">input</code> and <code class=\"language-plaintext highlighter-rouge\">position</code> values of the resulting error are wrong. We want the error to contain the entire string and the position to be a position of that string, so we will need them in our <code class=\"language-plaintext highlighter-rouge\">parseArray</code> function. And once we have the original input and the position we want to parse at, we no longer need the substring. <em class=\"sidenote-number\">We can simply check whether the string starts with the token at that index:</em><em class=\"sidenote\">Yes, there is a version of <code class=\"language-plaintext highlighter-rouge\">startsWith</code> that takes an index. No, I didn’t know either.</em></p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"k\">:</span> <span class=\"kt\">Int</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">startsWith</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">))</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">,</span> <span class=\"n\">token</span><span class=\"o\">))</span>\n</code></pre></div></div>\n<p>So now:</p>\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseArray</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"k\">for</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"mi\">1</span><span class=\"o\">)</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>And after fixing the compilation errors of adding a new parameter… ✅ Green!</p>\n\n<p>🤔 Do you remember what this section was about? The question was: “What is a parser”? Looking at our <code class=\"language-plaintext highlighter-rouge\">parseToken</code> we have <em class=\"sidenote-number\">one possible answer</em><em class=\"sidenote\">Mind the gap. We will refine this answer later in the series.</em> now: A parser is a function that given a <code class=\"language-plaintext highlighter-rouge\">String</code> input and a position in that string either returns a parsed value (like the empty array above) or a parse failure:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">type</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"nc\">String</span><span class=\"o\">,</span> <span class=\"nc\">Int</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Either</span><span class=\"o\">[</span><span class=\"kt\">ParseError</span>, <span class=\"kt\">A</span><span class=\"o\">]</span>\n</code></pre></div></div>\n\n<p>♻️ We ended our previous TDD cycle with green. A refactor is due. But what are we going to refactor? 🤔</p>\n\n<p>With that definition you don’t even need to squint too hard to see that <code class=\"language-plaintext highlighter-rouge\">parseToken</code> can be seen as a function that given a <code class=\"language-plaintext highlighter-rouge\">String</code> (the token) returns a parser:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseToken</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">startsWith</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">))</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">,</span> <span class=\"n\">token</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>As <code class=\"language-plaintext highlighter-rouge\">parseToken</code> it is no longer parsing any token but returning a parser of strings, maybe we better call it <code class=\"language-plaintext highlighter-rouge\">string</code>:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">startsWith</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">))</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span> <span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">,</span> <span class=\"n\">token</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>Now, why not make our <code class=\"language-plaintext highlighter-rouge\">parseArray</code> a parser too?</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">parseArray</span><span class=\"o\">()</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"k\">for</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">)</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>And as it is not taking arguments, why not make it a value?:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">object</span> <span class=\"nc\">JsonParser</span><span class=\"k\">:</span>\n  <span class=\"kt\">val</span> <span class=\"kt\">array:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"k\">for</span>\n      <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n      <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">)</span>\n    <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n\n</code></pre></div></div>\n\n<p>And our tests:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"s\">\"[]\"</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n\n<span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array failure\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">input</span> <span class=\"k\">=</span> <span class=\"s\">\"[\"</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">input</span><span class=\"o\">,</span> <span class=\"mi\">1</span><span class=\"o\">,</span> <span class=\"n\">expected</span> <span class=\"k\">=</span> <span class=\"s\">\"]\"</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"combining-parsers\">Combining parsers</h2>\n\n<p>Let’s now imagine you want to accept the next kind of empty arrays. Those with some whitespace within.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">private</span> <span class=\"k\">val</span> <span class=\"nv\">random</span> <span class=\"k\">=</span> <span class=\"k\">new</span> <span class=\"nc\">Random</span><span class=\"o\">()</span>\n\n<span class=\"nf\">test</span><span class=\"o\">(</span><span class=\"s\">\"Parse empty array with whitespace\"</span><span class=\"o\">)</span> <span class=\"o\">{</span>\n  <span class=\"k\">val</span> <span class=\"nv\">ws</span> <span class=\"k\">=</span> <span class=\"s\">\" \"</span> <span class=\"o\">*</span> <span class=\"nv\">random</span><span class=\"o\">.</span><span class=\"py\">between</span><span class=\"o\">(</span><span class=\"mi\">1</span><span class=\"o\">,</span> <span class=\"mi\">5</span><span class=\"o\">)</span>\n  <span class=\"nf\">assert</span><span class=\"o\">(</span><span class=\"nf\">array</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"s\">\"[$ws]\"</span><span class=\"o\">,</span> <span class=\"mi\">0</span><span class=\"o\">)</span> <span class=\"o\">==</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)))</span>\n<span class=\"o\">}</span>\n</code></pre></div></div>\n\n<p>🔴:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"[  ]\"</span>, 1, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span> did not equal Right<span class=\"o\">(</span>JsonArray<span class=\"o\">(</span>List<span class=\"o\">()))</span>\nScalaTestFailureLocation: com.agilogy.wapl.JsonParserTest at <span class=\"o\">(</span>JsonParserTest.scala:21<span class=\"o\">)</span>\nExpected :Right<span class=\"o\">(</span>JsonArray<span class=\"o\">(</span>List<span class=\"o\">()))</span>\nActual   :Left<span class=\"o\">(</span>ParseError<span class=\"o\">(</span><span class=\"s2\">\"[  ]\"</span>, 1, <span class=\"s2\">\"]\"</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>We will need a parser for <code class=\"language-plaintext highlighter-rouge\">whitespace</code>.</p>\n\n<p><img src=\"../assets/json-whitespace.png\" alt=\"json-whitespace\" style=\"zoom:30%;\" /></p>\n\n<p>Acording to the Json grammar this should parse 0 or more whitespace characters. It can’t fail. If our string starts with whitespace in the given index, it succeeds. If it doesn’t it also succeeds. So we don’t even need tests for that one. Which is already suspicious. We may be missing something….</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">whitespace</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Unit</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"k\">_</span><span class=\"o\">,</span> <span class=\"k\">_</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">Right</span><span class=\"o\">(())</span>\n</code></pre></div></div>\n\n<p>Let’s try now to rewrite our array parser:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"k\">for</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">whitespace</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"o\">???)</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>And here it is. The bit we were missing. After parsing some whitespace we need to know how many whitespace characters there were. We could solve that one <em>ad hoc</em> by stating that <code class=\"language-plaintext highlighter-rouge\">whitespace</code> is a <code class=\"language-plaintext highlighter-rouge\">Parser[Int]</code>, which returns the number of whitespace characters it found:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">private</span> <span class=\"k\">val</span> <span class=\"nv\">whiteSpaceChars</span> <span class=\"k\">=</span> <span class=\"nc\">Set</span><span class=\"o\">(</span><span class=\"sc\">' '</span><span class=\"o\">,</span> <span class=\"sc\">'\\n'</span><span class=\"o\">,</span> <span class=\"sc\">'\\r'</span><span class=\"o\">,</span> <span class=\"sc\">'\\t'</span><span class=\"o\">)</span>\n\n<span class=\"k\">val</span> <span class=\"nv\">whitespace</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">substring</span><span class=\"o\">(</span><span class=\"n\">position</span><span class=\"o\">).</span><span class=\"py\">takeWhile</span><span class=\"o\">(</span><span class=\"n\">c</span> <span class=\"k\">=&gt;</span> <span class=\"nv\">whiteSpaceChars</span><span class=\"o\">.</span><span class=\"py\">contains</span><span class=\"o\">(</span><span class=\"n\">c</span><span class=\"o\">)).</span><span class=\"py\">length</span><span class=\"o\">)</span>\n\n<span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"k\">for</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n    <span class=\"n\">whiteSpaceCount</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">whitespace</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"o\">+</span> <span class=\"n\">whiteSpaceCount</span><span class=\"o\">)</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>✅!</p>\n\n<p>♻️ I start to be fed up with the position arithmetics in our <code class=\"language-plaintext highlighter-rouge\">array</code> parser. In the second step of our for comprehension we pass <code class=\"language-plaintext highlighter-rouge\">position + 1</code> because what the first step parsed occupies 1 character. Then in the third step we pass <code class=\"language-plaintext highlighter-rouge\">position + 1 + whitesSpaceCount</code> because the previous 2 steps parsed <code class=\"language-plaintext highlighter-rouge\">1 + whitesSpaceCount</code> characters. Every step needs to add the number of parsed characters by the previous steps. It is not nice. What about our steps all returned the position at which they stopped parsing?</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">whitespace</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">substring</span><span class=\"o\">(</span><span class=\"n\">position</span><span class=\"o\">).</span><span class=\"py\">takeWhile</span><span class=\"o\">(</span><span class=\"n\">c</span> <span class=\"k\">=&gt;</span> <span class=\"nv\">whiteSpaceChars</span><span class=\"o\">.</span><span class=\"py\">contains</span><span class=\"o\">(</span><span class=\"n\">c</span><span class=\"o\">)).</span><span class=\"py\">length</span><span class=\"o\">)</span>\n\n<span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"k\">for</span>\n    <span class=\"n\">i0</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n    <span class=\"n\">i1</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">whitespace</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">i0</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">i1</span><span class=\"o\">)</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n\n<span class=\"k\">def</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"k\">:</span> <span class=\"kt\">String</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nf\">if</span> <span class=\"o\">(</span><span class=\"nv\">s</span><span class=\"o\">.</span><span class=\"py\">startsWith</span><span class=\"o\">(</span><span class=\"n\">token</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">))</span> <span class=\"nc\">Right</span><span class=\"o\">(</span><span class=\"n\">position</span> <span class=\"o\">+</span> <span class=\"nv\">token</span><span class=\"o\">.</span><span class=\"py\">length</span><span class=\"o\">)</span> \n\t<span class=\"k\">else</span> <span class=\"nc\">Left</span><span class=\"o\">(</span><span class=\"nc\">ParseError</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">,</span> <span class=\"n\">token</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>Much better! Now I need to remember which one of the <code class=\"language-plaintext highlighter-rouge\">i{n}</code> variables to pass, but I don’t need to be calculating the next position to pass by hand. And after some adjusting of the expected result of parsing in the tests we are still green.</p>\n\n<p>And now, try to honor <em class=\"sidenote-number\">this section name</em> <em class=\"sidenote\">It seems to be a recurrent theme. I name a section “X” and then I spend lines and more lines without any mention to “X”, until I remember what I was talking about. Sorry not sorry. 😙</em>. Our <code class=\"language-plaintext highlighter-rouge\">array</code> parser is combining the <code class=\"language-plaintext highlighter-rouge\">parseToken(\"[\")</code>, <code class=\"language-plaintext highlighter-rouge\">whitespace</code> and <code class=\"language-plaintext highlighter-rouge\">parseToken(\"]\")</code> parsers by hand. That is, it is implementing a parser that, given the string and the position, uses those parsers. But we could just build the new parser by combining the existing parsers before we actually run the parser. Let’s first forget about the whitespace for a moment:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"k\">for</span>\n    <span class=\"n\">i0</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">i0</span><span class=\"o\">)</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>I’m proposing a function that given 2 parsers (namely <code class=\"language-plaintext highlighter-rouge\">string(\"[\")</code> and  <code class=\"language-plaintext highlighter-rouge\">string(\"]\")</code> ) returns a parser that internally does what the code above does:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">],</span> <span class=\"n\">b</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">???</span>\n</code></pre></div></div>\n\n<p>As all our parsers here return the position after parsing what they parse, I’m assuming we want to sequence this kind of parsers. And I’m assuming we want to return the position after parsing the combination:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">a</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">],</span> <span class=\"n\">b</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"k\">for</span>\n    <span class=\"n\">ia</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">a</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n    <span class=\"n\">ib</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">b</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">ia</span><span class=\"o\">)</span>\n  <span class=\"k\">yield</span> <span class=\"n\">ib</span>\n</code></pre></div></div>\n\n<p>And now, our simplified <code class=\"language-plaintext highlighter-rouge\">array</code> parser without whitespaces is:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> \n  <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">),</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>🔴 Ops! That does not compile. We have a parser that returns <code class=\"language-plaintext highlighter-rouge\">Int</code> but we need a <code class=\"language-plaintext highlighter-rouge\">JsonArray</code>. So let’s fix that:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"k\">for</span>\n    <span class=\"k\">_</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">),</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">))(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n  <span class=\"k\">yield</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>Or, if you prefer:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">),</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">))(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n\t\t<span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>✅ (except our whitespace test, of course)</p>\n\n<p>But before recovering our whitespace, let’s dig a bit deeper in this idea. We tried to combine the parsers to get a parser before actually running the resulting parser. Let’s say we apply the same idea to that <code class=\"language-plaintext highlighter-rouge\">.map</code>. We may want to be able to transform the parser we got by combining <code class=\"language-plaintext highlighter-rouge\">parseToken(\"[\")</code> and  <code class=\"language-plaintext highlighter-rouge\">parseToken(\"]\")</code>, which was a <code class=\"language-plaintext highlighter-rouge\">Parser[Int]</code> by transforming it into a <code class=\"language-plaintext highlighter-rouge\">Parser[JsonArray]</code>. We need a function… let’s call it <code class=\"language-plaintext highlighter-rouge\">map</code>, of course:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">def</span> <span class=\"nf\">map</span><span class=\"o\">[</span><span class=\"kt\">A</span>,<span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">p</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])(</span><span class=\"n\">f</span><span class=\"k\">:</span> <span class=\"kt\">A</span> <span class=\"o\">=&gt;</span> <span class=\"n\">B</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n  <span class=\"nf\">p</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"n\">f</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>And now:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">map</span><span class=\"o\">(</span><span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">),</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)))(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>✅ (again, without the whitespace stuff)</p>\n\n<p>This is Scala. Let’s add some sugar.</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">implicit</span> <span class=\"k\">class</span> <span class=\"nc\">ParserOps</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span><span class=\"k\">:</span>\n  <span class=\"kt\">def</span> <span class=\"kt\">map</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">f</span><span class=\"k\">:</span> <span class=\"kt\">A</span> <span class=\"o\">=&gt;</span> <span class=\"n\">B</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"n\">f</span><span class=\"o\">)</span>  \n\n<span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">),</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>Ops! That was the Scala 2 way of having extension methods. It all changed in Scala 3 and I didn’t <em class=\"sidenote-number\">remember</em> <em class=\"sidenote\">In fact, if you were to look at the companion repository in github and followed the commits along, I realized about that while finishing the writing of the second part of this series. I prefer to correct it here, though, to avoid the confusion of mixing Scala 2 and Scala 3 features.</em>. So:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">extension</span> <span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">](</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">A</span><span class=\"o\">])</span>\n  <span class=\"k\">def</span> <span class=\"nf\">map</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">](</span><span class=\"n\">f</span><span class=\"k\">:</span> <span class=\"kt\">A</span> <span class=\"o\">=&gt;</span> <span class=\"n\">B</span><span class=\"o\">)</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">B</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"n\">f</span><span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>More sugar!</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">extension</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">])</span>\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span> <span class=\"k\">=&gt;</span>\n    <span class=\"k\">for</span>\n      <span class=\"n\">ia</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">self</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">position</span><span class=\"o\">)</span>\n      <span class=\"n\">ib</span> <span class=\"k\">&lt;-</span> <span class=\"nf\">other</span><span class=\"o\">(</span><span class=\"n\">s</span><span class=\"o\">,</span> <span class=\"n\">ia</span><span class=\"o\">)</span>\n    <span class=\"k\">yield</span> <span class=\"n\">ib</span>\n\n<span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"n\">sequence</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>Or, if you prefer operators:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">extension</span><span class=\"o\">(</span><span class=\"n\">self</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">])</span>\n\n  <span class=\"n\">infix</span> <span class=\"k\">def</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"o\">...</span>\n  <span class=\"k\">def</span> <span class=\"nf\">**</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">])</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">Int</span><span class=\"o\">]</span> <span class=\"k\">=</span> <span class=\"nf\">sequence</span><span class=\"o\">(</span><span class=\"n\">other</span><span class=\"o\">)</span>\n\n<span class=\"n\">end</span> <span class=\"n\">extension</span>\n\n<span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">)).</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>And now, let’s recover our whitespace parsing:</p>\n\n<div class=\"language-scala highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">val</span> <span class=\"nv\">array</span><span class=\"k\">:</span> <span class=\"kt\">Parser</span><span class=\"o\">[</span><span class=\"kt\">JsonArray</span><span class=\"o\">]</span> <span class=\"k\">=</span>\n  <span class=\"o\">(</span><span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"[\"</span><span class=\"o\">)</span> <span class=\"o\">**</span> <span class=\"n\">whitespace</span> <span class=\"o\">**</span> <span class=\"nf\">string</span><span class=\"o\">(</span><span class=\"s\">\"]\"</span><span class=\"o\">))</span>\n    <span class=\"o\">.</span><span class=\"py\">map</span><span class=\"o\">(</span><span class=\"k\">_</span> <span class=\"k\">=&gt;</span> <span class=\"nc\">JsonArray</span><span class=\"o\">(</span><span class=\"nv\">List</span><span class=\"o\">.</span><span class=\"py\">empty</span><span class=\"o\">))</span>\n</code></pre></div></div>\n\n<p>✅✅ Everything green again. Including our <code class=\"language-plaintext highlighter-rouge\">JsonArray</code> with whitespace test.</p>\n\n<h2 id=\"conclusions\">Conclusions</h2>\n\n<p>We applied TDD to implement a parser capable of parsing… just empty Json arrays with or without whitespace in between. Even though their capability is very limited, this exercise served the purpose of defining our design for a parser  <code class=\"language-plaintext highlighter-rouge\">type Parser[A] = (String, Int) =&gt; Either[ParseError, A]</code>. Then we discovered that instead of having functions that happen to parse what we want, we can haver functions that return parsers and values of type parser. Finally we found a way of combining 2 or more of these parsers to build a new parser without actually programming what the parser does when it receives the <code class=\"language-plaintext highlighter-rouge\">String</code> and <code class=\"language-plaintext highlighter-rouge\">Int</code> arguments, but designing how it is a sequence of 2 other parsers.</p>\n\n<p>You can see the companion repository to this series at <a href=\"https://github.com/agile-jordi/writingAParserLibrary/tree/part1\">https://github.com/agile-jordi/writingAParserLibrary/tree/part1</a>.</p>\n\n<h2 id=\"all-articles-in-the-series\">All articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-11-11-writing-a-parser-combinator-library-1.html\">Writing a Parser Combinator Library in Scala 3. Part 1: Introduction to Parsing</a></li>\n  <li><a href=\"./2022-12-16-writing-a-parser-combinator-library-2.html\">Writing a parser library in Scala. Part 2: Choices and repetitions</a></li>\n</ol>\n",
            "url": "https://blog.agilogy.com/2022-11-11-writing-a-parser-combinator-library-1.html",
            "date_published": "2022-11-11T00:00:00+01:00",
            "date_modified": "2022-11-11T00:00:00+01:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-10-25-writing-a-pbt-ibrary-3.html",
            "title": "Writing a Property Based Testing library in Kotlin, a Journey (part 3)",
            "content_text": "In our previous posts we developed a minimal property based testing (PBT) library capable of checking properties on primitive types, nullable types, tuples and types mapped from other types, giving us the possibility of testing properties of our programs and functions for many kinds of input values.\n\nOne of the (many) shortcoming of this small thing we created is in the reproducibility of failed tests. If you are checking a property for simple values like forAny(Arb.int) { i -&gt; i + i &gt;= i }  the outcome is quite informative:\n\nProperty failed at attempt 3 with sample -836667656\ncom.agilogy.wapbtl.PropertyFailedException: Property failed at attempt 3 with sample -836667656\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny$test(forAny.kt:14)\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny(forAny.kt:18)\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny$default(forAny.kt:9)\n\n\nWe have the sample that made our property fail. If we want to reproduce the failed test, we just need to write an example based test with that example. But… What if our sample is a more or less complex datatype whose toString() is not suitable for a copy &amp; paste into Kotlin code? What if the test is not a one-liner and “simply” writing an example based test involves copying an important amount of lines?\n\nWhat I would like is to be able to change a single line of code and, hop!, make our property based test just test the exact sample for which I got a failure.\n\nRandomness\n\nGrab your dice instance of Random and let’s dig into how randomness works…\n\n\n\nAs you probably already know, random values generation by computers is actually quite a complex topic. Long story short, Kotlin’s Random generates random values using an, in fact, predictable function that takes a seed and returns an endless sequence of aparently random numbers. Give it the same seed and poof! randomness is gone: you’ll get the same sequence of values. This would be dangerous if you were using pseudo-randomness for cryptogrhaphic purposes, but it is really useful for us.\n\nSo, what we need is to be able to seed our tests whenever we want to reproduce a failure.\n\nRed\n\nLet’s do this TDD style. That is, let’s write the test first so that we design the feature by thinking how we would like to use it instead of thinking about how to implement it:\n\n@Test\nfun forAnySeedParameterShouldReproduceTheFailingTest() {\n    val property: (Int) -&gt; Boolean = { i -&gt; i + i &gt;= i }\n    val failure = assertFailsWith&lt;PropertyFailedException&gt; {\n        forAny(Arb.int, property = property)\n    }\n    var actualExecutionsWithSeed = 0\n    val seededFailure = assertFailsWith&lt;PropertyFailedException&gt; {\n        forAny(Arb.int, failure.seed) {\n          actualExecutionsWithSeed++\n          property(it)\n        }\n    }\n    assertEquals(failure.sample, seededFailure.sample)\n    assertEquals(failure.seed, seededFailure.seed)\n    assertEquals(1, seededFailure.attempt)\n    assertEquals(1, actualExecutionsWithSeed)  \n}\n\n\nSo, whenever we get a PropertyFailedException we want to get a seed. And, forAny now will take an optional seed as an argument and will give us some guarantees:\n\n\n  If we use the seed returned by a failure, the test will fail\n  The sample (and seed) returned by this failure will be the same sample (and seed) of the original exception\n  But this time, the failure will be found at the first attempt.\n\n\nSo now our forAny functions will have a signature like this one (here the one for one Arb argument):\n\nfun &lt;A&gt; forAny(r: Arb&lt;A&gt;, seed: Long? = null, property: (A) -&gt; Boolean): Unit\n\n\nAnd in case of failure it will throw:\n\nclass PropertyFailedException(val attempt: Int, val sample: Any?, val seed: Long) : Exception(\n    \"Property failed at attempt $attempt with seed $seed, sample $sample\"\n)\n\n\nGreen\n\nOk, now let’s go for the green.\n\nOur Arbitrary instances are currently using kotlin.Random like this:\n\nval Arb.Companion.int: Arb&lt;Int&gt; get() = object : Arb&lt;Int&gt; {\n        override fun generate(): Int = kotlin.random.Random.nextInt()\n}\n\n\nWhat does kotlin.random.Random.nextInt() do? If we look under the hood at the implementation of the standard library, we’ll find:\n\npackage kotlin.random\npublic abstract class Random {\n    // ...\n    companion object Default : Random(), Serializable {\n      // ...\n      private val defaultRandom: Random = defaultPlatformRandom()\n      override fun nextInt(): Int = defaultRandom.nextInt()\n    }\n\n\nThere is an important amount of things going on here:\n\n\n  At initialization time, an instance of defaultRandom is created\n  When we execute Random.nextInt() it uses defaultRandom to generate an IntI didn’t know, but companion objects can have a name. Don’t let that distract you. If the companion object of Random has a method nextInt() then you can use it as Random.nextInt() no matter what the name of the companion object is . See the kotlin docs.\n  As a (probably) different Int value is returned each time, some kind of state must have also changed in defaultInt each time we invoke nextInt().\n\n\nInitially, I naively assumed I could get the “current seed” out of such state and, therefore, implement our tests like this:\n\nval seed = Random.getCurrentSeed() // &lt;-- invented function, does not exist\nval sample = r.generate()\nval result = property(sample)\nif (!result)\n  throw PropertyFailedException(attemptNumber, seed, sample)\n\n\n\nUnfortunately, I found no such function. Furthermore, like the name suggests, defaultPlantformRandom() is platform specific and you can’t reason about the implementation used unless you throw the current platform (JVM, Javascript or Native) into the discussion.\n\nBut we have a function in the standard library to get a Random instance with a given seed:\n\npublic fun Random(seed: Long): Random = XorWowRandom(seed.toInt(), seed.shr(32).toInt())\n\n\nThis time, for some reason, the returned type is not dependant on the platform, but we get an XorWowRandom instance no matter the plantform. Again, looking inside it we can actually see its mutable state:\n\ninternal class XorWowRandom internal constructor(\n    private var x: Int,\n    private var y: Int,\n    private var z: Int,\n    private var w: Int,\n    private var v: Int,\n    private var addend: Int\n) : Random() // ...\n\n\nSo, for each tests execution I need to create an instance of Random from a known seed, make our generators use that instance of Random and, in case of failure, inform about the seed I used. How do we generate such a seed? We could use the current time in milliseconds or we can simply use… Random (the default instance):\n\nval seed = Random.nextLong()\nval random = Random(seed)\nval sample = r.generate(random)\nval result = property(sample)\nif (!result)\n  throw PropertyFailedException(attemptNumber, seed, sample)\n\n\nSo our Arbitrary interface is now:\n\ninterface Arb&lt;A&gt; {\n    fun generate(random: Random): A\n    companion object\n}\n\n\nAnd for primitives we simply use the Random argument instead of the platform default Random:\n\nval Arb.Companion.int: Arb&lt;Int&gt; get() = object : Arb&lt;Int&gt; {\n        override fun generate(random: Random): Int = random.nextInt()\n}\n\n\nBut what about combinators? Let’s look at how product2 ens up:\n\nfun &lt;A, B, Z&gt; Arb.Companion.product2(\n    a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, f: (A, B) -&gt; Z\n): Arb&lt;Z&gt; =\n    object : Arb&lt;Z&gt; {\n        override fun generate(random: Random): Z = f(a.generate(random), b.generate(random))\n    }\n\n\nAlthough aparently simple, there are some interesting implications in this design. As random is mutable (like we already saw), this combinator uses it twice, mutating its state twice. And that is exactly what we want: given a seed, the combinator will generate always the same pair of values. And this is valid for any of our other combinators. Let’s see some of them:\n\nfun &lt;A, B, C, Z&gt; Arb.Companion.product3(\n    a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;, f: (A, B, C) -&gt; Z\n): Arb&lt;Z&gt; =\n    object : Arb&lt;Z&gt; {\n        override fun generate(random: Random): Z = f(a.generate(random), b.generate(random), c.generate(random))\n    }\n\nfun &lt;A, B&gt; Arb&lt;A&gt;.map(f: (A) -&gt; B): Arb&lt;B&gt; = object: Arb&lt;B&gt;{\n    override fun generate(random: Random): B = f(this@map.generate(random))\n}\n\n\nFinally, we need our forAny function  to accept an optional seed argument. If such a seed is provided it should just run one test with the samples generated by such seed:\n\nfun &lt;A&gt; forAny(r: Arb&lt;A&gt;, seed: Long? = null, property: (A) -&gt; Boolean) {\n    if (seed == null) {\n        (1..100).forEach { attemptNumber -&gt;\n            val currentSeed = Random.nextLong()\n            val sample = r.generate(Random(currentSeed))\n            val result = property(sample)\n            if (!result)\n                throw PropertyFailedException(attemptNumber, currentSeed, sample)\n        }\n    } else {\n        val sample = r.generate(Random(seed))\n        val result = property(sample)\n        if (!result)\n            throw PropertyFailedException(1, seed, sample)\n    }\n\n}\n\n\nRefactor\n\nI can improve many things but, at least, let’s get rid of the code repetition in forAny I used a function definition inside the forAny function, which may be not that familiar to some readers. I like functions insde functions because they don’t bloat the namespace of your class and they don’t require visibility modifiers. I know I don’t need to look at them when reasoning about any other function that the one they are defined in. But if you don’t like them, simply define a new private function in your class and call it a day.:\n\nfun &lt;A&gt; forAny(r: Arb&lt;A&gt;, seed: Long? = null, property: (A) -&gt; Boolean,) {\n    fun test(currentSeed: Long, attemptNumber: Int) {\n        val sample = r.generate(Random(currentSeed))\n        val result = property(sample)\n        if (!result)\n            throw PropertyFailedException(attemptNumber, currentSeed, sample)\n    }\n    if (seed == null) {\n        (1..100).forEach { attemptNumber -&gt;\n            test(Random.nextLong(), attemptNumber)\n        }\n    } else {\n        test(seed, 1)\n    }\n}\n\n\nConclusion\n\nSo, that’s it! Now, whenever you get a test failure, if you want to run it again after some bug fixing attempt or you need to debug it, you simply look for the seed returned by the error message (let’s say its 123456L) and replace forAny(arb, property) with:\n\nforAny(arb, 123456L, property)\n\n\nYou can see the current version of our library at https://github.com/agile-jordi/wapbtl/tree/part3.\n\nAll articles in the series\n\n\n  Writing a property based testing library, part 1\n  Writing a property based testing library, part 2\n  Writing a property based testing library, part 3\n  Writing a property based testing library, part 4\n\n\n",
            "content_html": "<p>In our <a href=\"/2022-10-04-writing-a-pbt-ibrary-1.html\">previous</a> <a href=\"/2022-10-14-writing-a-pbt-ibrary-2.html\">posts</a> we developed a minimal property based testing (PBT) library capable of checking properties on primitive types, nullable types, tuples and types mapped from other types, giving us the possibility of testing properties of our programs and functions for many kinds of input values.</p>\n\n<p>One of the (many) shortcoming of this small thing we created is in the reproducibility of failed tests. If you are checking a property for simple values like <code class=\"language-plaintext highlighter-rouge\">forAny(Arb.int) { i -&gt; i + i &gt;= i }</code>  the outcome is quite informative:</p>\n\n<div class=\"language-shell highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>Property failed at attempt 3 with sample <span class=\"nt\">-836667656</span>\ncom.agilogy.wapbtl.PropertyFailedException: Property failed at attempt 3 with sample <span class=\"nt\">-836667656</span>\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny<span class=\"nv\">$test</span><span class=\"o\">(</span>forAny.kt:14<span class=\"o\">)</span>\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny<span class=\"o\">(</span>forAny.kt:18<span class=\"o\">)</span>\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny<span class=\"nv\">$default</span><span class=\"o\">(</span>forAny.kt:9<span class=\"o\">)</span>\n</code></pre></div></div>\n\n<p>We have the sample that made our property fail. If we want to reproduce the failed test, we just need to write an example based test with that example. But… What if our sample is a more or less complex datatype whose <code class=\"language-plaintext highlighter-rouge\">toString()</code> is not suitable for a copy &amp; paste into Kotlin code? What if the test is not a one-liner and “simply” writing an example based test involves copying an important amount of lines?</p>\n\n<p>What I would like is to be able to change a single line of code and, hop!, make our property based test just test the exact sample for which I got a failure.</p>\n\n<h2 id=\"randomness\">Randomness</h2>\n\n<p>Grab your <del>dice</del> <ins>instance of Random</ins> and let’s dig into how randomness works…</p>\n\n<p><img src=\"https://media1.giphy.com/media/VGoZVlR9naOZCiRLSy/giphy.gif\" alt=\"Roll The Dice GIFs - Get the best GIF on GIPHY\" /></p>\n\n<p>As you probably already know, random values generation by computers is actually quite a complex topic. Long story short, Kotlin’s <code class=\"language-plaintext highlighter-rouge\">Random</code> generates random values using an, in fact, predictable function that takes a seed and returns an endless sequence of aparently random numbers. Give it the same seed and poof! randomness is gone: you’ll get the same sequence of values. This would be dangerous if you were using pseudo-randomness for cryptogrhaphic purposes, but it is really useful for us.</p>\n\n<p>So, what we need is to be able to seed our tests whenever we want to reproduce a failure.</p>\n\n<h2 id=\"red\">Red</h2>\n\n<p>Let’s do this TDD style. That is, let’s write the test first so that we design the feature by thinking how we would like to use it instead of thinking about how to implement it:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">forAnySeedParameterShouldReproduceTheFailingTest</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kd\">val</span> <span class=\"py\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> <span class=\"n\">i</span> <span class=\"p\">+</span> <span class=\"n\">i</span> <span class=\"p\">&gt;=</span> <span class=\"n\">i</span> <span class=\"p\">}</span>\n    <span class=\"kd\">val</span> <span class=\"py\">failure</span> <span class=\"p\">=</span> <span class=\"n\">assertFailsWith</span><span class=\"p\">&lt;</span><span class=\"nc\">PropertyFailedException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"n\">property</span> <span class=\"p\">=</span> <span class=\"n\">property</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n    <span class=\"kd\">var</span> <span class=\"py\">actualExecutionsWithSeed</span> <span class=\"p\">=</span> <span class=\"mi\">0</span>\n    <span class=\"kd\">val</span> <span class=\"py\">seededFailure</span> <span class=\"p\">=</span> <span class=\"n\">assertFailsWith</span><span class=\"p\">&lt;</span><span class=\"nc\">PropertyFailedException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">seed</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n          <span class=\"n\">actualExecutionsWithSeed</span><span class=\"p\">++</span>\n          <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">it</span><span class=\"p\">)</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n    <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">sample</span><span class=\"p\">,</span> <span class=\"n\">seededFailure</span><span class=\"p\">.</span><span class=\"n\">sample</span><span class=\"p\">)</span>\n    <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">seed</span><span class=\"p\">,</span> <span class=\"n\">seededFailure</span><span class=\"p\">.</span><span class=\"n\">seed</span><span class=\"p\">)</span>\n    <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">seededFailure</span><span class=\"p\">.</span><span class=\"n\">attempt</span><span class=\"p\">)</span>\n    <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">actualExecutionsWithSeed</span><span class=\"p\">)</span>  \n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>So, whenever we get a <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> we want to get a <code class=\"language-plaintext highlighter-rouge\">seed</code>. And, <code class=\"language-plaintext highlighter-rouge\">forAny</code> now will take an optional <code class=\"language-plaintext highlighter-rouge\">seed</code> as an argument and will give us some guarantees:</p>\n\n<ul>\n  <li>If we use the seed returned by a failure, the test will fail</li>\n  <li>The sample (and seed) returned by this failure will be the same sample (and seed) of the original exception</li>\n  <li>But this time, the failure will be found at the first attempt.</li>\n</ul>\n\n<p>So now our <code class=\"language-plaintext highlighter-rouge\">forAny</code> functions will have a signature like this one (here the one for one <code class=\"language-plaintext highlighter-rouge\">Arb</code> argument):</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">):</span> <span class=\"nc\">Unit</span>\n</code></pre></div></div>\n\n<p>And in case of failure it will throw:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">attempt</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span> <span class=\"kd\">val</span> <span class=\"py\">sample</span><span class=\"p\">:</span> <span class=\"nc\">Any</span><span class=\"p\">?,</span> <span class=\"kd\">val</span> <span class=\"py\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">)</span> <span class=\"p\">:</span> <span class=\"nc\">Exception</span><span class=\"p\">(</span>\n    <span class=\"s\">\"Property failed at attempt $attempt with seed $seed, sample $sample\"</span>\n<span class=\"p\">)</span>\n</code></pre></div></div>\n\n<h2 id=\"green\">Green</h2>\n\n<p>Ok, now let’s go for the green.</p>\n\n<p>Our <code class=\"language-plaintext highlighter-rouge\">Arbitrary</code> instances are currently using <code class=\"language-plaintext highlighter-rouge\">kotlin.Random</code> like this:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;</span> <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextInt</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>What does <code class=\"language-plaintext highlighter-rouge\">kotlin.random.Random.nextInt()</code> do? If we look under the hood at the implementation of the standard library, we’ll find:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">package</span> <span class=\"nn\">kotlin.random</span>\n<span class=\"k\">public</span> <span class=\"k\">abstract</span> <span class=\"kd\">class</span> <span class=\"nc\">Random</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// ...</span>\n    <span class=\"k\">companion</span> <span class=\"k\">object</span> <span class=\"nc\">Default</span> <span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">(),</span> <span class=\"nc\">Serializable</span> <span class=\"p\">{</span>\n      <span class=\"c1\">// ...</span>\n      <span class=\"k\">private</span> <span class=\"kd\">val</span> <span class=\"py\">defaultRandom</span><span class=\"p\">:</span> <span class=\"nc\">Random</span> <span class=\"p\">=</span> <span class=\"nf\">defaultPlatformRandom</span><span class=\"p\">()</span>\n      <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">nextInt</span><span class=\"p\">():</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"n\">defaultRandom</span><span class=\"p\">.</span><span class=\"nf\">nextInt</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>There is an important amount of things going on here:</p>\n\n<ol>\n  <li>At initialization time, an instance of <code class=\"language-plaintext highlighter-rouge\">defaultRandom</code> is created</li>\n  <li>When we execute <code class=\"language-plaintext highlighter-rouge\">Random.nextInt()</code> it uses <code class=\"language-plaintext highlighter-rouge\">defaultRandom</code> to generate an <code class=\"language-plaintext sidenote-number highlighter-rouge\">Int</code><em class=\"sidenote\">I didn’t know, but companion objects can have a name. Don’t let that distract you. If the companion object of <code class=\"language-plaintext highlighter-rouge\">Random</code> has a method <code class=\"language-plaintext highlighter-rouge\">nextInt()</code> then you can use it as <code class=\"language-plaintext highlighter-rouge\">Random.nextInt()</code> no matter what the name of the companion object is . See the <a href=\"https://kotlinlang.org/docs/object-declarations.html#companion-objects\">kotlin docs</a>.</em></li>\n  <li>As a (probably) different <code class=\"language-plaintext highlighter-rouge\">Int</code> value is returned each time, some kind of state must have also changed in <code class=\"language-plaintext highlighter-rouge\">defaultInt</code> each time we invoke <code class=\"language-plaintext highlighter-rouge\">nextInt()</code>.</li>\n</ol>\n\n<p>Initially, I naively assumed I could get the “current seed” out of such state and, therefore, implement our tests like this:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">seed</span> <span class=\"p\">=</span> <span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">getCurrentSeed</span><span class=\"p\">()</span> <span class=\"c1\">// &lt;-- invented function, does not exist</span>\n<span class=\"kd\">val</span> <span class=\"py\">sample</span> <span class=\"p\">=</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">()</span>\n<span class=\"kd\">val</span> <span class=\"py\">result</span> <span class=\"p\">=</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">sample</span><span class=\"p\">)</span>\n<span class=\"k\">if</span> <span class=\"p\">(!</span><span class=\"n\">result</span><span class=\"p\">)</span>\n  <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"n\">attemptNumber</span><span class=\"p\">,</span> <span class=\"n\">seed</span><span class=\"p\">,</span> <span class=\"n\">sample</span><span class=\"p\">)</span>\n\n</code></pre></div></div>\n\n<p>Unfortunately, I found no such function. Furthermore, like the name suggests, <code class=\"language-plaintext highlighter-rouge\">defaultPlantformRandom()</code> is platform specific and you can’t reason about the implementation used unless you throw the current platform (JVM, Javascript or Native) into the discussion.</p>\n\n<p>But we have a function in the standard library to get a <code class=\"language-plaintext highlighter-rouge\">Random</code> instance with a given seed:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">public</span> <span class=\"k\">fun</span> <span class=\"nf\">Random</span><span class=\"p\">(</span><span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">):</span> <span class=\"nc\">Random</span> <span class=\"p\">=</span> <span class=\"nc\">XorWowRandom</span><span class=\"p\">(</span><span class=\"n\">seed</span><span class=\"p\">.</span><span class=\"nf\">toInt</span><span class=\"p\">(),</span> <span class=\"n\">seed</span><span class=\"p\">.</span><span class=\"nf\">shr</span><span class=\"p\">(</span><span class=\"mi\">32</span><span class=\"p\">).</span><span class=\"nf\">toInt</span><span class=\"p\">())</span>\n</code></pre></div></div>\n\n<p>This time, for some reason, the returned type is not dependant on the platform, but we get an <code class=\"language-plaintext highlighter-rouge\">XorWowRandom</code> instance no matter the plantform. Again, looking inside it we can actually see its mutable state:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">internal</span> <span class=\"kd\">class</span> <span class=\"nc\">XorWowRandom</span> <span class=\"k\">internal</span> <span class=\"k\">constructor</span><span class=\"p\">(</span>\n    <span class=\"k\">private</span> <span class=\"kd\">var</span> <span class=\"py\">x</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span>\n    <span class=\"k\">private</span> <span class=\"kd\">var</span> <span class=\"py\">y</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span>\n    <span class=\"k\">private</span> <span class=\"kd\">var</span> <span class=\"py\">z</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span>\n    <span class=\"k\">private</span> <span class=\"kd\">var</span> <span class=\"py\">w</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span>\n    <span class=\"k\">private</span> <span class=\"kd\">var</span> <span class=\"py\">v</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span>\n    <span class=\"k\">private</span> <span class=\"kd\">var</span> <span class=\"py\">addend</span><span class=\"p\">:</span> <span class=\"nc\">Int</span>\n<span class=\"p\">)</span> <span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">()</span> <span class=\"c1\">// ...</span>\n</code></pre></div></div>\n\n<p>So, for each tests execution I need to create an instance of <code class=\"language-plaintext highlighter-rouge\">Random</code> from a known seed, make our generators use that instance of <code class=\"language-plaintext highlighter-rouge\">Random</code> and, in case of failure, inform about the seed I used. How do we generate such a seed? We could use the current time in milliseconds or we can simply use… <code class=\"language-plaintext highlighter-rouge\">Random</code> (the default instance):</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">seed</span> <span class=\"p\">=</span> <span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextLong</span><span class=\"p\">()</span>\n<span class=\"kd\">val</span> <span class=\"py\">random</span> <span class=\"p\">=</span> <span class=\"nc\">Random</span><span class=\"p\">(</span><span class=\"n\">seed</span><span class=\"p\">)</span>\n<span class=\"kd\">val</span> <span class=\"py\">sample</span> <span class=\"p\">=</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">)</span>\n<span class=\"kd\">val</span> <span class=\"py\">result</span> <span class=\"p\">=</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">sample</span><span class=\"p\">)</span>\n<span class=\"k\">if</span> <span class=\"p\">(!</span><span class=\"n\">result</span><span class=\"p\">)</span>\n  <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"n\">attemptNumber</span><span class=\"p\">,</span> <span class=\"n\">seed</span><span class=\"p\">,</span> <span class=\"n\">sample</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>So our <code class=\"language-plaintext highlighter-rouge\">Arbitrary</code> interface is now:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">A</span>\n    <span class=\"k\">companion</span> <span class=\"k\">object</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>And for primitives we simply use the <code class=\"language-plaintext highlighter-rouge\">Random</code> argument instead of the platform default <code class=\"language-plaintext highlighter-rouge\">Random</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;</span> <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nf\">nextInt</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But what about combinators? Let’s look at how <code class=\"language-plaintext highlighter-rouge\">product2</code> ens up:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">product2</span><span class=\"p\">(</span>\n    <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">f</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Z</span>\n<span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n    <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">Z</span> <span class=\"p\">=</span> <span class=\"nf\">f</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">),</span> <span class=\"n\">b</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">))</span>\n    <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Although aparently simple, there are some interesting implications in this design. As <code class=\"language-plaintext highlighter-rouge\">random</code> is mutable (like we already saw), this combinator uses it twice, mutating its state twice. And that is exactly what we want: given a seed, the combinator will generate always the same pair of values. And this is valid for any of our other combinators. Let’s see some of them:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">,</span> <span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">product3</span><span class=\"p\">(</span>\n    <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;,</span> <span class=\"n\">f</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Z</span>\n<span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n    <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">Z</span> <span class=\"p\">=</span> <span class=\"nf\">f</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">),</span> <span class=\"n\">b</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">),</span> <span class=\"n\">c</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">))</span>\n    <span class=\"p\">}</span>\n\n<span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nf\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;.</span><span class=\"nf\">map</span><span class=\"p\">(</span><span class=\"n\">f</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">B</span><span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"k\">object</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">B</span> <span class=\"p\">=</span> <span class=\"nf\">f</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"nd\">@map</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">))</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Finally, we need our <code class=\"language-plaintext highlighter-rouge\">forAny</code> function  to accept an optional <code class=\"language-plaintext highlighter-rouge\">seed</code> argument. If such a seed is provided it should just run one test with the samples generated by such seed:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">seed</span> <span class=\"p\">==</span> <span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"o\">..</span><span class=\"mi\">100</span><span class=\"p\">).</span><span class=\"nf\">forEach</span> <span class=\"p\">{</span> <span class=\"n\">attemptNumber</span> <span class=\"p\">-&gt;</span>\n            <span class=\"kd\">val</span> <span class=\"py\">currentSeed</span> <span class=\"p\">=</span> <span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextLong</span><span class=\"p\">()</span>\n            <span class=\"kd\">val</span> <span class=\"py\">sample</span> <span class=\"p\">=</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"nc\">Random</span><span class=\"p\">(</span><span class=\"n\">currentSeed</span><span class=\"p\">))</span>\n            <span class=\"kd\">val</span> <span class=\"py\">result</span> <span class=\"p\">=</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">sample</span><span class=\"p\">)</span>\n            <span class=\"k\">if</span> <span class=\"p\">(!</span><span class=\"n\">result</span><span class=\"p\">)</span>\n                <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"n\">attemptNumber</span><span class=\"p\">,</span> <span class=\"n\">currentSeed</span><span class=\"p\">,</span> <span class=\"n\">sample</span><span class=\"p\">)</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n        <span class=\"kd\">val</span> <span class=\"py\">sample</span> <span class=\"p\">=</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"nc\">Random</span><span class=\"p\">(</span><span class=\"n\">seed</span><span class=\"p\">))</span>\n        <span class=\"kd\">val</span> <span class=\"py\">result</span> <span class=\"p\">=</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">sample</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"p\">(!</span><span class=\"n\">result</span><span class=\"p\">)</span>\n            <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"n\">seed</span><span class=\"p\">,</span> <span class=\"n\">sample</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"refactor\">Refactor</h2>\n\n<p>I can improve many things but, at least, let’s get rid of the code repetition in <code class=\"language-plaintext sidenote-number highlighter-rouge\">forAny</code> <em class=\"sidenote\">I used a function definition inside the <code class=\"language-plaintext highlighter-rouge\">forAny</code> function, which may be not that familiar to some readers. I like functions insde functions because they don’t bloat the namespace of your class and they don’t require visibility modifiers. I know I don’t need to look at them when reasoning about any other function that the one they are defined in. But if you don’t like them, simply define a new private function in your class and call it a day.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">seed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">?</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">,)</span> <span class=\"p\">{</span>\n    <span class=\"k\">fun</span> <span class=\"nf\">test</span><span class=\"p\">(</span><span class=\"n\">currentSeed</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">,</span> <span class=\"n\">attemptNumber</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"kd\">val</span> <span class=\"py\">sample</span> <span class=\"p\">=</span> <span class=\"n\">r</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"nc\">Random</span><span class=\"p\">(</span><span class=\"n\">currentSeed</span><span class=\"p\">))</span>\n        <span class=\"kd\">val</span> <span class=\"py\">result</span> <span class=\"p\">=</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">sample</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"p\">(!</span><span class=\"n\">result</span><span class=\"p\">)</span>\n            <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"n\">attemptNumber</span><span class=\"p\">,</span> <span class=\"n\">currentSeed</span><span class=\"p\">,</span> <span class=\"n\">sample</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">seed</span> <span class=\"p\">==</span> <span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"o\">..</span><span class=\"mi\">100</span><span class=\"p\">).</span><span class=\"nf\">forEach</span> <span class=\"p\">{</span> <span class=\"n\">attemptNumber</span> <span class=\"p\">-&gt;</span>\n            <span class=\"nf\">test</span><span class=\"p\">(</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextLong</span><span class=\"p\">(),</span> <span class=\"n\">attemptNumber</span><span class=\"p\">)</span>\n        <span class=\"p\">}</span>\n    <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n        <span class=\"nf\">test</span><span class=\"p\">(</span><span class=\"n\">seed</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"conclusion\">Conclusion</h2>\n\n<p>So, that’s it! Now, whenever you get a test failure, if you want to run it again after some bug fixing attempt or you need to debug it, you simply look for the seed returned by the error message (let’s say its <code class=\"language-plaintext highlighter-rouge\">123456L</code>) and replace <code class=\"language-plaintext highlighter-rouge\">forAny(arb, property)</code> with:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">arb</span><span class=\"p\">,</span> <span class=\"mi\">123456L</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>You can see the current version of our library at <a href=\"https://github.com/agile-jordi/wapbtl/tree/part3\">https://github.com/agile-jordi/wapbtl/tree/part3</a>.</p>\n\n<h2 id=\"all-articles-in-the-series\">All articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-10-04-writing-a-pbt-ibrary-1.html\">Writing a property based testing library, part 1</a></li>\n  <li><a href=\"./2022-10-14-writing-a-pbt-ibrary-2.html\">Writing a property based testing library, part 2</a></li>\n  <li><a href=\"./2022-10-25-writing-a-pbt-ibrary-3.html\">Writing a property based testing library, part 3</a></li>\n  <li><a href=\"./2024-01-12-writing-a-pbt-library-4-housekeeping.html\">Writing a property based testing library, part 4</a></li>\n</ol>\n\n",
            "url": "https://blog.agilogy.com/2022-10-25-writing-a-pbt-ibrary-3.html",
            "date_published": "2022-10-25T00:00:00+02:00",
            "date_modified": "2022-10-25T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-10-14-writing-a-pbt-ibrary-2.html",
            "title": "Writing a Property Based Testing library in Kotlin, a Journey (part 2)",
            "content_text": "In our previous post we developed a minimal Property Based Testing library in Kotlin that was capable of testing properties of Int values. Amongst its limitations, I find its inhability to test properties on other types disturbing. So let’s add some more Arb values to our beloved library.\n\nSimple types\n\nWe could start by adding Arb instances for some types for which kotlin.random.Random already knows how to generate random valuesWhat about Char and String, aren’t they simple? They aren’t. Not if you work outside the ASCII limits. Which I do. Because I speak catalan, and we have things like è or ç or even l·l… and I work in projects that use asiatic languages which for us, poor latin alphabet users, are a complex fantasy.:\n\nval Arb.Companion.long: Arb&lt;Long&gt; get() = object : Arb&lt;Long&gt; {\n    override fun generate(): Long = kotlin.random.Random.nextLong()\n}\n\nval Arb.Companion.float: Arb&lt;Float&gt; get() = object : Arb&lt;Float&gt;{\n    override fun generate(): Float = kotlin.random.Random.nextFloat()\n}\n\nval Arb.Companion.double: Arb&lt;Double&gt; get() = object : Arb&lt;Double&gt;{\n    override fun generate(): Double = kotlin.random.Random.nextDouble()\n}\n\nval Arb.Companion.boolean: Arb&lt;Boolean&gt; get() = object : Arb&lt;Boolean&gt;{\n    override fun generate(): Boolean = kotlin.random.Random.nextBoolean()\n}\n\n\nStudying kotlin.random.Random we can see it is also easy to generate random values within a range. So, let’s add that:\n\nfun Arb.Companion.int(range: IntRange): Arb&lt;Int&gt; = object : Arb&lt;Int&gt; {\n    override fun generate(): Int = kotlin.random.Random.nextInt(range)\n}\n\n\nAnd so on…\n\nNullable values\n\nWhat about nullable types like Int? or Float?. We could build a nullable version of each Arb we have, but that would be tedious and repetitive. What we would like is to be able to convert an Arb&lt;A&gt; to an Arb&lt;A?&gt; for any given A .\n\nLet’s try it! We can even adjust the probability we want to get a null value: We parameterize the type as &lt;A: Any&gt; so that you can’t use orNull on already nullable types. That will avoid confusion, as applying multiple times orNull would exagerate the probability of null values being generated.\n\nfun &lt;A : Any&gt; Arb&lt;A&gt;.orNull(nullProbability: Double = 0.5): Arb&lt;A?&gt; =\n  object : Arb&lt;A?&gt; {\n    override fun generate(): A? =\n      if (Random.nextDouble(0.0, 1.0) &lt;= nullProbability) null\n      else this@orNull.generate()\n}\n\n\nArbitrary pairs, triples and other tuples\n\nLet’s say I want to check a typical property, like the commutativity of the sum of integers:\n\n\n  For any pair of ints a, b: a + b = b + a\n\n\nIn this example I need arbitrary values of type Pair&lt;Int, Int&gt;. Again, instead of thinking about a specific solution every time we need one, let’s generalize that to arbitrary values that are tuples of other types:\n\nfun &lt;A, B&gt; Arb.Companion.pair(a: Arb&lt;A&gt;, b: Arb&lt;B&gt;): Arb&lt;Pair&lt;A, B&gt;&gt; =\n    object : Arb&lt;Pair&lt;A, B&gt;&gt; {\n        override fun generate(): Pair&lt;A, B&gt; = a.generate() to b.generate()\n    }\n\nfun &lt;A, B, C&gt; Arb.Companion.triple(\n  a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;\n): Arb&lt;Triple&lt;A, B, C&gt;&gt; =\n    object : Arb&lt;Triple&lt;A, B, C&gt;&gt; {\n        override fun generate(): Triple&lt;A, B, C&gt; =\n            Triple(a.generate(), b.generate(), c.generate())\n    }\n\n\nOf course, in the Kotlin tradition of not having tuples of arity greater than 3, we can add versions of this idea for whatever arity as long as we ask for a function to build the result:\n\nfun &lt;A, B, Z&gt; Arb.Companion.product2(\n  a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, f: (A, B) -&gt; Z\n): Arb&lt;Z&gt; =\n    object : Arb&lt;Z&gt; {\n        override fun generate(): Z = f(a.generate(), b.generate())\n    }\n\nfun &lt;A, B, C, Z&gt; Arb.Companion.product3(\n  a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;, f: (A, B, C) -&gt; Z\n): Arb&lt;Z&gt; =\n    object : Arb&lt;Z&gt; {\n        override fun generate(): Z = \n          f(a.generate(), b.generate(), c.generate())\n    }\n\nfun &lt;A, B, C, D, Z&gt; Arb.Companion.product4(\n    a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;, d: Arb&lt;D&gt;, f: (A, B, C, D) -&gt; Z\n): Arb&lt;Z&gt; =\n    object : Arb&lt;Z&gt; {\n        override fun generate(): Z = \n          f(a.generate(), b.generate(), c.generate(), d.generate())\n    }\n\n\nAnd now we can see pair and triple as simple helpers over product2 and product3:\n\nfun &lt;A, B&gt; Arb.Companion.pair(a: Arb&lt;A&gt;, b: Arb&lt;B&gt;): Arb&lt;Pair&lt;A, B&gt;&gt; =\n    product2(a, b, ::Pair)\n\nfun &lt;A, B, C&gt; Arb.Companion.triple(\n  a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;\n): Arb&lt;Triple&lt;A, B, C&gt;&gt; =\n    product3(a, b, c, ::Triple)\n\n\nNow we can test our commutativity:\n\n@Test\nfun testSumCommutativity() {\n    forAny(Arb.pair(Arb.int, Arb.int)){ (a, b) -&gt; a + b == b + a }\n}\n\n\nLooking at this example, it seems interesting to make forAny accept more than one Arb so that our user doesn’t need to build a tuple to test properties over a number of values:\n\nfun &lt;A, B&gt; forAny(a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, property: (A, B) -&gt; Boolean) =\n    forAny(Arb.pair(a, b)){ (a, b) -&gt; property(a,b) }\n\n\nUnfortunately this approach builds an unnecessary Pair and is limited to arities 2 and 3. Let’s try a different approach:\n\nfun &lt;A, B&gt; forAny(a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, property: (A, B) -&gt; Boolean) =\n    forAny(Arb.product2(a, b, property)){ it }\n\nfun &lt;A, B, C&gt; forAny(a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, c: Arb&lt;C&gt;, property: (A, B, C) -&gt; Boolean) =\n    forAny(Arb.product3(a, b, c, property)){ it }\n\n\nWait! What did I just do here? I must admit it. I actually wrote these articles some weeks ago and now, while proofreading it before publishing, I couldn’t initially remember how this works. So let’s try to explain it a bit.\n\nThe trick is using property as the function argument of productN. That way, the productN function directly builds the result of evaluating the property. Hence, we expect, forAny such evaluated property, to simply be true. It’s like:\n\nfun &lt;A, B&gt; forAny(a: Arb&lt;A&gt;, b: Arb&lt;B&gt;, property: (A, B) -&gt; Boolean) =\n    forAny(Arb.product2(a, b, property)){ propertyEvaluationResult -&gt; propertyEvaluationResult == true }\n\n\n\nThe first version I showed simply uses the implicit it parameter name and avoids the ugly it == true expression.\n\nNow we can use any arity we have a productN for and we will not be building an intermediate tuple just to get its parts when we need to actually evaluate the property.\n\nFinally, our property would be:\n\n@Test\nfun testSumCommutativity() {\n    forAny(Arb.int, Arb.int){ a, b -&gt; a + b == b + a }\n}\n\n\nMapping…\n\nNow let’s say you have a nice Enum representing some important business type:\n\nenum class DayOfWeek{\n    Mon, Tue, Wed, Thu, Fri, Sat, Sun;\n    fun next(days: Int): DayOfWeek = ...\n}\n\n\nAnd let’s imagine we want to check some properties involving days of week. We may want to check that days of the week repeat after 7 days. Or we may want to check that we know how to write the day of the week in a String and read it afterwards. Whatever the property, we need an Arb&lt;DayOfWeek&gt;.\n\nWe can build one by generating a random number between 0 and 6 and getting the enum value in that position:\n\nfun Arb.Companion.dayOfWeek() = object : Arb&lt;DayOfWeek&gt; {\n    override fun generate(): DayOfWeek {\n        val i = kotlin.random.Random.nextInt(0..6)\n        return DayOfWeek.values()[i]\n    }\n}\n\n\nBut it is a shame we repeated the generation of random integers. We already implemented that. Let’s say we want to be able to apply DayOfWeek.values()[i] to whatever i is generated by Arb.int. Does that sound familiar? Not yet? Ok, let’s call it map:\n\n}\nWait! What was that???\n\nfun &lt;A, B&gt; Arb&lt;A&gt;.map(f: (A) -&gt; B): Arb&lt;B&gt; = object: Arb&lt;B&gt;{\n    override fun generate(): B = f(this@map.generate())\n}\n\n\nNow, we can rewrite our dayOfWeek Arb like this:\n\nfun Arb.Companion.dayOfWeek() = Arb.int(0..6).map { DayOfWeek.values()[it] }\n\n\nIn fact, we can generalize further by providing a way to generate arbitrary values of any Enum. The trick is the function enumValues&lt;E&gt; that Kotlin provides. If you invoke it (with a type parameter which is an Enum) it will return all the values of the Enum. If you try, IntelliJ will complain that your function must be inline and your type param reifiedIf this sounds alien to you, you can learn more about inline functions and reified parameters in the excellent Kotlin documentation.. Just Alt+Enter it!\n\ninline fun &lt;reified E : Enum&lt;E&gt;&gt; Arb.Companion.enum(): Arb&lt;E&gt; {\n    val values = enumValues&lt;E&gt;()\n    return Arb.int(values.indices).map { values[it] }\n}\n\n\nCreating arbitraries for (arbitrary) data classes\n\nDid you see what I did? We are now equipped with:\n\n  Arbitrary instances for primitive types\n  A combinator orNull() to go from Arbitrary&lt;A&gt; to Arbitrary&lt;A?&gt;\n  A combinator map to go from Arbitrary&lt;A&gt; to Arbitrary&lt;B&gt; given a function (A) -&gt; B\n  A family of combinators product2, product3, product4, etc. to build an instance of Arbitrary from several instances of (possibly) different types.\n\n\nArmed with all these tools, we can now generate many of the instances we need. In particular, we can now generate an Arbitrary for any data class as long as we have the needed primitive instances I’m aware we have unsigned integers in Kotlin, but I wanted an example of map being used and that was what I got.:\n\ndata class Natural(val value: Int)\ndata class Coordinates(val x: Int, val y: Int)\ndata class Circle(val center: Coordinates, val radius: Int)\nval distanceArb = Arb.int(0..10).map{ Natural(it) }\nval coordinateArb = Arb.int(-10..10)\nval coordinatesArb = Arb.product2(coordinateArb, coordinateArb) {\n  x, y -&gt; Coordinates(x, y) \n}\nval circleArb = Arb.product2(coordinatesArb, distanceArb) { \n  coords, radius -&gt; Circle(coords, radius) \n}\n\n\nHow cool is that!!?? 😎 Now, if you know about ADTs you know we have product types… but we are missing sum types. This one is long enough, so let’s add those to our backlog.\n\nConclusion\n\nWe added values and functions to get Arb instances of several types. Beyond primitive Arb types we built by hand (like Boolean, Int, Double and so on), we started creating Arb combinators, functions that take Arb instances and maybe other parameters and return new Arb instances.\n\nIn particular, we first created a combinator orNull() that given an Arb&lt;A&gt; (where A is not nullable) returns an Arb&lt;A?&gt;. Then we saw how to create an Arb of pairs of types given a pair of Arbs of (possibly) different types and generalized the idea to any arity. Finally we saw how to map over Arb instances to get an Arb that returns the result of applying a function to the result of the original Arb.\n\nYou can see the current version of our library at https://github.com/agile-jordi/wapbtl/tree/part2.\n\nAll articles in the series\n\n\n  Writing a property based testing library, part 1\n  Writing a property based testing library, part 2\n  Writing a property based testing library, part 3\n  Writing a property based testing library, part 4\n\n\n",
            "content_html": "<p>In our <a href=\"/2022-10-04-writing-a-pbt-ibrary-1.html\">previous post</a> we developed a minimal Property Based Testing library in Kotlin that was capable of testing properties of <code class=\"language-plaintext highlighter-rouge\">Int</code> values. Amongst its limitations, I find its inhability to test properties on other types disturbing. So let’s add some more <code class=\"language-plaintext highlighter-rouge\">Arb</code> values to our beloved library.</p>\n\n<h2 id=\"simple-types\">Simple types</h2>\n\n<p>We could start by adding <code class=\"language-plaintext highlighter-rouge\">Arb</code> instances for some types for which <code class=\"language-plaintext highlighter-rouge\">kotlin.random.Random</code> already knows how to generate random <em class=\"sidenote-number\">values</em><em class=\"sidenote\">What about <code class=\"language-plaintext highlighter-rouge\">Char</code> and <code class=\"language-plaintext highlighter-rouge\">String</code>, aren’t they simple? They aren’t. Not if you work outside the ASCII limits. Which I do. Because I speak catalan, and we have things like <code class=\"language-plaintext highlighter-rouge\">è</code> or <code class=\"language-plaintext highlighter-rouge\">ç</code> or even <code class=\"language-plaintext highlighter-rouge\">l·l</code>… and I work in projects that use asiatic languages which for us, poor latin alphabet users, are a complex fantasy.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">long</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Long</span><span class=\"p\">&gt;</span> <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Long</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Long</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextLong</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n\n<span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">float</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Float</span><span class=\"p\">&gt;</span> <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Float</span><span class=\"p\">&gt;{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Float</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextFloat</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n\n<span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">double</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Double</span><span class=\"p\">&gt;</span> <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Double</span><span class=\"p\">&gt;{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Double</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextDouble</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n\n<span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">boolean</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Boolean</span><span class=\"p\">&gt;</span> <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Boolean</span><span class=\"p\">&gt;{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Boolean</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextBoolean</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Studying <code class=\"language-plaintext highlighter-rouge\">kotlin.random.Random</code> we can see it is also easy to generate random values within a range. So, let’s add that:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">range</span><span class=\"p\">:</span> <span class=\"nc\">IntRange</span><span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextInt</span><span class=\"p\">(</span><span class=\"n\">range</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>And so on…</p>\n\n<h2 id=\"nullable-values\">Nullable values</h2>\n\n<p>What about nullable types like <code class=\"language-plaintext highlighter-rouge\">Int?</code> or <code class=\"language-plaintext highlighter-rouge\">Float?</code>. We could build a nullable version of each <code class=\"language-plaintext highlighter-rouge\">Arb</code> we have, but that would be tedious and repetitive. What we would like is to be able to convert an <code class=\"language-plaintext highlighter-rouge\">Arb&lt;A&gt;</code> to an <code class=\"language-plaintext highlighter-rouge\">Arb&lt;A?&gt;</code> for any given <code class=\"language-plaintext highlighter-rouge\">A</code> .</p>\n\n<p>Let’s try it! We can even adjust the probability we want to get a null value: <em class=\"marginnote\">We parameterize the type as &lt;A: Any&gt; so that you can’t use <code class=\"language-plaintext highlighter-rouge\">orNull</code> on already nullable types. That will avoid confusion, as applying multiple times <code class=\"language-plaintext highlighter-rouge\">orNull</code> would exagerate the probability of null values being generated.</em></p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span> <span class=\"p\">:</span> <span class=\"nc\">Any</span><span class=\"p\">&gt;</span> <span class=\"nf\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;.</span><span class=\"nf\">orNull</span><span class=\"p\">(</span><span class=\"n\">nullProbability</span><span class=\"p\">:</span> <span class=\"nc\">Double</span> <span class=\"p\">=</span> <span class=\"mf\">0.5</span><span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n  <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">?&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">A</span><span class=\"p\">?</span> <span class=\"p\">=</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextDouble</span><span class=\"p\">(</span><span class=\"mf\">0.0</span><span class=\"p\">,</span> <span class=\"mf\">1.0</span><span class=\"p\">)</span> <span class=\"p\">&lt;=</span> <span class=\"n\">nullProbability</span><span class=\"p\">)</span> <span class=\"k\">null</span>\n      <span class=\"k\">else</span> <span class=\"k\">this</span><span class=\"nd\">@orNull</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"arbitrary-pairs-triples-and-other-tuples\">Arbitrary pairs, triples and other tuples</h2>\n\n<p>Let’s say I want to check a typical property, like the commutativity of the sum of integers:</p>\n\n<blockquote>\n  <p>For any pair of ints a, b: a + b = b + a</p>\n</blockquote>\n\n<p>In this example I need arbitrary values of type <code class=\"language-plaintext highlighter-rouge\">Pair&lt;Int, Int&gt;</code>. Again, instead of thinking about a specific solution every time we need one, let’s generalize that to arbitrary values that are tuples of other types:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">pair</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Pair</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;&gt;</span> <span class=\"p\">=</span>\n    <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Pair</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Pair</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">()</span> <span class=\"n\">to</span> <span class=\"n\">b</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n\n<span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">triple</span><span class=\"p\">(</span>\n  <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;</span>\n<span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Triple</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;&gt;</span> <span class=\"p\">=</span>\n    <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Triple</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Triple</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n            <span class=\"nc\">Triple</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">b</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">c</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">())</span>\n    <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Of course, in the Kotlin tradition of <strong>not</strong> having tuples of arity greater than 3, we can add versions of this idea for whatever arity as long as we ask for a function to build the result:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">product2</span><span class=\"p\">(</span>\n  <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">f</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Z</span>\n<span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n    <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Z</span> <span class=\"p\">=</span> <span class=\"nf\">f</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">b</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">())</span>\n    <span class=\"p\">}</span>\n\n<span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">,</span> <span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">product3</span><span class=\"p\">(</span>\n  <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;,</span> <span class=\"n\">f</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Z</span>\n<span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n    <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Z</span> <span class=\"p\">=</span> \n          <span class=\"nf\">f</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">b</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">c</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">())</span>\n    <span class=\"p\">}</span>\n\n<span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">,</span> <span class=\"nc\">D</span><span class=\"p\">,</span> <span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">product4</span><span class=\"p\">(</span>\n    <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;,</span> <span class=\"n\">d</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">D</span><span class=\"p\">&gt;,</span> <span class=\"n\">f</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">,</span> <span class=\"nc\">D</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Z</span>\n<span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n    <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Z</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Z</span> <span class=\"p\">=</span> \n          <span class=\"nf\">f</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">b</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">c</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">(),</span> <span class=\"n\">d</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">())</span>\n    <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>And now we can see <code class=\"language-plaintext highlighter-rouge\">pair</code> and <code class=\"language-plaintext highlighter-rouge\">triple</code> as simple helpers over <code class=\"language-plaintext highlighter-rouge\">product2</code> and <code class=\"language-plaintext highlighter-rouge\">product3</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">pair</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Pair</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;&gt;</span> <span class=\"p\">=</span>\n    <span class=\"nf\">product2</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"o\">::</span><span class=\"nc\">Pair</span><span class=\"p\">)</span>\n\n<span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">triple</span><span class=\"p\">(</span>\n  <span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;</span>\n<span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Triple</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;&gt;</span> <span class=\"p\">=</span>\n    <span class=\"nf\">product3</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"o\">::</span><span class=\"nc\">Triple</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Now we can test our commutativity:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testSumCommutativity</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">pair</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)){</span> <span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"n\">a</span> <span class=\"p\">+</span> <span class=\"n\">b</span> <span class=\"p\">==</span> <span class=\"n\">b</span> <span class=\"p\">+</span> <span class=\"n\">a</span> <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Looking at this example, it seems interesting to make <code class=\"language-plaintext highlighter-rouge\">forAny</code> accept more than one <code class=\"language-plaintext highlighter-rouge\">Arb</code> so that our user doesn’t need to build a tuple to test properties over a number of values:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">)</span> <span class=\"p\">=</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">pair</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)){</span> <span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span><span class=\"n\">b</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Unfortunately this approach builds an unnecessary <code class=\"language-plaintext highlighter-rouge\">Pair</code> and is limited to arities 2 and 3. Let’s try a different approach:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">)</span> <span class=\"p\">=</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">product2</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">)){</span> <span class=\"n\">it</span> <span class=\"p\">}</span>\n\n<span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">c</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">C</span><span class=\"p\">&gt;,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">,</span> <span class=\"nc\">C</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">)</span> <span class=\"p\">=</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">product3</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">c</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">)){</span> <span class=\"n\">it</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Wait! What did I just do <em class=\"sidenote-number\">here?</em> <em class=\"sidenote\">I must admit it. I actually wrote these articles some weeks ago and now, while proofreading it before publishing, I couldn’t initially remember how this works. So let’s try to explain it a bit.</em></p>\n\n<p>The trick is using <code class=\"language-plaintext highlighter-rouge\">property</code> as the function argument of <code class=\"language-plaintext highlighter-rouge\">productN</code>. That way, the <code class=\"language-plaintext highlighter-rouge\">productN</code> function directly builds the result of evaluating the property. Hence, we expect, <code class=\"language-plaintext highlighter-rouge\">forAny</code> such evaluated property, to simply be true. It’s like:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">)</span> <span class=\"p\">=</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">product2</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">)){</span> <span class=\"n\">propertyEvaluationResult</span> <span class=\"p\">-&gt;</span> <span class=\"n\">propertyEvaluationResult</span> <span class=\"p\">==</span> <span class=\"k\">true</span> <span class=\"p\">}</span>\n\n</code></pre></div></div>\n\n<p>The first version I showed simply uses the implicit <code class=\"language-plaintext highlighter-rouge\">it</code> parameter name and avoids the ugly <code class=\"language-plaintext highlighter-rouge\">it == true</code> expression.</p>\n\n<p>Now we can use any arity we have a <code class=\"language-plaintext highlighter-rouge\">productN</code> for and we will not be building an intermediate tuple just to get its parts when we need to actually evaluate the property.</p>\n\n<p>Finally, our property would be:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testSumCommutativity</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">){</span> <span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"p\">-&gt;</span> <span class=\"n\">a</span> <span class=\"p\">+</span> <span class=\"n\">b</span> <span class=\"p\">==</span> <span class=\"n\">b</span> <span class=\"p\">+</span> <span class=\"n\">a</span> <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"mapping\">Mapping…</h2>\n\n<p>Now let’s say you have a nice <code class=\"language-plaintext highlighter-rouge\">Enum</code> representing some important business type:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">enum</span> <span class=\"kd\">class</span> <span class=\"nc\">DayOfWeek</span><span class=\"p\">{</span>\n    <span class=\"nc\">Mon</span><span class=\"p\">,</span> <span class=\"nc\">Tue</span><span class=\"p\">,</span> <span class=\"nc\">Wed</span><span class=\"p\">,</span> <span class=\"nc\">Thu</span><span class=\"p\">,</span> <span class=\"nc\">Fri</span><span class=\"p\">,</span> <span class=\"nc\">Sat</span><span class=\"p\">,</span> <span class=\"nc\">Sun</span><span class=\"p\">;</span>\n    <span class=\"k\">fun</span> <span class=\"nf\">next</span><span class=\"p\">(</span><span class=\"n\">days</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">):</span> <span class=\"nc\">DayOfWeek</span> <span class=\"p\">=</span> <span class=\"o\">..</span><span class=\"p\">.</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>And let’s imagine we want to check some properties involving days of week. We may want to check that days of the week repeat after 7 days. Or we may want to check that we know how to write the day of the week in a String and read it afterwards. Whatever the property, we need an <code class=\"language-plaintext highlighter-rouge\">Arb&lt;DayOfWeek&gt;</code>.</p>\n\n<p>We can build one by generating a random number between 0 and 6 and getting the enum value in that position:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">dayOfWeek</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"kd\">object</span> <span class=\"err\">: </span><span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">DayOfWeek</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">DayOfWeek</span> <span class=\"p\">{</span>\n        <span class=\"kd\">val</span> <span class=\"py\">i</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextInt</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"o\">..</span><span class=\"mi\">6</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nc\">DayOfWeek</span><span class=\"p\">.</span><span class=\"nf\">values</span><span class=\"p\">()[</span><span class=\"n\">i</span><span class=\"p\">]</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But it is a shame we repeated the generation of random integers. We already implemented that. Let’s say we want to be able to apply <code class=\"language-plaintext highlighter-rouge\">DayOfWeek.values()[i]</code> to whatever <code class=\"language-plaintext highlighter-rouge\">i</code> is generated by <code class=\"language-plaintext highlighter-rouge\">Arb.int</code>. Does that sound familiar? Not yet? Ok, let’s call it <code class=\"language-plaintext highlighter-rouge\">map</code>:</p>\n\n<p><img src=\"../assets/scary-monad.gif\" alt=\"scary-monad\" class=\"figcaption\" />}\n<em class=\"figcaption\">Wait! What was that???</em></p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">,</span> <span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"nf\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;.</span><span class=\"nf\">map</span><span class=\"p\">(</span><span class=\"n\">f</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">B</span><span class=\"p\">):</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"k\">object</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">B</span><span class=\"p\">&gt;{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">B</span> <span class=\"p\">=</span> <span class=\"nf\">f</span><span class=\"p\">(</span><span class=\"k\">this</span><span class=\"nd\">@map</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">())</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Now, we can rewrite our <code class=\"language-plaintext highlighter-rouge\">dayOfWeek</code> <code class=\"language-plaintext highlighter-rouge\">Arb</code> like this:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">dayOfWeek</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"o\">..</span><span class=\"mi\">6</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"nc\">DayOfWeek</span><span class=\"p\">.</span><span class=\"nf\">values</span><span class=\"p\">()[</span><span class=\"n\">it</span><span class=\"p\">]</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>In fact, we can generalize further by providing a way to generate arbitrary values of any <code class=\"language-plaintext highlighter-rouge\">Enum</code>. The trick is the function <code class=\"language-plaintext highlighter-rouge\">enumValues&lt;E&gt;</code> that Kotlin provides. If you invoke it (with a type parameter which is an <code class=\"language-plaintext highlighter-rouge\">Enum</code>) it will return all the values of the <code class=\"language-plaintext highlighter-rouge\">Enum</code>. If you try, IntelliJ will complain that your function must be <code class=\"language-plaintext highlighter-rouge\">inline</code> and your type param <code class=\"language-plaintext sidenote-number highlighter-rouge\">reified</code><em class=\"sidenote\">If this sounds alien to you, you can learn more about inline functions and reified parameters in the excellent <a href=\"https://kotlinlang.org/docs/inline-functions.html#reified-type-parameters\">Kotlin documentation</a>.</em>. Just <code class=\"language-plaintext highlighter-rouge\">Alt+Enter</code> it!</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">inline</span> <span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"k\">reified</span> <span class=\"nc\">E</span> <span class=\"p\">:</span> <span class=\"nc\">Enum</span><span class=\"p\">&lt;</span><span class=\"nc\">E</span><span class=\"p\">&gt;&gt;</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"nf\">enum</span><span class=\"p\">():</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">E</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"kd\">val</span> <span class=\"py\">values</span> <span class=\"p\">=</span> <span class=\"n\">enumValues</span><span class=\"p\">&lt;</span><span class=\"nc\">E</span><span class=\"p\">&gt;()</span>\n    <span class=\"k\">return</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"n\">values</span><span class=\"p\">.</span><span class=\"n\">indices</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"n\">values</span><span class=\"p\">[</span><span class=\"n\">it</span><span class=\"p\">]</span> <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"creating-arbitraries-for-arbitrary-data-classes\">Creating arbitraries for (arbitrary) data classes</h2>\n\n<p>Did you see what I did? We are now equipped with:</p>\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">Arbitrary</code> instances for primitive types</li>\n  <li>A combinator <code class=\"language-plaintext highlighter-rouge\">orNull()</code> to go from <code class=\"language-plaintext highlighter-rouge\">Arbitrary&lt;A&gt;</code> to <code class=\"language-plaintext highlighter-rouge\">Arbitrary&lt;A?&gt;</code></li>\n  <li>A combinator <code class=\"language-plaintext highlighter-rouge\">map</code> to go from <code class=\"language-plaintext highlighter-rouge\">Arbitrary&lt;A&gt;</code> to <code class=\"language-plaintext highlighter-rouge\">Arbitrary&lt;B&gt;</code> given a function <code class=\"language-plaintext highlighter-rouge\">(A) -&gt; B</code></li>\n  <li>A family of combinators <code class=\"language-plaintext highlighter-rouge\">product2</code>, <code class=\"language-plaintext highlighter-rouge\">product3</code>, <code class=\"language-plaintext highlighter-rouge\">product4</code>, etc. to build an instance of <code class=\"language-plaintext highlighter-rouge\">Arbitrary</code> from several instances of (possibly) different types.</li>\n</ul>\n\n<p>Armed with all these tools, we can now generate <strong>many</strong> of the instances we need. In particular, we can now generate an <code class=\"language-plaintext highlighter-rouge\">Arbitrary</code> for any data class as long as we have the needed primitive <em class=\"sidenote-number\">instances</em> <em class=\"sidenote\">I’m aware we have unsigned integers in Kotlin, but I wanted an example of <code class=\"language-plaintext highlighter-rouge\">map</code> being used and that was what I got.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">data class</span> <span class=\"nc\">Natural</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">value</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">)</span>\n<span class=\"kd\">data class</span> <span class=\"nc\">Coordinates</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">x</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span> <span class=\"kd\">val</span> <span class=\"py\">y</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">)</span>\n<span class=\"kd\">data class</span> <span class=\"nc\">Circle</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">center</span><span class=\"p\">:</span> <span class=\"nc\">Coordinates</span><span class=\"p\">,</span> <span class=\"kd\">val</span> <span class=\"py\">radius</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">)</span>\n<span class=\"kd\">val</span> <span class=\"py\">distanceArb</span> <span class=\"p\">=</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">int</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"o\">..</span><span class=\"mi\">10</span><span class=\"p\">).</span><span class=\"nf\">map</span><span class=\"p\">{</span> <span class=\"nc\">Natural</span><span class=\"p\">(</span><span class=\"n\">it</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n<span class=\"kd\">val</span> <span class=\"py\">coordinateArb</span> <span class=\"p\">=</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">int</span><span class=\"p\">(-</span><span class=\"mi\">10</span><span class=\"o\">..</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n<span class=\"kd\">val</span> <span class=\"py\">coordinatesArb</span> <span class=\"p\">=</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">product2</span><span class=\"p\">(</span><span class=\"n\">coordinateArb</span><span class=\"p\">,</span> <span class=\"n\">coordinateArb</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Coordinates</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">)</span> \n<span class=\"p\">}</span>\n<span class=\"kd\">val</span> <span class=\"py\">circleArb</span> <span class=\"p\">=</span> <span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"nf\">product2</span><span class=\"p\">(</span><span class=\"n\">coordinatesArb</span><span class=\"p\">,</span> <span class=\"n\">distanceArb</span><span class=\"p\">)</span> <span class=\"p\">{</span> \n  <span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"n\">radius</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Circle</span><span class=\"p\">(</span><span class=\"n\">coords</span><span class=\"p\">,</span> <span class=\"n\">radius</span><span class=\"p\">)</span> \n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>How cool is that!!?? 😎 Now, if you know about ADTs you know we have product types… but we are missing sum types. This one is long enough, so let’s add those to our backlog.</p>\n\n<h2 id=\"conclusion\">Conclusion</h2>\n\n<p>We added values and functions to get <code class=\"language-plaintext highlighter-rouge\">Arb</code> instances of several types. Beyond <em>primitive</em> <code class=\"language-plaintext highlighter-rouge\">Arb</code> types we built by hand (like <code class=\"language-plaintext highlighter-rouge\">Boolean</code>, <code class=\"language-plaintext highlighter-rouge\">Int</code>, <code class=\"language-plaintext highlighter-rouge\">Double</code> and so on), we started creating <code class=\"language-plaintext highlighter-rouge\">Arb</code> <strong>combinators</strong>, functions that take <code class=\"language-plaintext highlighter-rouge\">Arb</code> instances and maybe other parameters and return new <code class=\"language-plaintext highlighter-rouge\">Arb</code> instances.</p>\n\n<p>In particular, we first created a combinator <code class=\"language-plaintext highlighter-rouge\">orNull()</code> that given an <code class=\"language-plaintext highlighter-rouge\">Arb&lt;A&gt;</code> (where <code class=\"language-plaintext highlighter-rouge\">A</code> is not nullable) returns an <code class=\"language-plaintext highlighter-rouge\">Arb&lt;A?&gt;</code>. Then we saw how to create an <code class=\"language-plaintext highlighter-rouge\">Arb</code> of pairs of types given a pair of <code class=\"language-plaintext highlighter-rouge\">Arb</code>s of (possibly) different types and generalized the idea to any arity. Finally we saw how to <code class=\"language-plaintext highlighter-rouge\">map</code> over <code class=\"language-plaintext highlighter-rouge\">Arb</code> instances to get an <code class=\"language-plaintext highlighter-rouge\">Arb</code> that returns the result of applying a function to the result of the original <code class=\"language-plaintext highlighter-rouge\">Arb</code>.</p>\n\n<p>You can see the current version of our library at <a href=\"https://github.com/agile-jordi/wapbtl/tree/part2\">https://github.com/agile-jordi/wapbtl/tree/part2</a>.</p>\n\n<h2 id=\"all-articles-in-the-series\">All articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-10-04-writing-a-pbt-ibrary-1.html\">Writing a property based testing library, part 1</a></li>\n  <li><a href=\"./2022-10-14-writing-a-pbt-ibrary-2.html\">Writing a property based testing library, part 2</a></li>\n  <li><a href=\"./2022-10-25-writing-a-pbt-ibrary-3.html\">Writing a property based testing library, part 3</a></li>\n  <li><a href=\"./2024-01-12-writing-a-pbt-library-4-housekeeping.html\">Writing a property based testing library, part 4</a></li>\n</ol>\n\n",
            "url": "https://blog.agilogy.com/2022-10-14-writing-a-pbt-ibrary-2.html",
            "date_published": "2022-10-14T00:00:00+02:00",
            "date_modified": "2022-10-14T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-10-04-writing-a-pbt-ibrary-1.html",
            "title": "Writing a Property Based Testing library in Kotlin, a Journey (part 1)",
            "content_text": "I feel like doing that: writing a property based testing library. I’ve been blogging about property based testing in the past few weeks. In particular, about value shrinking. You can find the articles here and here. The idea was to talk about the general concept but still show it in real(ish) code. At the same time, I wanted to avoid talking specifically about Kotest, Scalatest or any other library. Not because they are’nt amazing (they indeed are) but because they may be daunting and full-featured, which could be distracting to the purposes of my intent.\n\nBut now I’m in the mood for writing an actual property based testing library. Not one you will use in real projects, but one I can use to learn (and hopefully show, explain or teach) something about property based testing. Furthermore through my experience with those libraries, I’ve seen things I’d like to improve. Why not try my best at it?\n\n\n\nSo… let’s do this! Let’s write a property based testing library from scracth, in Kotlin, and tell the world about what I learn in the way…\n\nYou may already know about property based testing and maybe even used it. You may as well have read my previous blog posts about shrinking. Or property based testing may be a new concept to you. I hope whatever your situation is, this will be an interesting read, as we dive into such an amazing exercise.\n\nProperty based testing: an introduction\n\nI’m not goint to lie here. There are plenty of good introductory articles to property based testing, I’m in a hurry, I’m lazy and I don’t want to write a lengthy explanation. So let’s go direct to the point.\n\nOur statement will be: We want to generate hundreds or thousands of random tests cases automatically with which to test our software instead of testing using hardcoded examples. Whenever our library finds a test case that fails, we want it to search for the simplest test case that still fails, and provide a clear, concise error message about what failed.\n\nEasy peasy. So, if you are testing a nice sum(a:Int, b:Int): Int function,  instead of writing a test like…\n\nval a = 5\nval b = 9\nassertEquals(14, sum(a, b))\n\n\nYou’d write something like I know, I know… Bear with me and this ugly design. I just try to avoid spoiling the nice design we’ll use just a couple of paragraphs below…:\n\ntestManyTimes {\n  val a = someRandomInt()\n  val b = someRandomInt()\n  assertEquals(`???`, sum(a, b))\n}\n\n\nBut what value do we use for ??? Why not assertEquals(a + b, sum(a, b)? -  you may say… Well, because that would mean, basically duplicating the implementation of the function under test in your test code. Which would have the classical DRY violations flaws and, worst of all, it would only test that 2 probably buggy implementations behave the same way.?\n\nWhen you use random data for test inputs and initial states, you get results that you can’t foresee. Therefore, you can’t write a test that expects a particular result (or end state). The assertions you need to do depend on the test data randomly generated. We say you are checking properties.\n\nHere you have an example of one such property:\n\n\n  For any integer number i, sum(i, 0) = i\n\n\nLet’s code!\n\nHow would we code a simple property like the one above? Clearly not with the testManyTimes and someRandomInt names I used above. We need:\n\n\n  A value that represents “any integer number”. We’ll call it randomInt.\n  A function that given such value returns wether it satisfies the desired property or not\n\n\nSo let’s go with this naming:\n\nforAny(randomInt){ i -&gt; sum(i, 0) == i }\n\n\nWe could define one such function like this I’m assuming a certain degree of imperative programming here: The function forAny will throw if there is a test failure. We could of course have it return a result functionally, but I prefer to keep things more familiar to more people.:\n\nfun forAny(r: RandomInt, property: (Int) -&gt; Boolean): Unit\n\n\nI don’t know about you, but this is asking me to generalize to other types than Int:\n\nfun &lt;A&gt; forAny(r: Random&lt;A&gt;, property: (A) -&gt; Boolean): Unit\n\n\nUnfortunately, Random is the name of a class in kotlin.random that is used to… generate random numbers. I’d prefer to use a different name. The usual name for such a thing in property based testing is Arbitrary or Arb, for short. So, let’s do some renaming:\n\nfun &lt;A&gt; forAny(a: Arb&lt;A&gt;, property: (A) -&gt; Boolean): Unit\n\n\nLet’s try to implement this forAny function. We want to test, let’s say, 100 test cases generated by Arb:\n\nfun &lt;A&gt; forAny(a: Arb&lt;A&gt;, property: (A) -&gt; Boolean) {\n    (1..100).forEach { attemptNumber -&gt;\n        val sample = a.generate()\n        if (!property(sample)) \n          throw PropertyFailedException(attemptNumber,sample)\n    }\n}\n\n\nSo, we found out we need Arb&lt;A&gt; to implement  generate() I added a companion object so that we can later add extension functions and values to it, see below.:\n\ninterface Arb&lt;A&gt; {\n    fun generate(): A\n    companion object\n}\n\n\nThere are, of course, several important limitationsSome examples of such limitations: We would like to be able to provide a seed that makes our random values reproducible, we’d like to have better error messages, we’d like to be able to configure how many iterations we want on each property we check, we will want the library to simplify test cases that fail to provide the simplest value that still fails, etc. in this implementation, but we want to start with something we can run as soon as possible and iterate from there.\n\nGenerating arbitrary integers\n\nSo, to check our initial property, forAny(arbInt){ i -&gt; sum(i, 0) == i }, we need an Arb&lt;Int&gt;, a generator of arbitrary Int values. If you know a bit about the Kotlin (or Java) way of generating random values it is not complicated. To make it easier to find using our IDE/editor auto-complete, we will add this Arb value as an extension to Arb companion object:\n\nval Arb.Companion.int get() = object: Arb&lt;Int&gt;{\n    override fun generate(): Int = kotlin.random.Random.nextInt()\n}\n\n\nFinally checking some properties!\n\nNow, everything is in place to actually testWe are using kotlin.test here, but any testing library/framework can work with our library, as it only needs to mark a test failed when a PropertyFailedException is thrown. some properties on Ints:\n\n@Test\nfun testSum0() = forAny(Arb.int) { i -&gt; sum(i, 0) == i }\n\n\n✅ Green!\n\nWhat about finding a test case that fails? We’ll use a property that is not true for the sake of demonstration purposes, but that would be what you would get if you were testing a property of your system and found a bug:\n\n@Test\nfun testDoubleIsGreater() = forAny(Arb.int) { i -&gt; sum(i, i) &gt;= i }\n\n\n🔴 Property failed at attempt 3 with sample 2018188761\n\ncom.agilogy.wapbtl.PropertyFailedException: Property failed at attempt 3 with sample 2018188761\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny(forAny.kt:12)\n\tat app//com.agilogy.wapbtl.ForAnyIntTest.testDoubleIsGreater(ForAnyIntTest.kt:14)\n\tat java.base@11.0.13/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\n\nTesting a testing library\n\nSo far so good… But, hey, I just realized I write automated tests for everything I develop. A property based testing library will be no exeption. So, I’d like to write a test about how a failed property check throws an exception:\n\n@Test\nfun testDoubleIsGreater() =\n  assertFailsWith&lt;PropertyFailedException&gt; {  \n    forAny(Arb.int) { i -&gt; sum(i, i) &gt;= i } \n  }\n\n\nBut this seems not enough… Not any PropertyFailedException is ok. At least, we would like to check that the sampleUnfortunately, Kotlin does not allow us to define a parameterized class that extends Exception and, therefore, the sample in our PropertyFailedException is of type Any?. That’s the reason for that ugly cast in the code below. we get returned effectively fails our property check. As I’ll be using the property { i -&gt; i + i &gt;= i } twice, I extracted a value for it:\n\n@Test\nfun testDoubleIsGreater() {\n    val property: (Int) -&gt; Boolean =  { i -&gt; sum(i, i) &gt;= i }\n    val failure = assertFailsWith&lt;PropertyFailedException&gt; {\n        forAny(Arb.int, property)\n    }\n    val failedSample = failure.sample as Int\n    assertFalse { property(failedSample) }\n}\n\n\nConclusion\n\nSo we created a minimalist property based testing library that is capable of testing properties of Int values. We implemented it in under 30 lines of code (without relying to magic one-liners). I hope this dissipates some magic feeling arround property based testing.\n\nOn top of that, we started writing tests of our property based testing library. I have the intuition that testing a library that generates random values will soon get quite complicated. But, hey, if it were easy it wouldn’t be fun!\n\nAt the same time, we uncovered several limitations of our property testing function. And we are only capable, so far, of testing properties on Int values.\n\nYou can see the current version of our library at https://github.com/agile-jordi/wapbtl/tree/part1.\n\nWill our intrepid developers overcome such limitations? Stay tuned!\n\n\n\nAll articles in the series\n\n\n  Writing a property based testing library, part 1\n  Writing a property based testing library, part 2\n  Writing a property based testing library, part 3\n  Writing a property based testing library, part 4\n\n",
            "content_html": "<p>I feel like doing that: writing a property based testing library. I’ve been blogging about property based testing in the past few weeks. In particular, about value shrinking. You can find the articles <a href=\"./2022-08-26-pbt-shrinking-part1.html\">here</a> and <a href=\"./2022-09-13-pbt-shrinking-part2.html\">here</a>. The idea was to talk about the general concept but still show it in real(ish) code. At the same time, I wanted to avoid talking specifically about <a href=\"https://kotest.io/\">Kotest</a>, <a href=\"https://www.scalatest.org/\">Scalatest</a> or any other library. Not because they are’nt amazing (they indeed are) but because they may be daunting and full-featured, which could be distracting to the purposes of my intent.</p>\n\n<p>But now I’m in the mood for writing an actual property based testing library. Not one you will use in real projects, but one I can use to learn (and hopefully show, explain or teach) something about property based testing. Furthermore through my experience with those libraries, I’ve seen things I’d like to improve. Why not try my best at it?</p>\n\n<p><img src=\"../assets/img/letsDoThis.gif\" alt=\"Let's do this!\" class=\"figcaption\" /></p>\n\n<p>So… let’s do this! Let’s write a property based testing library from scracth, in Kotlin, and tell the world about what I learn in the way…</p>\n\n<p>You may already know about property based testing and maybe even used it. You may as well have read my previous blog posts about shrinking. Or property based testing may be a new concept to you. I hope whatever your situation is, this will be an interesting read, as we dive into such an amazing exercise.</p>\n\n<h2 id=\"property-based-testing-an-introduction\">Property based testing: an introduction</h2>\n\n<p>I’m not goint to lie here. There are plenty of good introductory articles to property based testing, I’m in a hurry, I’m lazy and I don’t want to write a lengthy explanation. So let’s go direct to the point.</p>\n\n<p>Our statement will be: We want to generate hundreds or thousands of random tests cases automatically with which to test our software instead of testing using hardcoded examples. Whenever our library finds a test case that fails, we want it to search for the simplest test case that still fails, and provide a clear, concise error message about what failed.</p>\n\n<p>Easy peasy. So, if you are testing a nice <code class=\"language-plaintext highlighter-rouge\">sum(a:Int, b:Int): Int</code> function,  instead of writing a test like…</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">a</span> <span class=\"p\">=</span> <span class=\"mi\">5</span>\n<span class=\"kd\">val</span> <span class=\"py\">b</span> <span class=\"p\">=</span> <span class=\"mi\">9</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">14</span><span class=\"p\">,</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">))</span>\n</code></pre></div></div>\n\n<p>You’d write something <em class=\"sidenote-number\">like</em> <em class=\"sidenote\">I know, I know… Bear with me and this ugly design. I just try to avoid spoiling the nice design we’ll use just a couple of paragraphs below…</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">testManyTimes</span> <span class=\"p\">{</span>\n  <span class=\"kd\">val</span> <span class=\"py\">a</span> <span class=\"p\">=</span> <span class=\"nf\">someRandomInt</span><span class=\"p\">()</span>\n  <span class=\"kd\">val</span> <span class=\"py\">b</span> <span class=\"p\">=</span> <span class=\"nf\">someRandomInt</span><span class=\"p\">()</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"err\">`</span><span class=\"p\">???</span><span class=\"err\">`</span><span class=\"p\">,</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">))</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But what value do we use for <code class=\"language-plaintext sidenote-number highlighter-rouge\">???</code> <em class=\"sidenote\">Why not <code class=\"language-plaintext highlighter-rouge\">assertEquals(a + b, sum(a, b)</code>? -  you may say… Well, because that would mean, basically duplicating the implementation of the function under test in your test code. Which would have the classical DRY violations flaws and, worst of all, it would only test that 2 probably buggy implementations behave the same way.</em>?</p>\n\n<p>When you use random data for test inputs and initial states, you get results that you can’t foresee. Therefore, you can’t write a test that expects a particular result (<a href=\"./2022-06-17-testing-and-persistent-state.html\">or end state</a>). The assertions you need to do depend on the test data randomly generated. We say you are checking properties.</p>\n\n<p>Here you have an example of one such property:</p>\n\n<blockquote>\n  <p>For any integer number i, sum(i, 0) = i</p>\n</blockquote>\n\n<h2 id=\"lets-code\">Let’s code!</h2>\n\n<p>How would we code a simple property like the one above? Clearly not with the <code class=\"language-plaintext highlighter-rouge\">testManyTimes</code> and <code class=\"language-plaintext highlighter-rouge\">someRandomInt</code> names I used above. We need:</p>\n\n<ul>\n  <li>A value that represents “any integer number”. We’ll call it <code class=\"language-plaintext highlighter-rouge\">randomInt</code>.</li>\n  <li>A function that given such value returns wether it satisfies the desired property or not</li>\n</ul>\n\n<p>So let’s go with this naming:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">randomInt</span><span class=\"p\">){</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"p\">==</span> <span class=\"n\">i</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>We could define one such function like <em class=\"sidenote-number\">this</em> <em class=\"sidenote\">I’m assuming a certain degree of imperative programming here: The function forAny will throw if there is a test failure. We could of course have it return a result functionally, but I prefer to keep things more familiar to more people.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"nc\">RandomInt</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">):</span> <span class=\"nc\">Unit</span>\n</code></pre></div></div>\n\n<p>I don’t know about you, but this is asking me to generalize to other types than <code class=\"language-plaintext highlighter-rouge\">Int</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">r</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">):</span> <span class=\"nc\">Unit</span>\n</code></pre></div></div>\n\n<p>Unfortunately, <code class=\"language-plaintext highlighter-rouge\">Random</code> is the name of a class in <code class=\"language-plaintext highlighter-rouge\">kotlin.random</code> that is used to… generate random numbers. I’d prefer to use a different name. The usual name for such a thing in property based testing is <code class=\"language-plaintext highlighter-rouge\">Arbitrary</code> or <code class=\"language-plaintext highlighter-rouge\">Arb</code>, for short. So, let’s do some renaming:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">):</span> <span class=\"nc\">Unit</span>\n</code></pre></div></div>\n\n<p>Let’s try to implement this <code class=\"language-plaintext highlighter-rouge\">forAny</code> function. We want to test, let’s say, 100 test cases generated by <code class=\"language-plaintext highlighter-rouge\">Arb</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;,</span> <span class=\"n\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"o\">..</span><span class=\"mi\">100</span><span class=\"p\">).</span><span class=\"nf\">forEach</span> <span class=\"p\">{</span> <span class=\"n\">attemptNumber</span> <span class=\"p\">-&gt;</span>\n        <span class=\"kd\">val</span> <span class=\"py\">sample</span> <span class=\"p\">=</span> <span class=\"n\">a</span><span class=\"p\">.</span><span class=\"nf\">generate</span><span class=\"p\">()</span>\n        <span class=\"k\">if</span> <span class=\"p\">(!</span><span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">sample</span><span class=\"p\">))</span> \n          <span class=\"k\">throw</span> <span class=\"nc\">PropertyFailedException</span><span class=\"p\">(</span><span class=\"n\">attemptNumber</span><span class=\"p\">,</span><span class=\"n\">sample</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>So, we found out we need <code class=\"language-plaintext highlighter-rouge\">Arb&lt;A&gt;</code> to implement  <code class=\"language-plaintext sidenote-number highlighter-rouge\">generate()</code> <em class=\"sidenote\">I added a companion object so that we can later add extension functions and values to it, see below.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">A</span>\n    <span class=\"k\">companion</span> <span class=\"k\">object</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>There are, of course, several important <em class=\"sidenote-number\">limitations</em><em class=\"sidenote\">Some examples of such limitations: We would like to be able to provide a seed that makes our random values reproducible, we’d like to have better error messages, we’d like to be able to configure how many iterations we want on each property we check, we will want the library to <a href=\"./2022-08-26-pbt-shrinking-part1.html\">simplify test cases that fail to provide the simplest value that still fails</a>, etc.</em> in this implementation, but we want to start with something we can run as soon as possible and iterate from there.</p>\n\n<h2 id=\"generating-arbitrary-integers\">Generating arbitrary integers</h2>\n\n<p>So, to check our initial property, <code class=\"language-plaintext highlighter-rouge\">forAny(arbInt){ i -&gt; sum(i, 0) == i }</code>, we need an <code class=\"language-plaintext highlighter-rouge\">Arb&lt;Int&gt;</code>, a generator of arbitrary <code class=\"language-plaintext highlighter-rouge\">Int</code> values. If you know a bit about the Kotlin (or Java) way of generating random values it is not complicated. To make it easier to find using our IDE/editor auto-complete, we will add this <code class=\"language-plaintext highlighter-rouge\">Arb</code> value as an extension to <code class=\"language-plaintext highlighter-rouge\">Arb</code> companion object:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">Arb</span><span class=\"p\">.</span><span class=\"nc\">Companion</span><span class=\"p\">.</span><span class=\"n\">int</span> <span class=\"k\">get</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"k\">object</span><span class=\"p\">:</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;{</span>\n    <span class=\"k\">override</span> <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">():</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"n\">kotlin</span><span class=\"p\">.</span><span class=\"n\">random</span><span class=\"p\">.</span><span class=\"nc\">Random</span><span class=\"p\">.</span><span class=\"nf\">nextInt</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"finally-checking-some-properties\">Finally checking some properties!</h2>\n\n<p>Now, everything is in place to actually <em class=\"sidenote-number\">test</em><em class=\"sidenote\">We are using <code class=\"language-plaintext highlighter-rouge\">kotlin.test</code> here, but any testing library/framework can work with our library, as it only needs to mark a test failed when a <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> is thrown.</em> some properties on <code class=\"language-plaintext highlighter-rouge\">Int</code>s:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testSum0</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"p\">==</span> <span class=\"n\">i</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>✅ Green!</p>\n\n<p>What about finding a test case that fails? We’ll use a property that is not true for the sake of demonstration purposes, but that would be what you would get if you were testing a property of your system and found a bug:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testDoubleIsGreater</span><span class=\"p\">()</span> <span class=\"p\">=</span> <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"p\">&gt;=</span> <span class=\"n\">i</span> <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>🔴 Property failed at attempt 3 with sample 2018188761</p>\n\n<div class=\"language-console highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"go\">com.agilogy.wapbtl.PropertyFailedException: Property failed at attempt 3 with sample 2018188761\n\tat app//com.agilogy.wapbtl.ForAnyKt.forAny(forAny.kt:12)\n\tat app//com.agilogy.wapbtl.ForAnyIntTest.testDoubleIsGreater(ForAnyIntTest.kt:14)\n\tat java.base@11.0.13/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n</span></code></pre></div></div>\n\n<h2 id=\"testing-a-testing-library\">Testing a testing library</h2>\n\n<p>So far so good… But, hey, I just realized I write automated tests for everything I develop. A property based testing library will be no exeption. So, I’d like to write a test about how a failed property check throws an exception:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testDoubleIsGreater</span><span class=\"p\">()</span> <span class=\"p\">=</span>\n  <span class=\"n\">assertFailsWith</span><span class=\"p\">&lt;</span><span class=\"nc\">PropertyFailedException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>  \n    <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"p\">&gt;=</span> <span class=\"n\">i</span> <span class=\"p\">}</span> \n  <span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But this seems not enough… Not any <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> is ok. At least, we would like to check that <em class=\"sidenote-number\">the sample</em><em class=\"sidenote\">Unfortunately, Kotlin does not allow us to define a parameterized class that extends <code class=\"language-plaintext highlighter-rouge\">Exception</code> and, therefore, the <code class=\"language-plaintext highlighter-rouge\">sample</code> in our <code class=\"language-plaintext highlighter-rouge\">PropertyFailedException</code> is of type <code class=\"language-plaintext highlighter-rouge\">Any?</code>. That’s the reason for that ugly cast in the code below.</em> we get returned effectively fails our property check. As I’ll be using the property <code class=\"language-plaintext highlighter-rouge\">{ i -&gt; i + i &gt;= i }</code> twice, I extracted a value for it:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testDoubleIsGreater</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kd\">val</span> <span class=\"py\">property</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">Int</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">Boolean</span> <span class=\"p\">=</span>  <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">)</span> <span class=\"p\">&gt;=</span> <span class=\"n\">i</span> <span class=\"p\">}</span>\n    <span class=\"kd\">val</span> <span class=\"py\">failure</span> <span class=\"p\">=</span> <span class=\"n\">assertFailsWith</span><span class=\"p\">&lt;</span><span class=\"nc\">PropertyFailedException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nf\">forAny</span><span class=\"p\">(</span><span class=\"nc\">Arb</span><span class=\"p\">.</span><span class=\"n\">int</span><span class=\"p\">,</span> <span class=\"n\">property</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n    <span class=\"kd\">val</span> <span class=\"py\">failedSample</span> <span class=\"p\">=</span> <span class=\"n\">failure</span><span class=\"p\">.</span><span class=\"n\">sample</span> <span class=\"k\">as</span> <span class=\"nc\">Int</span>\n    <span class=\"nf\">assertFalse</span> <span class=\"p\">{</span> <span class=\"nf\">property</span><span class=\"p\">(</span><span class=\"n\">failedSample</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"conclusion\">Conclusion</h2>\n\n<p>So we created a minimalist property based testing library that is capable of testing properties of <code class=\"language-plaintext highlighter-rouge\">Int</code> values. We implemented it in under 30 lines of code (without relying to magic one-liners). I hope this dissipates some magic feeling arround property based testing.</p>\n\n<p>On top of that, we started writing tests of our property based testing library. I have the intuition that testing a library that generates random values will soon get quite complicated. But, hey, if it were easy it wouldn’t be fun!</p>\n\n<p>At the same time, we uncovered several limitations of our property testing function. And we are only capable, so far, of testing properties on Int values.</p>\n\n<p>You can see the current version of our library at <a href=\"https://github.com/agile-jordi/wapbtl/tree/part1\">https://github.com/agile-jordi/wapbtl/tree/part1</a>.</p>\n\n<p>Will our intrepid developers overcome such limitations? Stay tuned!</p>\n\n<p><img src=\"../assets/img/same-bat-channel.png\" alt=\"Batman Robin GIF - Batman Robin Old School - Descubre &amp; Comparte GIFs\" /></p>\n\n<h2 id=\"all-articles-in-the-series\">All articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-10-04-writing-a-pbt-ibrary-1.html\">Writing a property based testing library, part 1</a></li>\n  <li><a href=\"./2022-10-14-writing-a-pbt-ibrary-2.html\">Writing a property based testing library, part 2</a></li>\n  <li><a href=\"./2022-10-25-writing-a-pbt-ibrary-3.html\">Writing a property based testing library, part 3</a></li>\n  <li><a href=\"./2024-01-12-writing-a-pbt-library-4-housekeeping.html\">Writing a property based testing library, part 4</a></li>\n</ol>\n",
            "url": "https://blog.agilogy.com/2022-10-04-writing-a-pbt-ibrary-1.html",
            "date_published": "2022-10-04T00:00:00+02:00",
            "date_modified": "2022-10-04T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-09-13-pbt-shrinking-part2.html",
            "title": "Property based testing: Shrinking (part 2) - Shrinking functions",
            "content_text": "In our previous blog post on shrinking we saw that we want to find  the simplest failing example we can in a shrinking tree. We had an initial example that failed our tests:\n\nItemSearchCriteria(\n  ItemFilter(23, 110, 2022-01-01T00:00:00.000, setOf(Tag.clothes)),\n  AgetItemOrder\n)\n\n\nTo try to find simpler examples that may still be good examples of how our system fails, we decided to simplify the initial example, to shrink it. To do so, we started by removing filters one by one. With this strategy we got a list of simplifications we could try and further simplify if we wanted.\n\nToday we’ll try to discuss how this intuititive idea of shrinking can be automated.\n\nShrinking functions\n\nLet’s say our PBT library encodes generators of values of type A as an interface Arb&lt;A&gt;. In our example above, we would have a Arb&lt;ItemSearchCriteria&gt;. Such an interface would be something like:\n\ninterface Arb&lt;A&gt;{\n  fun generate(random: Random): A\n}\n\n\nIntuitively we would like to also have Shrinkers, that we could define as a separate interface or as part of the Arb interface. In any case, they would provide a function that given a value of type A returns the list of possible first level shrinks:\n\nfun shrinks(value: A): List&lt;A&gt;\n\n\nThe type of such a function would be:\n\ntype ShrinkFunction&lt;A&gt; = (A) -&gt; List&lt;A&gt;\n\n\nA shrinking function takes the value you want to shrink and returns a list of one-step shrinks from that value.\n\nThe shrink function must return a list of values because there may be multiple different ways of shrinking the same value. In our example, when simplifying ItemFilter we could remove minWeightInKgs, maxWeightInKgs, olderThan or hasAllTags and each one gives us a different value..\n\nOn the other hand, it is important that the shrink function only returns different ways of slightly shrink a value, since the shrinking tree will be built by recursively applying the shrink function to a shrinks of the list when needed. In our example, when simplifying ItemFilter we don’t need to remove combinations of more than one filter (like removing both minWeightInKgs and maxWeightInKgs) as that example will be obtained by further simplifying an example where we first removed just one filter.\n\nShrinking simple types\n\nGiven such a definition, the PBT library can define shrink functions for some ubiquitous simple types like Int or  Instant Unrelated: Because you know and use Instant, right? You know DateTime does not correctly represent when something happened but else what did the clocks somewhere in the world display when that happened, right?.\n\nAn example naive implementation of Int shrinking may be:\n\nfun intShrinks(value: Int): List&lt;Int&gt; =\n    if (value == 0) emptyList()\n    else if (value &lt; 0) intShrinks(-value).map { -it }\n    else listOfNotNull(\n        if (value &gt;= 20) sqrt(value.toDouble()).toInt() else null,\n        if (value &gt;= 10) value / 2 else null,\n        if (value &lt; 20) (value - 1) else null\n    )\n\n\nThe value 110 would produce the following shrinking tree Note this is a different shrinking function than the one I used in the previous post. If you noticed, sorry about that… and I’m frankly impressed you did.:\n\ngraph LR\n  110 --&gt; 10 --&gt; 5\n  10 --&gt; 9 --&gt; 8 --&gt; 7 --&gt; 6 --&gt; 5 --&gt; 4 --&gt; 3 --&gt; 2 --&gt; 1 --&gt; 0\n  110 --&gt; 55 --&gt; 7\n  55 --&gt; 27 --&gt; 5\n  27 --&gt; 13 --&gt; 6\n\n\nWe can go as far as we want here. Depending on your use case, you could also simply rule that the only shrink of an Int value you want to try is 0, simplifying things. But most of the time you can rely on the shrinking function provided by your PBT library and call it a day.\n\nShrinking nullable types\n\nTrying to generalize generic shrinks seems also easy for nullable types:\n\nfun &lt;A&gt; shrinks(value: A?): List&lt;A?&gt; = listOf(null)\n\n\nBut, “Wait a minute!” - you say. - “Then, the shrinks for 55 of type Int are listOf(7,27) but the shrinks for 55 of type Int? are just listOf(null)?”. And you are right, we are loosing the nice shrink function we already have for a type and not applying it to the nullable version of it. So let’s try to generalize that to a type that already has a shrinking function:\n\nfun &lt;A&gt; nullableShrinks(value: A?, notNullShrinks: (A) -&gt; List&lt;A&gt;): List&lt;A?&gt; = \n  if (value == null) emptyList() \n  else listOf(null) + notNullShrinks(value)\n\nfun nullableIntShrinks(value: Int?) = nullableShrinks(value, ::intShrinks)\n\n\nThat is, you can shrink the nullable value to null or either try to shrink it as you would if it weren’t nullable.\n\nDivertimento: Playing with functions\n\nNow that I already introduced a high order function (nullableShrinks is a function that takes a function as a parameter) allow me to dig deeper. I can’t help but do some functional programming here. You can skip this section if you are already tired of me selling this drug:\n\nFirst let’s redefine nullableShrinks to not only take a function as a parameter but to also return one. The idea is that it only takes the not null shrinking function (without the value to shrink) and it returns the shrinking function:\n\nfun &lt;A&gt; nullableShrinks(notNullShrinks: (A) -&gt; List&lt;A&gt;): &lt;A&gt; -&gt; List&lt;A?&gt; = { a -&gt;\n  if (a == null) emptyList() else listOf(null) + notNullShrinks(a)\n}\nval nullableIntShrinks: (Int?) -&gt; List&lt;Int?&gt; = nullableShrinks(::intShrink)\n\n\nOh! I forgot our nice type alias:\n\nfun &lt;A&gt; nullableShrinks(notNullShrinks: ShrinkFunction&lt;A&gt;):\n  ShrinkFunction&lt;A?&gt; = { a -&gt;\n  if (a == null) emptyList() else listOf(null) + notNullShrinks(a)\n}\nval nullableIntShrinks: ShrinkFunction&lt;Int?&gt; = nullableShrinks(::intShrink)\n\n\nFurthermore, if you like Kotlin function receivers as much as I like them, you can define and use such shrink function as:\n\nfun &lt;A&gt; ShrinkFunction&lt;A&gt;.nullable(): ShrinkFunction&lt;A?&gt; = { a -&gt;\n  if (a == null) emptyList() else listOf(null) + this(a)\n}\nval nullableIntShrinks = ::intShrink.nullable()\nval nullableInstantShrinks = ::instantShrink.nullable()\n\n\nUser provided shrink functions\n\nAnd now, we can imagine ourselves, users of the PBT library, implementing shrink functions for our types:\n\nval itemFilterShrinks: ShrinkFunction&lt;ItemFilter&gt; = { value -&gt;\n    listOf(\n      value.copy(minWeightInKgs = null),\n      value.copy(maxWeightInKgs = null),\n      value.copy(olderThan = null),\n      value.copy(hasAllTags = emptySet())\n    )\n}\n\n\nBut why not use the nice nullableIntShrink we just defined, instead of just trying minWeightInKgs=null? In fact, for each parameter we could try all the shrink values its shrink function provides. Assuming we also have an instantShrinks, we could do something like:\n\nval itemFilterShrinks: ShrinkFunction&lt;ItemFilter&gt; = { value -&gt;\n    // Either shrink minWeightInKg\n    ::intShrinks.nullable(value.minWeightInKgs).map { i -&gt; \n      value.copy(minWeightInKgs = i) \n    } + // or maxWeightInKg...\n    ::intShrinks.nullable(value.maxWeightInKgs).map { i -&gt; \n      value.copy(maxWeightInKgs = i) \n    } + // or olderThan...\n    instantShrink.nullable(value.olderThan).map { i -&gt;\n      value.copy(olderThan = i) \n    } + // or hasAllTags...\n    listOf(value.copy(hasAllTags = emptySet()))\n}\n\n\nOne way to understand this shrinking function is:\n\n\n  There are 4 options, the 4 fields you may shrink. We don’t care about combinations of fields, as once shrinked a field, a subtree will try to shrink other fields not yet shrinked.\n  In the option of every field (e.g. minWeightInKg) there are as many possible shrinks as the field type shrinking function provides (e.g. nullableIntShrink(value.minWeightInKgs) for the minWeightInKgs field value).\n\n\nThe problems with user provided shrink functions\n\nOk, we got this far. Nice! We can build shrink functions for all the types we use as test inputs. Isn’t that a large amount of types? That probably is a large amount of types. Isn’t it tedious? It is probably tedious. Is it error prone? It is indeed very error prone!\n\nLet’s look at these 2 problems in isolation:\n\nBugs in our bug hunting toolset\n\n\n\nLearn from the incredible shrinking man: A bug while playing with shrinking is much more dangerous!\n\nThe user provided shrink functions are… functions, indeed. And they are code. And code has bugs. But these are an insidious type of bugs, as they only show when you are already trying to understand and fix a failing test that may be as well a bug. Yikes! So, in your happy path, you won’t be running your shrink functions (neither in production nor in tests). They will run only when you have some test failure.\n\nWhen I’ve found a bug in one of our shrink functions, it usually goes like this:\n\n\n  I get a PBT test failure and the example causing the failure is complex but the shrinking function does not work, so I get another complex example.\n  I groan. Oh no! Not now!\n  I try to get by without shrinking and try to understand the complex example that fails my test.\n  If I do not despair:\n    \n      4.1. I fix whatever the test or the production code causing my original test failure\n      4.2. I miserably fail to have the discipline to fix the shrink function.\n      4.3. Goto 1.\n    \n  \n  If I despair:\n    \n      5.1. I try to fix my shrinking function while my head is thinking about the actual test failure I try to fix.\n      5.2. I finally manage to focus on fixing shrinking.\n      5.3. Now I need to switch contexts again: Hopefully I have a seed and I can rerun my original failing test with the new shrink function and get a shrunk example I can use to fix whatever failed.\n    \n  \n\n\nSolving the buggy shrinkers problem\n\nSo, I know, I don’t like bugs and I’m complaining like that was your fault. But, “hey, Jordi!” - you say - “good programmers write tests”. And tests I write, indeed. But I want my shrinks to properly shrink whatever input I provide, and I’m not in the mood to be just writing examples and the shrinking I expect of them.\n\nI’m leaving the mystery about how we test our shrinkers for a different post. Suffice to say that it is not easy. And, in case you want one spoiler, we don’t test in isolation but integrated in the PBT library, that applies them repeatedly in search for the simplest example.\n\nRepetition, repetition, repetition\n\nLet’s think about our original example. In fact we wanted to simplify a value of type ItemSearchCriteria:\n\ndata class ItemSearchCriteria(val filter: ItemFilter, val order: ItemOrder)\n\n\nSo we need a shrink function for it too. But the strategy is exactly the same:\n\n\n  There are as many options as fields our data class has (2 for ItemSearchCriteria, 4 for ItemFilter). We don’t care about combination of fields.\n  In the option of every field (e.g. filter for ItemSearchCriteria or minWeightInKg for ItemFilter), there are as many possible shrinks as the field type shrinking function provides.\n\n\nSo, assuming we also defined itemOrderShrinks:\n\nval itemSearchCriteriaShrinks: ShrinkFunction&lt;ItemSearchCriteria&gt; = { value -&gt;\n    // Either shrink filter\n    itemFilterShrinks(value.filter).map { f -&gt; \n      value.copy(filter = f) \n    } + // or order...\n    itemOrderShrinks(value.order).map { o -&gt; \n      value.copy(order = o) \n    }\n}\n\n\nWhat a repetition, huh? If only we could generalize that and automate it…\n\nAutomatic shrinking function derivation\n\nOur shrinking functions heaven would be to automatically derive the shrinking functions our types need. For that we need a generic algorithm that is capable of returning a shrinking function for a given type (spoiler, it will take other shrinking functions as inputs). On top of that, some black magic may prove useful; something that, given the type we want to shrink (e.g. ItemSearchCriteria) automatically invokes such function and returns the shrink function. That could be based on introspection, macros… But my doctor says I’m not allowed to use black magic while programming; I seem to be allergic. So I prefer to compose generators using monads and have the shrinking function derived for me, as I’ll show in the (hopefully near) future.\n\nConclusions\n\n\n  Jordi can’t explain shrinking in just 2 blog posts. He’ll need like… what, 4 of them? More? In my defense I must say it is not a problem of the written language. When I talk I tend to spend hours to explain anything I’m passionate about, as well. It could be related to my (not so great) knowledge of the English language; if that is the case I apologize, as I’m afraid I may be smarter in catalan or spanish.\n  Shrinking functions are promising… but this blog post leaves the reader with a sense of unsafety. Is all this effort worth it? Will we be able to use shrinking or even property based testing without spending lots of hours in doing so? Will the benefit overcome the costs? Many teams I worked with weren’t sure it wouldn’t pay off until they started using property based testing with a proper shrinking infrastructure… and they loved it. So, please, keep reading this series. I’ll try my best to keep writing them.\n  If you were expecting some more seriousness in the conclusions I’m sorry to disapoint you. I was in the mood for some more jokes. But please, do complain via Twitter.  After all, you went far enough to be reading the last few words of the article, so you deserve my apologies.\n\n\nAll the articles in the series\n\n\n  Property based testing: Shrinking (part 1)\n  Property based testing: Shrinking (part 2) - Shrinking functions\n\n",
            "content_html": "<p>In our <a href=\"2022-08-26-pbt-shrinking-part1.html\">previous blog post on shrinking</a> we saw that we want to find  the simplest failing example we can in a shrinking tree. We had an initial example that failed our tests:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span>\n  <span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span> <span class=\"mi\">110</span><span class=\"p\">,</span> <span class=\"mi\">2022</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"nc\">T00</span><span class=\"p\">:</span><span class=\"mi\">00</span><span class=\"p\">:</span><span class=\"mf\">00.000</span><span class=\"p\">,</span> <span class=\"nf\">setOf</span><span class=\"p\">(</span><span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">clothes</span><span class=\"p\">)),</span>\n  <span class=\"nc\">AgetItemOrder</span>\n<span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>To try to find simpler examples that may still be good examples of how our system fails, we decided to simplify the initial example, to <em>shrink</em> it. To do so, we started by removing filters one by one. With this strategy we got a list of simplifications we could try and further simplify if we wanted.</p>\n\n<p>Today we’ll try to discuss how this intuititive idea of shrinking can be automated.</p>\n\n<h2 id=\"shrinking-functions\">Shrinking functions</h2>\n\n<p>Let’s say our PBT library encodes generators of values of type <code class=\"language-plaintext highlighter-rouge\">A</code> as an interface <code class=\"language-plaintext highlighter-rouge\">Arb&lt;A&gt;</code>. In our example above, we would have a <code class=\"language-plaintext highlighter-rouge\">Arb&lt;ItemSearchCriteria&gt;</code>. Such an interface would be something like:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">interface</span> <span class=\"nc\">Arb</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;{</span>\n  <span class=\"k\">fun</span> <span class=\"nf\">generate</span><span class=\"p\">(</span><span class=\"n\">random</span><span class=\"p\">:</span> <span class=\"nc\">Random</span><span class=\"p\">):</span> <span class=\"nc\">A</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Intuitively we would like to also have Shrinkers, that we could define as a separate interface or as part of the <code class=\"language-plaintext highlighter-rouge\">Arb</code> interface. In any case, they would provide a function that given a value of type <code class=\"language-plaintext highlighter-rouge\">A</code> returns the list of possible first level shrinks:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">shrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nc\">A</span><span class=\"p\">):</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span>\n</code></pre></div></div>\n\n<p>The type of such a function would be:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"n\">type</span> <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span>\n</code></pre></div></div>\n\n<p>A shrinking function takes the value you want to shrink and returns a list of <strong><em>one-step</em></strong> shrinks from that value.</p>\n\n<p>The shrink function must return a list of values because there may be multiple different ways of shrinking the same value. In our example, when simplifying <code class=\"language-plaintext highlighter-rouge\">ItemFilter</code> we could remove <code class=\"language-plaintext highlighter-rouge\">minWeightInKgs</code>, <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code>, <code class=\"language-plaintext highlighter-rouge\">olderThan</code> or <code class=\"language-plaintext highlighter-rouge\">hasAllTags</code> and each one gives us a different value..</p>\n\n<p>On the other hand, it is important that the shrink function only returns different ways of slightly shrink a value, since the shrinking tree will be built by recursively applying the shrink function to a shrinks of the list when needed. In our example, when simplifying <code class=\"language-plaintext highlighter-rouge\">ItemFilter</code> we don’t need to remove combinations of more than one filter (like removing both <code class=\"language-plaintext highlighter-rouge\">minWeightInKgs</code> and <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code>) as that example will be obtained by further simplifying an example where we first removed just one filter.</p>\n\n<h2 id=\"shrinking-simple-types\">Shrinking simple types</h2>\n\n<p>Given such a definition, the PBT library can define shrink functions for some ubiquitous simple types like <code class=\"language-plaintext highlighter-rouge\">Int</code> or  <code class=\"language-plaintext sidenote-number highlighter-rouge\">Instant</code> <em class=\"sidenote\">Unrelated: Because you know and use <code class=\"language-plaintext highlighter-rouge\">Instant</code>, right? You know <code class=\"language-plaintext highlighter-rouge\">DateTime</code> does not correctly represent when something happened but else what did the clocks somewhere in the world display when that happened, right?</em>.</p>\n\n<p>An example naive implementation of <code class=\"language-plaintext highlighter-rouge\">Int</code> shrinking may be:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">intShrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">):</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">value</span> <span class=\"p\">==</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"nf\">emptyList</span><span class=\"p\">()</span>\n    <span class=\"k\">else</span> <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">value</span> <span class=\"p\">&lt;</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"nf\">intShrinks</span><span class=\"p\">(-</span><span class=\"n\">value</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"p\">-</span><span class=\"n\">it</span> <span class=\"p\">}</span>\n    <span class=\"k\">else</span> <span class=\"nf\">listOfNotNull</span><span class=\"p\">(</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">value</span> <span class=\"p\">&gt;=</span> <span class=\"mi\">20</span><span class=\"p\">)</span> <span class=\"nf\">sqrt</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">toDouble</span><span class=\"p\">()).</span><span class=\"nf\">toInt</span><span class=\"p\">()</span> <span class=\"k\">else</span> <span class=\"k\">null</span><span class=\"p\">,</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">value</span> <span class=\"p\">&gt;=</span> <span class=\"mi\">10</span><span class=\"p\">)</span> <span class=\"n\">value</span> <span class=\"p\">/</span> <span class=\"mi\">2</span> <span class=\"k\">else</span> <span class=\"k\">null</span><span class=\"p\">,</span>\n        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">value</span> <span class=\"p\">&lt;</span> <span class=\"mi\">20</span><span class=\"p\">)</span> <span class=\"p\">(</span><span class=\"n\">value</span> <span class=\"p\">-</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"k\">null</span>\n    <span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>The value <code class=\"language-plaintext highlighter-rouge\">110</code> would produce the following <em class=\"sidenote-number\">shrinking tree</em> <em class=\"sidenote\">Note this is a different shrinking function than the one I used in the previous post. If you noticed, sorry about that… and I’m frankly impressed you did.</em>:</p>\n\n<pre><code class=\"language-mermaid\">graph LR\n  110 --&gt; 10 --&gt; 5\n  10 --&gt; 9 --&gt; 8 --&gt; 7 --&gt; 6 --&gt; 5 --&gt; 4 --&gt; 3 --&gt; 2 --&gt; 1 --&gt; 0\n  110 --&gt; 55 --&gt; 7\n  55 --&gt; 27 --&gt; 5\n  27 --&gt; 13 --&gt; 6\n</code></pre>\n\n<p>We can go as far as we want here. Depending on your use case, you could also simply rule that the only shrink of an <code class=\"language-plaintext highlighter-rouge\">Int</code> value you want to try is <code class=\"language-plaintext highlighter-rouge\">0</code>, simplifying things. But most of the time you can rely on the shrinking function provided by your PBT library and call it a day.</p>\n\n<h2 id=\"shrinking-nullable-types\">Shrinking nullable types</h2>\n\n<p>Trying to generalize generic shrinks seems also easy for nullable types:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">shrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nc\">A</span><span class=\"p\">?):</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>But, “Wait a minute!” - you say. - “Then, the shrinks for <code class=\"language-plaintext highlighter-rouge\">55</code> of type <code class=\"language-plaintext highlighter-rouge\">Int</code> are <code class=\"language-plaintext highlighter-rouge\">listOf(7,27)</code> but the shrinks for 55 of type <code class=\"language-plaintext highlighter-rouge\">Int?</code> are just <code class=\"language-plaintext highlighter-rouge\">listOf(null)</code>?”. And you are right, we are loosing the nice shrink function we already have for a type and not applying it to the nullable version of it. So let’s try to generalize that to a type that already has a shrinking function:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">nullableShrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nc\">A</span><span class=\"p\">?,</span> <span class=\"n\">notNullShrinks</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;):</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> \n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">value</span> <span class=\"p\">==</span> <span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"nf\">emptyList</span><span class=\"p\">()</span> \n  <span class=\"k\">else</span> <span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"p\">+</span> <span class=\"nf\">notNullShrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">)</span>\n\n<span class=\"k\">fun</span> <span class=\"nf\">nullableIntShrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">?)</span> <span class=\"p\">=</span> <span class=\"nf\">nullableShrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">,</span> <span class=\"o\">::</span><span class=\"n\">intShrinks</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>That is, you can shrink the nullable value to null or either try to shrink it as you would if it weren’t nullable.</p>\n\n<h3 id=\"divertimento-playing-with-functions\">Divertimento: Playing with functions</h3>\n\n<p>Now that I already introduced a <em>high order function</em> (nullableShrinks is a function that takes a function as a parameter) allow me to dig deeper. I can’t help but do some functional programming here. You can skip this section if you are already tired of me selling this drug:</p>\n\n<p>First let’s redefine <code class=\"language-plaintext highlighter-rouge\">nullableShrinks</code> to not only take a function as a parameter but to also return one. The idea is that it only takes the not null shrinking function (without the value to shrink) and it returns the shrinking function:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">nullableShrinks</span><span class=\"p\">(</span><span class=\"n\">notNullShrinks</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">A</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;):</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">a</span> <span class=\"p\">-&gt;</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"p\">==</span> <span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"nf\">emptyList</span><span class=\"p\">()</span> <span class=\"k\">else</span> <span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"p\">+</span> <span class=\"nf\">notNullShrinks</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n<span class=\"kd\">val</span> <span class=\"py\">nullableIntShrinks</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"nc\">Int</span><span class=\"p\">?)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"nf\">nullableShrinks</span><span class=\"p\">(</span><span class=\"o\">::</span><span class=\"n\">intShrink</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Oh! I forgot our nice type alias:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">nullableShrinks</span><span class=\"p\">(</span><span class=\"n\">notNullShrinks</span><span class=\"p\">:</span> <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;):</span>\n  <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">a</span> <span class=\"p\">-&gt;</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"p\">==</span> <span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"nf\">emptyList</span><span class=\"p\">()</span> <span class=\"k\">else</span> <span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"p\">+</span> <span class=\"nf\">notNullShrinks</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n<span class=\"kd\">val</span> <span class=\"py\">nullableIntShrinks</span><span class=\"p\">:</span> <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">Int</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"nf\">nullableShrinks</span><span class=\"p\">(</span><span class=\"o\">::</span><span class=\"n\">intShrink</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Furthermore, if you like Kotlin function receivers as much as I like them, you can define and use such shrink function as:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;</span> <span class=\"nf\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"p\">&gt;.</span><span class=\"nf\">nullable</span><span class=\"p\">():</span> <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">A</span><span class=\"err\">?</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">a</span> <span class=\"p\">-&gt;</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"p\">==</span> <span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"nf\">emptyList</span><span class=\"p\">()</span> <span class=\"k\">else</span> <span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">)</span> <span class=\"p\">+</span> <span class=\"k\">this</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n<span class=\"kd\">val</span> <span class=\"py\">nullableIntShrinks</span> <span class=\"p\">=</span> <span class=\"o\">::</span><span class=\"n\">intShrink</span><span class=\"p\">.</span><span class=\"nf\">nullable</span><span class=\"p\">()</span>\n<span class=\"kd\">val</span> <span class=\"py\">nullableInstantShrinks</span> <span class=\"p\">=</span> <span class=\"o\">::</span><span class=\"n\">instantShrink</span><span class=\"p\">.</span><span class=\"nf\">nullable</span><span class=\"p\">()</span>\n</code></pre></div></div>\n\n<h2 id=\"user-provided-shrink-functions\">User provided shrink functions</h2>\n\n<p>And now, we can imagine ourselves, users of the PBT library, implementing shrink functions for our types:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">itemFilterShrinks</span><span class=\"p\">:</span> <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">ItemFilter</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">value</span> <span class=\"p\">-&gt;</span>\n    <span class=\"nf\">listOf</span><span class=\"p\">(</span>\n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">minWeightInKgs</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">),</span>\n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">maxWeightInKgs</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">),</span>\n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">olderThan</span> <span class=\"p\">=</span> <span class=\"k\">null</span><span class=\"p\">),</span>\n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">hasAllTags</span> <span class=\"p\">=</span> <span class=\"nf\">emptySet</span><span class=\"p\">())</span>\n    <span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But why not use the nice <code class=\"language-plaintext highlighter-rouge\">nullableIntShrink</code> we just defined, instead of just trying <code class=\"language-plaintext highlighter-rouge\">minWeightInKgs=null</code>? In fact, for each parameter we could try all the shrink values its shrink function provides. Assuming we also have an <code class=\"language-plaintext highlighter-rouge\">instantShrinks</code>, we could do something like:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">itemFilterShrinks</span><span class=\"p\">:</span> <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">ItemFilter</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">value</span> <span class=\"p\">-&gt;</span>\n    <span class=\"c1\">// Either shrink minWeightInKg</span>\n    <span class=\"o\">::</span><span class=\"n\">intShrinks</span><span class=\"p\">.</span><span class=\"nf\">nullable</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">.</span><span class=\"n\">minWeightInKgs</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> \n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">minWeightInKgs</span> <span class=\"p\">=</span> <span class=\"n\">i</span><span class=\"p\">)</span> \n    <span class=\"p\">}</span> <span class=\"p\">+</span> <span class=\"c1\">// or maxWeightInKg...</span>\n    <span class=\"o\">::</span><span class=\"n\">intShrinks</span><span class=\"p\">.</span><span class=\"nf\">nullable</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">.</span><span class=\"n\">maxWeightInKgs</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span> \n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">maxWeightInKgs</span> <span class=\"p\">=</span> <span class=\"n\">i</span><span class=\"p\">)</span> \n    <span class=\"p\">}</span> <span class=\"p\">+</span> <span class=\"c1\">// or olderThan...</span>\n    <span class=\"n\">instantShrink</span><span class=\"p\">.</span><span class=\"nf\">nullable</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">.</span><span class=\"n\">olderThan</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"n\">i</span> <span class=\"p\">-&gt;</span>\n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">olderThan</span> <span class=\"p\">=</span> <span class=\"n\">i</span><span class=\"p\">)</span> \n    <span class=\"p\">}</span> <span class=\"p\">+</span> <span class=\"c1\">// or hasAllTags...</span>\n    <span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">hasAllTags</span> <span class=\"p\">=</span> <span class=\"nf\">emptySet</span><span class=\"p\">()))</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>One way to understand this shrinking function is:</p>\n\n<ol>\n  <li>There are 4 options, the 4 fields you may shrink. We don’t care about combinations of fields, as once shrinked a field, a subtree will try to shrink other fields not yet shrinked.</li>\n  <li>In the option of every field (e.g. <code class=\"language-plaintext highlighter-rouge\">minWeightInKg</code>) there are as many possible shrinks as the field type shrinking function provides (e.g. <code class=\"language-plaintext highlighter-rouge\">nullableIntShrink(value.minWeightInKgs)</code> for the <code class=\"language-plaintext highlighter-rouge\">minWeightInKgs</code> field value).</li>\n</ol>\n\n<h2 id=\"the-problems-with-user-provided-shrink-functions\">The problems with user provided shrink functions</h2>\n\n<p>Ok, we got this far. Nice! We can build shrink functions for all the types we use as test inputs. Isn’t that a large amount of types? That probably is a large amount of types. Isn’t it tedious? It is probably tedious. Is it error prone? It is indeed very error prone!</p>\n\n<p>Let’s look at these 2 problems in isolation:</p>\n\n<h3 id=\"bugs-in-our-bug-hunting-toolset\">Bugs in our bug hunting toolset</h3>\n\n<p><img src=\"../assets/img/TheIncredibleShrinkingMan.jpg\" alt=\"The Incredible Shrinking Man (1957)\" class=\"figcaption\" /></p>\n\n<p><em class=\"figcaption\">Learn from the incredible shrinking man: A bug while playing with shrinking is much more dangerous!</em></p>\n\n<p>The user provided shrink functions are… functions, indeed. And they are code. And code has bugs. But these are an insidious type of bugs, as they only show when you are already trying to understand and fix a failing test that may be as well a bug. Yikes! So, in your happy path, you won’t be running your shrink functions (neither in production nor in tests). They will run only when you have some test failure.</p>\n\n<p>When I’ve found a bug in one of our shrink functions, it usually goes like this:</p>\n\n<ol>\n  <li>I get a PBT test failure and the example causing the failure is complex but the shrinking function does not work, so I get another complex example.</li>\n  <li>I groan. Oh no! Not now!</li>\n  <li>I try to get by without shrinking and try to understand the complex example that fails my test.</li>\n  <li>If I do not despair:\n    <ul>\n      <li>4.1. I fix whatever the test or the production code causing my original test failure</li>\n      <li>4.2. I miserably fail to have the discipline to fix the shrink function.</li>\n      <li>4.3. Goto 1.</li>\n    </ul>\n  </li>\n  <li>If I despair:\n    <ul>\n      <li>5.1. I try to fix my shrinking function while my head is thinking about the actual test failure I try to fix.</li>\n      <li>5.2. I finally manage to focus on fixing shrinking.</li>\n      <li>5.3. Now I need to switch contexts again: Hopefully I have a seed and I can rerun my original failing test with the new shrink function and get a shrunk example I can use to fix whatever failed.</li>\n    </ul>\n  </li>\n</ol>\n\n<h3 id=\"solving-the-buggy-shrinkers-problem\">Solving the buggy shrinkers problem</h3>\n\n<p>So, I know, I don’t like bugs and I’m complaining like that was your fault. But, “hey, Jordi!” - you say - “good programmers write tests”. And tests I write, indeed. But I want my shrinks to properly shrink whatever input I provide, and I’m not in the mood to be just writing examples and the shrinking I expect of them.</p>\n\n<p>I’m leaving the mystery about how we test our shrinkers for a different post. Suffice to say that it is not easy. And, in case you want one spoiler, we don’t test in isolation but integrated in the PBT library, that applies them repeatedly in search for the simplest example.</p>\n\n<h3 id=\"repetition-repetition-repetition\">Repetition, repetition, repetition</h3>\n\n<p>Let’s think about our original example. In fact we wanted to simplify a value of type <code class=\"language-plaintext highlighter-rouge\">ItemSearchCriteria</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">data class</span> <span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">filter</span><span class=\"p\">:</span> <span class=\"nc\">ItemFilter</span><span class=\"p\">,</span> <span class=\"kd\">val</span> <span class=\"py\">order</span><span class=\"p\">:</span> <span class=\"nc\">ItemOrder</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>So we need a shrink function for it too. But the strategy is exactly the same:</p>\n\n<ol>\n  <li>There are as many options as fields our data class has (2 for <code class=\"language-plaintext highlighter-rouge\">ItemSearchCriteria</code>, 4 for <code class=\"language-plaintext highlighter-rouge\">ItemFilter</code>). We don’t care about combination of fields.</li>\n  <li>In the option of every field (e.g. <code class=\"language-plaintext highlighter-rouge\">filter</code> for <code class=\"language-plaintext highlighter-rouge\">ItemSearchCriteria</code> or <code class=\"language-plaintext highlighter-rouge\">minWeightInKg</code> for <code class=\"language-plaintext highlighter-rouge\">ItemFilter</code>), there are as many possible shrinks as the field type shrinking function provides.</li>\n</ol>\n\n<p>So, assuming we also defined <code class=\"language-plaintext highlighter-rouge\">itemOrderShrinks</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">val</span> <span class=\"py\">itemSearchCriteriaShrinks</span><span class=\"p\">:</span> <span class=\"nc\">ShrinkFunction</span><span class=\"p\">&lt;</span><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">value</span> <span class=\"p\">-&gt;</span>\n    <span class=\"c1\">// Either shrink filter</span>\n    <span class=\"nf\">itemFilterShrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">.</span><span class=\"n\">filter</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"n\">f</span> <span class=\"p\">-&gt;</span> \n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">filter</span> <span class=\"p\">=</span> <span class=\"n\">f</span><span class=\"p\">)</span> \n    <span class=\"p\">}</span> <span class=\"p\">+</span> <span class=\"c1\">// or order...</span>\n    <span class=\"nf\">itemOrderShrinks</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">.</span><span class=\"n\">order</span><span class=\"p\">).</span><span class=\"nf\">map</span> <span class=\"p\">{</span> <span class=\"n\">o</span> <span class=\"p\">-&gt;</span> \n      <span class=\"n\">value</span><span class=\"p\">.</span><span class=\"nf\">copy</span><span class=\"p\">(</span><span class=\"n\">order</span> <span class=\"p\">=</span> <span class=\"n\">o</span><span class=\"p\">)</span> \n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>What a repetition, huh? If only we could generalize that and automate it…</p>\n\n<h3 id=\"automatic-shrinking-function-derivation\">Automatic shrinking function derivation</h3>\n\n<p>Our shrinking functions heaven would be to automatically derive the shrinking functions our types need. For that we need a generic algorithm that is capable of returning a shrinking function for a given type (spoiler, it will take other shrinking functions as inputs). On top of that, some black magic may prove useful; something that, given the type we want to shrink (e.g. <code class=\"language-plaintext highlighter-rouge\">ItemSearchCriteria</code>) automatically invokes such function and returns the shrink function. That could be based on introspection, macros… But my doctor says I’m not allowed to use black magic while programming; I seem to be allergic. So I prefer to compose generators using monads and have the shrinking function derived for me, as I’ll show in the (hopefully near) future.</p>\n\n<h2 id=\"conclusions\">Conclusions</h2>\n\n<ol>\n  <li>Jordi can’t explain shrinking in just 2 blog posts. He’ll need like… what, 4 of them? More? In my defense I must say it is not a problem of the written language. When I talk I tend to spend hours to explain anything I’m passionate about, as well. It <em>could be</em> related to my (not so great) knowledge of the English language; if that is the case I apologize, as I’m afraid I may be <a href=\"https://www.youtube.com/watch?v=pltc5rtoskM\">smarter in catalan or spanish</a>.</li>\n  <li>Shrinking functions are promising… but this blog post leaves the reader with a sense of unsafety. Is all this effort worth it? Will we be able to use shrinking or even property based testing without spending lots of hours in doing so? Will the benefit overcome the costs? Many teams I worked with weren’t sure it wouldn’t pay off until they started using property based testing with a proper shrinking infrastructure… and they loved it. So, please, keep reading this series. I’ll try my best to keep writing them.</li>\n  <li>If you were expecting some more seriousness in the conclusions I’m sorry to disapoint you. I was in the mood for some more jokes. But please, do complain via Twitter.  After all, you went far enough to be reading the last few words of the article, so you deserve my apologies.</li>\n</ol>\n\n<h2 id=\"all-the-articles-in-the-series\">All the articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-08-26-pbt-shrinking-part1.html\">Property based testing: Shrinking (part 1)</a></li>\n  <li><a href=\"./2022-09-13-pbt-shrinking-part2.html\">Property based testing: Shrinking (part 2) - Shrinking functions</a></li>\n</ol>\n",
            "url": "https://blog.agilogy.com/2022-09-13-pbt-shrinking-part2.html",
            "date_published": "2022-09-13T00:00:00+02:00",
            "date_modified": "2022-09-13T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-08-26-pbt-shrinking-part1.html",
            "title": "Property based testing: Shrinking (part 1)",
            "content_text": "As you may already know, Property Based Testing (PBT) is an automated testing technique where you test properties of your programs or functions instead of testing particular examples like we do in classical unit testing. A PBT library allows you to program properties (e.g. “for all integers i such that i != 0, 0 / i = 0”) and generators of values that generate random valid examples (e.g. a generator of integers i such that i != 0). It then checks that your program abides by the property you defined for many How many are “many examples”? This is a matter of a different post. generated random examples, assuming that if no counter-example is found after a number of attempts bigger enough, the property is true. Such properties can be written as tests that, instead of hard-coded examples, use randomly generated inputs (and initial state); we will say a property holds for a given example if the test doesn’t fail.\n\nIn this article I will focus on what happens when the property does not hold and an example is found that fails the test. In traditional automated testing, we only need to know which of our test scenarios failed an assertion (and which one), as the test has hard-coded examples we can reason about. But in PBT, beyond the property that failed an assertion, we may need to know what particular counter-example was found. Unfortunately, that randomly generated example may be very complex and there may be simpler values that also fail the test. Shrinking is a feature of property based testing libraries that tries to find such a simpler failing value.\n\nExample: searching for items\n\nLet’s say you have items in some repository represented here as a the function searchItems For the sake of simplification we will assume this repository has a fixed, hardcoded state, a number of hardcoded items so it can be represented as a pure function and we don’t have to deal with state.:\n\ndata class Tag(val value: String)\ndata class Item(\n  val id: String, \n  val weightInKgs: Int, \n  val createdAt: Instant, \n  val tags: Set&lt;Tag&gt;\n)\n\nsuspend fun searchItems(criteria: ItemSearchCriteria): List&lt;Item&gt; = notShown()    \ndata class ItemSearchCriteria(val filter: ItemFilter, val order: ItemOrder)\ndata class ItemFilter(\n  val minWeightInKgs: Int?, \n  val maxWeightInKgs: Int?, \n  val olderThan: Instant?, \n  val hasAllTags: Set&lt;Tag&gt; = emptySet()\n)\ninterface ItemOrder {\n    companion object{\n        object Indifferent: ItemOrder\n        object Age: ItemOrder\n        object Weight: ItemOrder\n    }\n}\n\n\n\nAnd let’s say you have a property such that:\n\nfun Item.matches(filter: ItemFilter): Boolean =\n  (filter.minWeightInKgs?.let { this.weightInKgs &gt;= it } ?: true) &amp;&amp;\n  (filter.maxWeightInKgs?.let { this.weightInKgs &lt;= it } ?: true) &amp;&amp;\n  (filter.olderThan?.let { this.createdAt &lt; it } ?: true) &amp;&amp;\n  this.tags.containsAll(filter.hasAllTags)\n\ntestAll(itemSearchCriteriaArb) { searchCriteria -&gt;\n  val result = searchItems(searchCriteria)\n  val failingResults = result.filter { it.matches(searchCriteria.filter) }\n  assertEquals(emptySet(), failingResults.toSet())\n}\n\n\nAssume we get a failing test with the following sample, for which our function returns items with weight above 110.\n\nItemSearchCriteria(ItemFilter(23, 110, 2022-01-01T00:00:00.000, setOf(Tag.clothes, Tag.exclusive)), AgetItemOrder)\n\n\nNow you know that the searchItem function is not behaving correctly with this particular example. Imagine there is a bug in the filter by maxWeightInKg that, by mistake, filters by the reverse condition in your implementation, but, of course, the developers are unaware of it.\n\nManually bug hunting\n\n\n\nIn our example, we found a test that fails when the randomly search criteria are the ones shown above. Let the game begin!\n\nOf course we may notice that the returned items all have a weight above 110 and we would be done. But that may be difficult to realize. Imagine your search returns hundreds or thousands of items and that each item, instead of a blog example is a complex entity. Now you are probably facing a daunting screen of thousands of lines printing the returned examples and it is difficult to see what of the filters they fail to satisfy.\n\nThe problem is that the example for which we got a failure is way too complex. We have (potentially) a lot of distracting values that don’t matter for the bug at hand. Knowing what the bug is, you and me know that it doesn’t matter wether you filter by olderThan or not. Knowing what the bug is, if I asked you, a wonderful and smart human being, what the simplest counter-example is, you would probably give me something like ItemSearchCriteria(ItemFilter(null, 0, null, emptySet()), Indifferent).\n\nYou are indeed smart… but, out there, you don’t know what the bug is in advance. So let’s try to simplify the example bit by bit.\n\nShrinking the failing example\n\nLooking at the problem at hand and assuming I don’t have any clue about what is failing, I’d try to remove criteria I think won’t affect filtering. So, let’s try telling our function we don’t care about sorting:\n\nItemSearchCriteria(ItemFilter(23, 110, 2022-01-01T00:00:00.000, setOf(Tag.clothes, Tag.exclusive)), Indifferent)\n\n\n1️⃣ 🔥 A failure. And now we have a simpler example, one with less distracting values.\n\nNow I’d try removing filters one by one. Let’s go left to right:\n\nItemSearchCriteria(ItemFilter(null, 110, 2022-01-01T00:00:00.000, setOf(Tag.clothes, Tag.exclusive)), Indifferent)\n\n\n2️⃣ 🔥Ok, it still fails. So far so good, it seems that the sorting and min weight aren’t unrelated to the problem.\n\nLet’s go for maxWeightInKgs:\n\nItemSearchCriteria(ItemFilter(null, null, 2022-01-01T00:00:00.000, setOf(Tag.clothes, Tag.exclusive)), Indifferent)\n\n\n\n\n3️⃣ ✅ Woa! That one passes the tests! This is already a very good hint! We may have a bug in maxWeightInKgs. But what about the other filters? Are they related to the failure? Our example is still not as nice as the one we know we want if we know where the bug is. At the same time, as this example didn’t fail, I wouldn’t probably keep shrinking it. In other terms, setting maxWeightInKgs to null opens a path (that would admit more simplifications) where our bug is not manifested. These are not the examples we are looking for.\n\nBut we can try to keep simplifying 2️⃣ to check wether olderThan and hasAllTags are unrelated. So, let’s try to remove olderThan:\n\nItemSearchCriteria(ItemFilter(null, 110, null, setOf(Tag.clothes, Tag.exclusive)), Indifferent)\n\n\n4️⃣ 🔥 Ok, it keeps failing. olderThan seems unrelated to our failure.\n\nItemSearchCriteria(ItemFilter(null, 110, null, emptySet()), Indifferent)\n\n\n5️⃣ 🔥 hasAllTags seems unrealted to the failure too.\n\nWhat about going one step further?\n\nItemSearchCriteria(ItemFilter(null, null, null, emptySet()), Indifferent)\n\n6️⃣ ✅ The test now succeeds. maxWeightInKgs definetively seems the cause of our trouble.\n\nSo the simplest example we’ve got so far is example 5️⃣. But we can play this game even further. Do we have a problem with the number 110? Or any number would fail? As humans, round decimal numbers and numbers closer to 0 seem simpler, so we could keep shrinking this example to test for maxWeightInKgs 100 7️⃣, 50 8️⃣, 0 9️⃣ and it would still fail. So we got:\n\nItemSearchCriteria(ItemFilter(null, 0, null, emptySet()), Indifferent)\n\n\nAssuming 0 is the simplest value for the maxWeightInKgsfilter (other than null), the example we have can’t be further simplified.\n\nNow, that’s a nice example to use to try to understand our bug!\n\nTraversing the shrinking tree\n\nIf we think carefully at what we just did we can see we are doing a search in a tree of simplifications Here 🔥 means the example fails the test and ✅ means the example passes the test.:\n\ngraph LR\n  0[initial &amp;#x1F525] --&gt; 1[1 &amp;#x1F525] --&gt; 2[2 &amp;#x1F525] --&gt; 3[3 &amp;#x2705]\n  0 --&gt; initialOthers[...]\n  1 --&gt; 1others[...]\n  2 --&gt; 4[4 &amp;#x1F525] --&gt; 5[5 &amp;#x1F525]--&gt; 6[6 &amp;#x2705]\n  2 --&gt; 2others[...]\n  4 --&gt; 4others[...]\n  5 --&gt; 7[7 &amp;#x1F525] --&gt; 8[8 &amp;#x1F525] --&gt; 9[9 &amp;#x1F525]\n  5 --&gt; 5others[...]\n  7 --&gt; 7others[...]\n  8 --&gt; 8others[...]\n\n\nWe did this more or less by hand. But, hey, there is a reason they taught you how to traverse a graph! Computers like to do this kind of stuff and they excel at it!! Why don’t ask our fancy open source PBT library to shrink for us?\n\nConclusions\n\nWe have seen how property based testing gives us complex examples of inputs for which our program doesn’t satisfy the property we expect it to. Once we have one such example it may be difficult to diagnose what the bug was. One strategy we may use is to simplify or shrink our example to get simpler examples that still fail. That can be useful to reason about what is failing but also to debug our program with less distracting inputs, for example.\n\nIn the next post in the series we’ll discuss how a property based testing library can automate this shrinking and what are the difficulties of doing so.\n\nAll the articles in the series\n\n\n  Property based testing: Shrinking (part 1)\n  Property based testing: Shrinking (part 2) - Shrinking functions\n\n\n",
            "content_html": "<p>As you may already know, Property Based Testing (PBT) is an automated testing technique where you test properties of your programs or functions instead of testing particular examples like we do in classical unit testing. A PBT library allows you to program properties (e.g. “for all integers <code class=\"language-plaintext highlighter-rouge\">i</code> such that <code class=\"language-plaintext highlighter-rouge\">i != 0</code>, <code class=\"language-plaintext highlighter-rouge\">0 / i = 0</code>”) and generators of values that generate random valid examples (e.g. a generator of integers <code class=\"language-plaintext highlighter-rouge\">i</code> such that <code class=\"language-plaintext highlighter-rouge\">i != 0</code>). It then checks that your program abides by the property you defined for <em class=\"sidenote-number\">many</em> <em class=\"sidenote\">How many are “many examples”? This is a matter of a different post.</em> generated random examples, assuming that if no counter-example is found after a number of attempts bigger enough, the property is true. Such properties can be written as tests that, instead of hard-coded examples, use randomly generated inputs (and <a href=\"2022-05-27-what-is-an-automated-test-again.html\">initial state</a>); we will say a property holds for a given example if the test doesn’t fail.</p>\n\n<p>In this article I will focus on what happens when the property does not hold and an example is found that fails the test. In traditional automated testing, we only need to know which of our test scenarios failed an assertion (and which one), as the test has hard-coded examples we can reason about. But in PBT, beyond the property that failed an assertion, we may need to know what particular counter-example was found. Unfortunately, that randomly generated example may be very complex and there may be simpler values that also fail the test. Shrinking is a feature of property based testing libraries that tries to find such a simpler failing value.</p>\n\n<h2 id=\"example-searching-for-items\">Example: searching for items</h2>\n\n<p>Let’s say you have items in some repository represented here as a <em class=\"sidenote-number\">the function <code class=\"language-plaintext highlighter-rouge\">searchItems</code></em> <em class=\"sidenote\">For the sake of simplification we will assume this repository has a fixed, hardcoded state, a number of hardcoded items so it can be represented as a pure function and we don’t have to <a href=\"2022-06-17-testing-and-persistent-state.html\">deal with state</a>.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">data class</span> <span class=\"nc\">Tag</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">value</span><span class=\"p\">:</span> <span class=\"nc\">String</span><span class=\"p\">)</span>\n<span class=\"kd\">data class</span> <span class=\"nc\">Item</span><span class=\"p\">(</span>\n  <span class=\"kd\">val</span> <span class=\"py\">id</span><span class=\"p\">:</span> <span class=\"nc\">String</span><span class=\"p\">,</span> \n  <span class=\"kd\">val</span> <span class=\"py\">weightInKgs</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span> \n  <span class=\"kd\">val</span> <span class=\"py\">createdAt</span><span class=\"p\">:</span> <span class=\"nc\">Instant</span><span class=\"p\">,</span> \n  <span class=\"kd\">val</span> <span class=\"py\">tags</span><span class=\"p\">:</span> <span class=\"nc\">Set</span><span class=\"p\">&lt;</span><span class=\"nc\">Tag</span><span class=\"p\">&gt;</span>\n<span class=\"p\">)</span>\n\n<span class=\"k\">suspend</span> <span class=\"k\">fun</span> <span class=\"nf\">searchItems</span><span class=\"p\">(</span><span class=\"n\">criteria</span><span class=\"p\">:</span> <span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">):</span> <span class=\"nc\">List</span><span class=\"p\">&lt;</span><span class=\"nc\">Item</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"nf\">notShown</span><span class=\"p\">()</span>    \n<span class=\"kd\">data class</span> <span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">filter</span><span class=\"p\">:</span> <span class=\"nc\">ItemFilter</span><span class=\"p\">,</span> <span class=\"kd\">val</span> <span class=\"py\">order</span><span class=\"p\">:</span> <span class=\"nc\">ItemOrder</span><span class=\"p\">)</span>\n<span class=\"kd\">data class</span> <span class=\"nc\">ItemFilter</span><span class=\"p\">(</span>\n  <span class=\"kd\">val</span> <span class=\"py\">minWeightInKgs</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">?,</span> \n  <span class=\"kd\">val</span> <span class=\"py\">maxWeightInKgs</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">?,</span> \n  <span class=\"kd\">val</span> <span class=\"py\">olderThan</span><span class=\"p\">:</span> <span class=\"nc\">Instant</span><span class=\"p\">?,</span> \n  <span class=\"kd\">val</span> <span class=\"py\">hasAllTags</span><span class=\"p\">:</span> <span class=\"nc\">Set</span><span class=\"p\">&lt;</span><span class=\"nc\">Tag</span><span class=\"p\">&gt;</span> <span class=\"p\">=</span> <span class=\"nf\">emptySet</span><span class=\"p\">()</span>\n<span class=\"p\">)</span>\n<span class=\"kd\">interface</span> <span class=\"nc\">ItemOrder</span> <span class=\"p\">{</span>\n    <span class=\"k\">companion</span> <span class=\"k\">object</span><span class=\"p\">{</span>\n        <span class=\"kd\">object</span> <span class=\"nc\">Indifferent</span><span class=\"p\">:</span> <span class=\"nc\">ItemOrder</span>\n        <span class=\"kd\">object</span> <span class=\"nc\">Age</span><span class=\"p\">:</span> <span class=\"nc\">ItemOrder</span>\n        <span class=\"kd\">object</span> <span class=\"nc\">Weight</span><span class=\"p\">:</span> <span class=\"nc\">ItemOrder</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n</code></pre></div></div>\n\n<p>And let’s say you have a property such that:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nc\">Item</span><span class=\"p\">.</span><span class=\"nf\">matches</span><span class=\"p\">(</span><span class=\"n\">filter</span><span class=\"p\">:</span> <span class=\"nc\">ItemFilter</span><span class=\"p\">):</span> <span class=\"nc\">Boolean</span> <span class=\"p\">=</span>\n  <span class=\"p\">(</span><span class=\"n\">filter</span><span class=\"p\">.</span><span class=\"n\">minWeightInKgs</span><span class=\"o\">?.</span><span class=\"nf\">let</span> <span class=\"p\">{</span> <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"n\">weightInKgs</span> <span class=\"p\">&gt;=</span> <span class=\"n\">it</span> <span class=\"p\">}</span> <span class=\"o\">?:</span> <span class=\"k\">true</span><span class=\"p\">)</span> <span class=\"p\">&amp;&amp;</span>\n  <span class=\"p\">(</span><span class=\"n\">filter</span><span class=\"p\">.</span><span class=\"n\">maxWeightInKgs</span><span class=\"o\">?.</span><span class=\"nf\">let</span> <span class=\"p\">{</span> <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"n\">weightInKgs</span> <span class=\"p\">&lt;=</span> <span class=\"n\">it</span> <span class=\"p\">}</span> <span class=\"o\">?:</span> <span class=\"k\">true</span><span class=\"p\">)</span> <span class=\"p\">&amp;&amp;</span>\n  <span class=\"p\">(</span><span class=\"n\">filter</span><span class=\"p\">.</span><span class=\"n\">olderThan</span><span class=\"o\">?.</span><span class=\"nf\">let</span> <span class=\"p\">{</span> <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"n\">createdAt</span> <span class=\"p\">&lt;</span> <span class=\"n\">it</span> <span class=\"p\">}</span> <span class=\"o\">?:</span> <span class=\"k\">true</span><span class=\"p\">)</span> <span class=\"p\">&amp;&amp;</span>\n  <span class=\"k\">this</span><span class=\"p\">.</span><span class=\"n\">tags</span><span class=\"p\">.</span><span class=\"nf\">containsAll</span><span class=\"p\">(</span><span class=\"n\">filter</span><span class=\"p\">.</span><span class=\"n\">hasAllTags</span><span class=\"p\">)</span>\n\n<span class=\"nf\">testAll</span><span class=\"p\">(</span><span class=\"n\">itemSearchCriteriaArb</span><span class=\"p\">)</span> <span class=\"p\">{</span> <span class=\"n\">searchCriteria</span> <span class=\"p\">-&gt;</span>\n  <span class=\"kd\">val</span> <span class=\"py\">result</span> <span class=\"p\">=</span> <span class=\"nf\">searchItems</span><span class=\"p\">(</span><span class=\"n\">searchCriteria</span><span class=\"p\">)</span>\n  <span class=\"kd\">val</span> <span class=\"py\">failingResults</span> <span class=\"p\">=</span> <span class=\"n\">result</span><span class=\"p\">.</span><span class=\"nf\">filter</span> <span class=\"p\">{</span> <span class=\"n\">it</span><span class=\"p\">.</span><span class=\"nf\">matches</span><span class=\"p\">(</span><span class=\"n\">searchCriteria</span><span class=\"p\">.</span><span class=\"n\">filter</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"nf\">emptySet</span><span class=\"p\">(),</span> <span class=\"n\">failingResults</span><span class=\"p\">.</span><span class=\"nf\">toSet</span><span class=\"p\">())</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Assume we get a failing test with the following sample, for which our function returns items with weight above <code class=\"language-plaintext highlighter-rouge\">110</code>.</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span> <span class=\"mi\">110</span><span class=\"p\">,</span> <span class=\"mi\">2022</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"nc\">T00</span><span class=\"p\">:</span><span class=\"mi\">00</span><span class=\"p\">:</span><span class=\"mf\">00.000</span><span class=\"p\">,</span> <span class=\"nf\">setOf</span><span class=\"p\">(</span><span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">clothes</span><span class=\"p\">,</span> <span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">exclusive</span><span class=\"p\">)),</span> <span class=\"nc\">AgetItemOrder</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Now you know that the <code class=\"language-plaintext highlighter-rouge\">searchItem</code> function is not behaving correctly with this particular example. Imagine there is a bug in the filter by <code class=\"language-plaintext highlighter-rouge\">maxWeightInKg</code> that, by mistake, filters by the reverse condition in your implementation, but, of course, the developers are unaware of it.</p>\n\n<h2 id=\"manually-bug-hunting\">Manually bug hunting</h2>\n\n<p class=\"figcaption\"><img src=\"https://y.yarn.co/76c65c90-5e05-419f-9a84-0f8adc431d92_text.gif\" /></p>\n\n<p>In our example, we found a test that fails when the randomly search criteria are the ones shown above. Let the game begin!</p>\n\n<p>Of course we may notice that the returned items all have a weight above 110 and we would be done. But that may be difficult to realize. Imagine your search returns hundreds or thousands of items and that each item, instead of a blog example is a complex entity. Now you are probably facing a daunting screen of thousands of lines printing the returned examples and it is difficult to see what of the filters they fail to satisfy.</p>\n\n<p>The problem is that the example for which we got a failure is way too complex. We have (potentially) a lot of distracting values that don’t matter for the bug at hand. Knowing what the bug is, you and me know that it doesn’t matter wether you filter by <code class=\"language-plaintext highlighter-rouge\">olderThan</code> or not. Knowing what the bug is, if I asked you, a wonderful and smart human being, what the simplest counter-example is, you would probably give me something like <code class=\"language-plaintext highlighter-rouge\">ItemSearchCriteria(ItemFilter(null, 0, null, emptySet()), Indifferent)</code>.</p>\n\n<p>You are indeed smart… but, out there, you don’t know what the bug is in advance. So let’s try to simplify the example bit by bit.</p>\n\n<h2 id=\"shrinking-the-failing-example\">Shrinking the failing example</h2>\n\n<p>Looking at the problem at hand and assuming I don’t have any clue about what is failing, I’d try to remove criteria I <em>think</em> won’t affect filtering. So, let’s try telling our function we don’t care about sorting:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span> <span class=\"mi\">110</span><span class=\"p\">,</span> <span class=\"mi\">2022</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"nc\">T00</span><span class=\"p\">:</span><span class=\"mi\">00</span><span class=\"p\">:</span><span class=\"mf\">00.000</span><span class=\"p\">,</span> <span class=\"nf\">setOf</span><span class=\"p\">(</span><span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">clothes</span><span class=\"p\">,</span> <span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">exclusive</span><span class=\"p\">)),</span> <span class=\"nc\">Indifferent</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>1️⃣ 🔥 A failure. And now we have a simpler example, one with less distracting values.</p>\n\n<p>Now I’d try removing filters one by one. Let’s go left to right:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"mi\">110</span><span class=\"p\">,</span> <span class=\"mi\">2022</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"nc\">T00</span><span class=\"p\">:</span><span class=\"mi\">00</span><span class=\"p\">:</span><span class=\"mf\">00.000</span><span class=\"p\">,</span> <span class=\"nf\">setOf</span><span class=\"p\">(</span><span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">clothes</span><span class=\"p\">,</span> <span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">exclusive</span><span class=\"p\">)),</span> <span class=\"nc\">Indifferent</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>2️⃣ 🔥Ok, it still fails. So far so good, it seems that the sorting and min weight aren’t unrelated to the problem.</p>\n\n<p>Let’s go for <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"mi\">2022</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"p\">-</span><span class=\"mi\">01</span><span class=\"nc\">T00</span><span class=\"p\">:</span><span class=\"mi\">00</span><span class=\"p\">:</span><span class=\"mf\">00.000</span><span class=\"p\">,</span> <span class=\"nf\">setOf</span><span class=\"p\">(</span><span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">clothes</span><span class=\"p\">,</span> <span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">exclusive</span><span class=\"p\">)),</span> <span class=\"nc\">Indifferent</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p class=\"figcaption\"><img src=\"https://c.tenor.com/TlfAvuz0tLMAAAAC/obi-wan-kenobi-these-are-not-the-droids.gif\" /></p>\n\n<p>3️⃣ ✅ Woa! That one passes the tests! This is already a very good hint! We may have a bug in <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code>. But what about the other filters? Are they related to the failure? Our example is still not as nice as the one we know we want if we know where the bug is. At the same time, as this example didn’t fail, I wouldn’t probably keep shrinking it. In other terms, setting <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code> to <code class=\"language-plaintext highlighter-rouge\">null</code> opens a path (that would admit more simplifications) where our bug is not manifested. These are not the examples we are looking for.</p>\n\n<p>But we can try to keep simplifying 2️⃣ to check wether <code class=\"language-plaintext highlighter-rouge\">olderThan</code> and <code class=\"language-plaintext highlighter-rouge\">hasAllTags</code> are unrelated. So, let’s try to remove <code class=\"language-plaintext highlighter-rouge\">olderThan</code>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"mi\">110</span><span class=\"p\">,</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"nf\">setOf</span><span class=\"p\">(</span><span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">clothes</span><span class=\"p\">,</span> <span class=\"nc\">Tag</span><span class=\"p\">.</span><span class=\"n\">exclusive</span><span class=\"p\">)),</span> <span class=\"nc\">Indifferent</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>4️⃣ 🔥 Ok, it keeps failing. <code class=\"language-plaintext highlighter-rouge\">olderThan</code> seems unrelated to our failure.</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"mi\">110</span><span class=\"p\">,</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"nf\">emptySet</span><span class=\"p\">()),</span> <span class=\"nc\">Indifferent</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>5️⃣ 🔥 <code class=\"language-plaintext highlighter-rouge\">hasAllTags</code> seems unrealted to the failure too.</p>\n\n<p>What about going one step further?</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"nf\">emptySet</span><span class=\"p\">()),</span> <span class=\"nc\">Indifferent</span><span class=\"p\">)</span>\n</code></pre></div></div>\n<p>6️⃣ ✅ The test now succeeds. <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code> definetively seems the cause of our trouble.</p>\n\n<p>So the simplest example we’ve got so far is example 5️⃣. But we can play this game even further. Do we have a problem with the number <code class=\"language-plaintext highlighter-rouge\">110</code>? Or any number would fail? As humans, round decimal numbers and numbers closer to 0 seem simpler, so we could keep shrinking this example to test for <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code> <code class=\"language-plaintext highlighter-rouge\">100</code> 7️⃣, <code class=\"language-plaintext highlighter-rouge\">50</code> 8️⃣, <code class=\"language-plaintext highlighter-rouge\">0</code> 9️⃣ and it would still fail. So we got:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">ItemSearchCriteria</span><span class=\"p\">(</span><span class=\"nc\">ItemFilter</span><span class=\"p\">(</span><span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"k\">null</span><span class=\"p\">,</span> <span class=\"nf\">emptySet</span><span class=\"p\">()),</span> <span class=\"nc\">Indifferent</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Assuming 0 is the simplest value for the <code class=\"language-plaintext highlighter-rouge\">maxWeightInKgs</code>filter (other than null), the example we have can’t be further simplified.</p>\n\n<p>Now, that’s a nice example to use to try to understand our bug!</p>\n\n<h2 id=\"traversing-the-shrinking-tree\">Traversing the shrinking tree</h2>\n\n<p>If we think carefully at what we just did we can see we are doing a search in a <em class=\"sidenote-number\">tree of simplifications</em> <em class=\"sidenote\">Here 🔥 means the example fails the test and ✅ means the example passes the test.</em>:</p>\n\n<pre><code class=\"language-mermaid\">graph LR\n  0[initial &amp;#x1F525] --&gt; 1[1 &amp;#x1F525] --&gt; 2[2 &amp;#x1F525] --&gt; 3[3 &amp;#x2705]\n  0 --&gt; initialOthers[...]\n  1 --&gt; 1others[...]\n  2 --&gt; 4[4 &amp;#x1F525] --&gt; 5[5 &amp;#x1F525]--&gt; 6[6 &amp;#x2705]\n  2 --&gt; 2others[...]\n  4 --&gt; 4others[...]\n  5 --&gt; 7[7 &amp;#x1F525] --&gt; 8[8 &amp;#x1F525] --&gt; 9[9 &amp;#x1F525]\n  5 --&gt; 5others[...]\n  7 --&gt; 7others[...]\n  8 --&gt; 8others[...]\n</code></pre>\n\n<p>We did this more or less by hand. But, hey, there is a reason they taught you how to traverse a graph! Computers like to do this kind of stuff and they excel at it!! Why don’t ask our fancy open source PBT library to shrink for us?</p>\n\n<h2 id=\"conclusions\">Conclusions</h2>\n\n<p>We have seen how property based testing gives us complex examples of inputs for which our program doesn’t satisfy the property we expect it to. Once we have one such example it may be difficult to diagnose what the bug was. One strategy we may use is to simplify or shrink our example to get simpler examples that still fail. That can be useful to reason about what is failing but also to debug our program with less distracting inputs, for example.</p>\n\n<p>In the next post in the series we’ll discuss how a property based testing library can automate this shrinking and what are the difficulties of doing so.</p>\n\n<h2 id=\"all-the-articles-in-the-series\">All the articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-08-26-pbt-shrinking-part1.html\">Property based testing: Shrinking (part 1)</a></li>\n  <li><a href=\"./2022-09-13-pbt-shrinking-part2.html\">Property based testing: Shrinking (part 2) - Shrinking functions</a></li>\n</ol>\n\n",
            "url": "https://blog.agilogy.com/2022-08-26-pbt-shrinking-part1.html",
            "date_published": "2022-08-26T00:00:00+02:00",
            "date_modified": "2022-08-26T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-07-08-testing-other-side-effects.html",
            "title": "Testing other side effects",
            "content_text": "Previously on Agilogy blog…\n\n\n  What if your function is not deterministic because… it generates random values? Or just because it uses the current system time? And what about it doing some I/O, like reading from the file system, a database or a socket? Even more, what about procedures generating some kind of externally observable effect, like writing to the file system or a databse?\n\n  What is an automated test, again?\n\n\n\n\nIn which trying to test a function that uses the System clock leads us to design for testing and, finally, to wonder what to test\n\nLet’s take a very simple function:\n\nfun age(birthDate: LocalDate): Int = \n  Period.between(birthDate, LocalDate.now()).years\n\n\nSimple, right? One line, and that means simple, right? Of course not. But why? Let’s try to write an automated test for it.\n\nNow, there are at least these 3 typical moments in the life of a developer where you can be in. You may be reading this puzzled, not knowing how the hell to test that without having to change the test yearly. Or you start thinking mocks. Or you start thinking how to redesign this one-linerI mean, beyond the ugly implicit usage of the system default time zone, which I, at least, would refactor out of my sight..\n\nI’m going to try to take you from puzzled to a better design without going through mocks Are you already thinking about them? Please, consider this article an alternative to mocking..\n\nThe issue with testing this function is, you may have guessed, Instant.now(), which would return a different value on each test execution.\n\nYou could, of course, try something like this:\n\n@Test\nfun testAge() {\n  assertEquals(7, age(LocalDate.of(2014, 7, 30)))\n}\n\n\nBut then, of course, after my son’s birthday party the test will fail and you would need to update it. Nasty.\n\nThe problem, here is that we are getting the current date LocalDate.now() and that has the odd habit of chaning as time goes by. We are also calculating how many years are there between 2 local dates, which would be fine to test, but… Yes, these 2 things this function does are what Rich Hickey would call complected If you haven’t seen this famous talk, make yourself a favour and bookmark it: Simple Made Easy. Then, when you are ready, take a cup of your best coffee, tea, mate or whatever is your poison and enjoy an hour of pure talent.:\n\n\n  Okay. So there’s this really cool word called complect. I found it. I love it. It means to interleave or entwine or braid. Okay?\n…\nHaving state in your program is never simple because it has a  fundamental complecting that goes on in its artifacts. It complects  value and time. (…) Well, if every time you call that method with the same arguments, you  can get a different result, guess what happened? That complexity just  leaked right out of there (…). If the thing that’s wrapping it is stateful (…) by stateful I mean every time you ask it the same question you get a different answer, you have this complexity and it’s like poison.\n\n  Rich Hickey, Simple Made Easy\n\n\nSo, even though it is a one-liner, we want to simplify this function. A first step would be to rule off the function that we find difficult to test:\n\nfun ageOn(today: LocalDate, birthDate: LocalDate): Int =   \n  Period.between(birthDate, today).years\n\n\nThat one is easy to test. We say it is testable Testability is, indeed, a software quality factor. But, curiously enough, aiming at testability enhances the quality of your software in other aspects as well.. But now the user of the function needs to do what was part of the responsibilities of age before: getting the current local date. We can recover our original age function defining a new function like this:\n\nfun age(birthDate: LocalDate): Int = ageOn(LocalDate.now(), birthDate)\n\n\nNow we can test we correctly calculated the number of years between two dates and that that is what we actually mean by age:\n\n@Test\nfun testAgeOn() {\n  assertEquals(\n    7,\n    ageOn(LocalDate.of(2022, 6, 1), LocalDate.of(2014, 6, 30))\n  )\n}\n\n\nWhat about the original age function? How do we test that one? We still can’t. The problem with testing age was, to begin with, that we don’t know how to test the part that gets the current local date… So, here are some questions that will make you think:\n\n\n  How do we test that LocalDate.now() returns the current date?\n  Assuming we can trust LocalDate.now(),  how do we test that age uses LocalDate.now() and not some other wrong / untrusted / untested method to get the current date?\n  Assuming age correctly gets the current date somehow, how do we know it is (correctly) using ageOn?\n\n\nOr, put it in another way, even with our test of ageOn, each risk in the following list corresponds to one of the questions we were asking above:\n\n\n  LocalDate.now() could be producing the wrong date, not the current date\n  age could be getting the current date using some untested method that gets it wrong\n  age could be correctly getting the current date but fail to calculate the number of years between the 2 dates, as we tested ageOn but we didn’t test wether age is invoking it and, if so, if it is handling it the correct arguments in the correct order.\n\n\nLet’s start with the last two concerns here…\n\nDesigning for testability\n\nLet’s imagine we solve the first question/concern above somehow More on that at the end of the article. But let’s consider it solved now.. What would we need to solve the other two? We want some new version of age that we can test, so that we solve the last question. And we want to make sure it uses what we want to get the current local date, so that the second question is also solved.\n\nThat is, we want a function that, given the way of getting the current date of our choice and a birth date, gets it and properly calculates the number of years since the birth date to that current date. Do you see what I did there? I just used the same expression for “the way of getting the current date” and “a birth date”. Yes, they both  can be parameters:\n\nfun age(getCurrentDate: () -&gt; LocalDate, birthDate: LocalDate): Int =\n  Period.between(birthDate, getCurrentDate()).years\n\n\nWe can now test almost everything we were concerned about:\n\n@Test\nfun testAge() {\n  val getDate: () -&gt; LocalDate = { LocalDate.of(2022, 6, 1) }\n  assertEquals(\n    7,\n    age(getDate, LocalDate.of(2014, 6, 30))\n  )\n}\n\n\nNote that getDate here is a function that always returns the same result. () -&gt; LocalDate is the type of functions that have no parameters and return a LocalDate.\n\nNow we can build tests where we check that age uses whatever function we pass it as the first argument (our second concern), and that age properly calculates the number of years between birthDate and the date returned by getCurrentDate.\n\nWe say that age depends on the function that returns the current date and that we injected that dependency into age.\n\nThis is just one particular style of dependency injection, one with which you may not be familiar. Some other styles come to mind:\n\n  Instead of injecting () -&gt; LocalDate we could have injected an instance of some named type like interface Clock that contained methods for what we wanted to acomplish:\n\n\nfun age(clock: Clock, birthDate: LocalDate): Int =\n  Period.between(birthDate, clock.getCurrentDate()).years\n\n\n\n  Instead of injecting the function or instance as a parameter of the function age, we could have put the age function in a class and inject something to the class:\n\n\nclass AgeModule(val clock: Clock){\n  fun age(birthDate: LocalDate): Int =\n    Period.between(birthDate, clock.getCurrentDate()).years\n}\n\n\n\n  Hell, if you are really into monadic stuff, we could have even used a reader Monad I may talk about that in a future article.  defining age as a function that returns a function that given whatever it needs injected, returns the result we want:\n\n\nfun age(birthDate: LocalDate): (Clock) -&gt; LocalDate = { clock -&gt;\n  Period.between(birthDate, clock.getCurrentDate()).years \n}\n\n\nWhat about testing that LocalDate.now() returns the current date?\n\nThat one, the one I left unsolved so far is the easiest one to solve. I don’t have any clue about how to properly test that, but I don’t even care. “How do I test that, then?” - you say. My answer: Don’t. Don’t test it. Nada. Niente. Res de res.\n\nThis may seem silly but it is, in fact, a very important part of our testing strategy at Agilogy. You should not be testing other’s code. And by “other’s” I mean code in another module. Once you think about it, in fact, it is quite common sense:\n\n\n  Testing some other module software breaks modularity itself. That other module is responsible for its own stuff, not your module. If something’s wrong there, test it there, where you can fix it.\n  Testing some other module software is very inefficient. Either it is a module you can trust and it will have tests for that, probably much better tests than those you will come up with, or it is a module you can’t trust and then you shouldn’t be using it at all Of course, I’m being a bit too blunt here. You may want to test some open source library does what you expect it too, for example. But I’m assuming we want to test our age function here and my point is that testing that a dependency of age properly does its work is out of the scope of the tests for age..\n  If a module B is used by a module A and you own both, testing your module B in A doesn’t provide any safety net against changes in B. You may be working on B and breaking things without that test telling you so and you may release a version of B used by some C that was not testing it properly. Boom, you have a bug in production you could have prevented by testing B in B.\n\n\nConclusions\n\nSo I cheated you. I told you I was going to talk about testing and I ended up talking about complection, software design and dependency injection…. or didn’t I?\n\n\n\nThe Oracle, not the Oracle DB\n\nSo we have built a simpler, better age function. But, paraphrasing the Oracle, what’s really going to bake your noodle later on is, would we still have reached such simple, elegant solution if I hadn’t said anything about testing?\n\nAll the articles in the series\n\n\n  What is an automated test, again?\n  Testing and persistent state\n  Testing other side effects\n\n",
            "content_html": "<p>Previously on Agilogy blog…</p>\n\n<blockquote>\n  <p>What if your function is not deterministic because… it generates random values? Or just because it uses the current system time? And what about it doing some I/O, like reading from the file system, a database or a socket? Even more, what about procedures generating some kind of externally observable effect, like <strong>writing</strong> to the file system or a databse?</p>\n\n  <p><a href=\"./2022-05-27-what-is-an-automated-test-again.html\">What is an automated test, again?</a></p>\n</blockquote>\n\n<!--more-->\n\n<h2 id=\"in-which-trying-to-test-a-function-that-uses-the-system-clock-leads-us-to-design-for-testing-and-finally-to-wonder-what-to-test\">In which trying to test a function that uses the System clock leads us to design for testing and, finally, to wonder what to test</h2>\n\n<p>Let’s take a very simple function:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> \n  <span class=\"nc\">Period</span><span class=\"p\">.</span><span class=\"nf\">between</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">,</span> <span class=\"nc\">LocalDate</span><span class=\"p\">.</span><span class=\"nf\">now</span><span class=\"p\">()).</span><span class=\"n\">years</span>\n</code></pre></div></div>\n\n<p>Simple, right? One line, and that means simple, right? Of course not. But why? Let’s try to write an automated test for it.</p>\n\n<p>Now, there are at least these 3 typical moments in the life of a developer where you can be in. You may be reading this <strong>puzzled</strong>, not knowing how the hell to test that without having to change the test yearly. Or you start thinking <strong>mocks</strong>. Or you start thinking how to redesign this <em class=\"sidenote-number\">one-liner</em><em class=\"sidenote\">I mean, beyond the ugly implicit usage of the system default time zone, which <strong>I</strong>, at least, would refactor out of my sight.</em>.</p>\n\n<p>I’m going to try to take you from puzzled to a better design without going through <em class=\"sidenote-number\">mocks</em> <em class=\"sidenote\">Are you already thinking about them? Please, consider this article an alternative to mocking.</em>.</p>\n\n<p>The issue with testing this function is, you may have guessed, <code class=\"language-plaintext highlighter-rouge\">Instant.now()</code>, which would return a different value on each test execution.</p>\n\n<p>You could, of course, try something like this:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testAge</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"nc\">LocalDate</span><span class=\"p\">.</span><span class=\"nf\">of</span><span class=\"p\">(</span><span class=\"mi\">2014</span><span class=\"p\">,</span> <span class=\"mi\">7</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">)))</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>But then, of course, after my son’s birthday party the test will fail and you would need to update it. Nasty.</p>\n\n<p>The problem, here is that we are getting the current date <code class=\"language-plaintext highlighter-rouge\">LocalDate.now()</code> and that has the odd habit of chaning as time goes by. We are also calculating how many years are there between 2 local dates, which would be fine to test, but… Yes, these 2 <em>things</em> this function does are what Rich Hickey would call <em class=\"sidenote-number\"><a href=\"https://www.youtube.com/watch?v=SxdOUGdseq4\">complected</a></em> <em class=\"sidenote\">If you haven’t seen this famous talk, make yourself a favour and bookmark it: <a href=\"https://www.youtube.com/watch?v=SxdOUGdseq4\">Simple Made Easy</a>. Then, when you are ready, take a cup of your best coffee, tea, mate or whatever is your poison and enjoy an hour of pure talent.</em>:</p>\n\n<blockquote>\n  <p>Okay. So there’s this really cool word called <strong>complect</strong>. I found it. I love it. It means to interleave or entwine or braid. Okay?\n…\nHaving state in your program is never simple because it has a  fundamental complecting that goes on in its artifacts. It complects  value and time. (…) Well, if every time you call that method with the same arguments, you  can get a different result, guess what happened? That complexity just  leaked right out of there (…). If the thing that’s wrapping it is stateful (…) by stateful I mean every time you ask it the same question you get a different answer, you have this complexity and it’s like poison.</p>\n\n  <p>Rich Hickey, <em class=\"cite\">Simple Made Easy</em></p>\n</blockquote>\n\n<p>So, even though it is a one-liner, we want to simplify this function. A first step would be to rule off the function that we find difficult to test:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">ageOn</span><span class=\"p\">(</span><span class=\"n\">today</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">,</span> <span class=\"n\">birthDate</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span>   \n  <span class=\"nc\">Period</span><span class=\"p\">.</span><span class=\"nf\">between</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">,</span> <span class=\"n\">today</span><span class=\"p\">).</span><span class=\"n\">years</span>\n</code></pre></div></div>\n\n<p>That one is easy to test. We say it is <em class=\"sidenote-number\">testable</em> <em class=\"sidenote\">Testability is, indeed, a software quality factor. But, curiously enough, aiming at testability enhances the quality of your software in other aspects as well.</em>. But now the user of the function needs to do what was part of the responsibilities of <code class=\"language-plaintext highlighter-rouge\">age</code> before: getting the current local date. We can recover our original <code class=\"language-plaintext highlighter-rouge\">age</code> function defining a new function like this:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"nf\">ageOn</span><span class=\"p\">(</span><span class=\"nc\">LocalDate</span><span class=\"p\">.</span><span class=\"nf\">now</span><span class=\"p\">(),</span> <span class=\"n\">birthDate</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Now we can test we correctly calculated the number of years between two dates and that that is what we actually mean by age:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testAgeOn</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span>\n    <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nf\">ageOn</span><span class=\"p\">(</span><span class=\"nc\">LocalDate</span><span class=\"p\">.</span><span class=\"nf\">of</span><span class=\"p\">(</span><span class=\"mi\">2022</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"nc\">LocalDate</span><span class=\"p\">.</span><span class=\"nf\">of</span><span class=\"p\">(</span><span class=\"mi\">2014</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">))</span>\n  <span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>What about the original <code class=\"language-plaintext highlighter-rouge\">age</code> function? How do we test that one? We still can’t. The problem with testing <code class=\"language-plaintext highlighter-rouge\">age</code> was, to begin with, that we don’t know how to test the part that gets the current local date… So, here are some questions that will make you think:</p>\n\n<ul>\n  <li>How do we test that <code class=\"language-plaintext highlighter-rouge\">LocalDate.now()</code> returns the current date?</li>\n  <li>Assuming we can trust <code class=\"language-plaintext highlighter-rouge\">LocalDate.now()</code>,  how do we test that <code class=\"language-plaintext highlighter-rouge\">age</code> uses <code class=\"language-plaintext highlighter-rouge\">LocalDate.now()</code> and not some other wrong / untrusted / untested method to get the current date?</li>\n  <li>Assuming <code class=\"language-plaintext highlighter-rouge\">age</code> correctly gets the current date somehow, how do we know it is (correctly) using <code class=\"language-plaintext highlighter-rouge\">ageOn</code>?</li>\n</ul>\n\n<p>Or, put it in another way, even with our test of <code class=\"language-plaintext highlighter-rouge\">ageOn</code>, each risk in the following list corresponds to one of the questions we were asking above:</p>\n\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">LocalDate.now()</code> could be producing the wrong date, not the current date</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">age</code> could be getting the current date using some untested method that gets it wrong</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">age</code> could be correctly getting the current date but fail to calculate the number of years between the 2 dates, as we tested <code class=\"language-plaintext highlighter-rouge\">ageOn</code> but we didn’t test wether <code class=\"language-plaintext highlighter-rouge\">age</code> is invoking it and, if so, if it is handling it the correct arguments in the correct order.</li>\n</ul>\n\n<p>Let’s start with the last two concerns here…</p>\n\n<h2 id=\"designing-for-testability\">Designing for testability</h2>\n\n<p>Let’s imagine we solve the first question/concern above <em class=\"sidenote-number\">somehow</em> <em class=\"sidenote\">More on that at the end of the article. But let’s consider it solved now.</em>. What would we need to solve the other two? We want some new version of <code class=\"language-plaintext highlighter-rouge\">age</code> that we can test, so that we solve the last question. And we want to make sure it uses what we want to get the current local date, so that the second question is also solved.</p>\n\n<p>That is, we want a function that, given the way of getting the current date of our choice and a birth date, gets it and properly calculates the number of years since the birth date to that current date. Do you see what I did there? I just used the same expression for “the way of getting the current date” and “a birth date”. Yes, they <strong>both</strong>  can be parameters:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"n\">getCurrentDate</span><span class=\"p\">:</span> <span class=\"p\">()</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">LocalDate</span><span class=\"p\">,</span> <span class=\"n\">birthDate</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span>\n  <span class=\"nc\">Period</span><span class=\"p\">.</span><span class=\"nf\">between</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">,</span> <span class=\"nf\">getCurrentDate</span><span class=\"p\">()).</span><span class=\"n\">years</span>\n</code></pre></div></div>\n\n<p>We can now test almost everything we were concerned about:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testAge</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"kd\">val</span> <span class=\"py\">getDate</span><span class=\"p\">:</span> <span class=\"p\">()</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">LocalDate</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"nc\">LocalDate</span><span class=\"p\">.</span><span class=\"nf\">of</span><span class=\"p\">(</span><span class=\"mi\">2022</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span>\n    <span class=\"mi\">7</span><span class=\"p\">,</span>\n    <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"n\">getDate</span><span class=\"p\">,</span> <span class=\"nc\">LocalDate</span><span class=\"p\">.</span><span class=\"nf\">of</span><span class=\"p\">(</span><span class=\"mi\">2014</span><span class=\"p\">,</span> <span class=\"mi\">6</span><span class=\"p\">,</span> <span class=\"mi\">30</span><span class=\"p\">))</span>\n  <span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Note that <code class=\"language-plaintext highlighter-rouge\">getDate</code> here is a function that always returns the same result. <code class=\"language-plaintext highlighter-rouge\">() -&gt; LocalDate</code> is the type of functions that have no parameters and return a <code class=\"language-plaintext highlighter-rouge\">LocalDate</code>.</p>\n\n<p>Now we can build tests where we check that <code class=\"language-plaintext highlighter-rouge\">age</code> uses whatever function we pass it as the first argument (our second concern), and that <code class=\"language-plaintext highlighter-rouge\">age</code> properly calculates the number of years between <code class=\"language-plaintext highlighter-rouge\">birthDate</code> and the date returned by <code class=\"language-plaintext highlighter-rouge\">getCurrentDate</code>.</p>\n\n<p>We say that <code class=\"language-plaintext highlighter-rouge\">age</code> depends on the function that returns the current date and that we <em>injected</em> that dependency into <code class=\"language-plaintext highlighter-rouge\">age</code>.</p>\n\n<p>This is just one particular style of dependency injection, one with which you may not be familiar. Some other styles come to mind:</p>\n<ul>\n  <li>Instead of injecting <code class=\"language-plaintext highlighter-rouge\">() -&gt; LocalDate</code> we could have injected an instance of some named type like <code class=\"language-plaintext highlighter-rouge\">interface Clock</code> that contained methods for what we wanted to acomplish:</li>\n</ul>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"n\">clock</span><span class=\"p\">:</span> <span class=\"nc\">Clock</span><span class=\"p\">,</span> <span class=\"n\">birthDate</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span>\n  <span class=\"nc\">Period</span><span class=\"p\">.</span><span class=\"nf\">between</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">,</span> <span class=\"n\">clock</span><span class=\"p\">.</span><span class=\"nf\">getCurrentDate</span><span class=\"p\">()).</span><span class=\"n\">years</span>\n</code></pre></div></div>\n\n<ul>\n  <li>Instead of injecting the function or instance as a parameter of the function <code class=\"language-plaintext highlighter-rouge\">age</code>, we could have put the <code class=\"language-plaintext highlighter-rouge\">age</code> function in a class and inject something to the class:</li>\n</ul>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class</span> <span class=\"nc\">AgeModule</span><span class=\"p\">(</span><span class=\"kd\">val</span> <span class=\"py\">clock</span><span class=\"p\">:</span> <span class=\"nc\">Clock</span><span class=\"p\">){</span>\n  <span class=\"k\">fun</span> <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span>\n    <span class=\"nc\">Period</span><span class=\"p\">.</span><span class=\"nf\">between</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">,</span> <span class=\"n\">clock</span><span class=\"p\">.</span><span class=\"nf\">getCurrentDate</span><span class=\"p\">()).</span><span class=\"n\">years</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<ul>\n  <li>Hell, if you are really into monadic stuff, we could have even used a <em class=\"sidenote-number\">reader <code class=\"language-plaintext highlighter-rouge\">Monad</code></em> <em class=\"sidenote\">I may talk about that in a future article.</em>  defining <code class=\"language-plaintext highlighter-rouge\">age</code> as a function that returns a function that given whatever it needs injected, returns the result we want:</li>\n</ul>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">age</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">:</span> <span class=\"nc\">LocalDate</span><span class=\"p\">):</span> <span class=\"p\">(</span><span class=\"nc\">Clock</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">LocalDate</span> <span class=\"p\">=</span> <span class=\"p\">{</span> <span class=\"n\">clock</span> <span class=\"p\">-&gt;</span>\n  <span class=\"nc\">Period</span><span class=\"p\">.</span><span class=\"nf\">between</span><span class=\"p\">(</span><span class=\"n\">birthDate</span><span class=\"p\">,</span> <span class=\"n\">clock</span><span class=\"p\">.</span><span class=\"nf\">getCurrentDate</span><span class=\"p\">()).</span><span class=\"n\">years</span> \n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"what-about-testing-that-localdatenow-returns-the-current-date\">What about testing that LocalDate.now() returns the current date?</h2>\n\n<p>That one, the one I left unsolved so far is the easiest one to solve. I don’t have any clue about how to properly test that, but I don’t even care. “How do I test that, then?” - you say. My answer: Don’t. Don’t test it. <em>Nada</em>. <em>Niente</em>. <em>Res de res</em>.</p>\n\n<p>This may seem silly but it is, in fact, a very important part of our testing strategy at Agilogy. You should not be testing other’s code. And by “other’s” I mean code in another module. Once you think about it, in fact, it is quite common sense:</p>\n\n<ul>\n  <li>Testing some other module software breaks modularity itself. That other module is responsible for its own stuff, not your module. If something’s wrong there, test it there, where you can fix it.</li>\n  <li>Testing some other module software is very inefficient. Either it is a module you can trust and it will have tests for that, probably much better tests than those you will come up with, or it is a module you can’t trust and then you shouldn’t be using it <em class=\"sidenote-number\">at all</em> <em class=\"sidenote\">Of course, I’m being a bit too blunt here. You may want to test some open source library does what you expect it too, for example. But I’m assuming we want to test our <code class=\"language-plaintext highlighter-rouge\">age</code> function here and my point is that testing that a dependency of <code class=\"language-plaintext highlighter-rouge\">age</code> properly does its work is out of the scope of the tests for <code class=\"language-plaintext highlighter-rouge\">age</code>.</em>.</li>\n  <li>If a module B is used by a module A and you own both, testing your module B in A doesn’t provide any safety net against changes in B. You may be working on B and breaking things without that test telling you so and you may release a version of B used by some C that was not testing it properly. Boom, you have a bug in production you could have prevented by testing B in B.</li>\n</ul>\n\n<h2 id=\"conclusions\">Conclusions</h2>\n\n<p>So I cheated you. I told you I was going to talk about testing and I ended up talking about complection, software design and dependency injection…. or didn’t I?</p>\n\n<p class=\"figcaption\"><img src=\"../assets/img/Matrix-Oracle.jpeg\" alt=\"The Oracle in the Matrix movies, explained before Resurrections - Polygon\" width=\"200px\" /></p>\n\n<p class=\"figcaption\">The Oracle, not the Oracle DB</p>\n\n<p>So we have built a simpler, better <code class=\"language-plaintext highlighter-rouge\">age</code> function. But, paraphrasing the Oracle, what’s really going to bake your noodle later on is, <a href=\"https://youtu.be/eVF4kebiks4?t=31\">would we still have reached such simple, elegant solution if I hadn’t said anything about testing?</a></p>\n\n<h2 id=\"all-the-articles-in-the-series\">All the articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-05-27-what-is-an-automated-test-again.html\">What is an automated test, again?</a></li>\n  <li><a href=\"./2022-06-17-testing-and-persistent-state.html\">Testing and persistent state</a></li>\n  <li><a href=\"./2022-07-08-testing-other-side-effects.html\">Testing other side effects</a></li>\n</ol>\n",
            "url": "https://blog.agilogy.com/2022-07-08-testing-other-side-effects.html",
            "date_published": "2022-07-08T00:00:00+02:00",
            "date_modified": "2022-07-08T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-06-17-testing-and-persistent-state.html",
            "title": "Testing and persistent state",
            "content_text": "The recipe consisted of (1) setting the initial known state, (2) executing the functionality to test, (3) collecting and asserting over results and (4) collecting and asserting over final state\n\nIn our previous post about software testing, we gave the perfect receipt to test something even in the presence of state. Armed with that, we were able to test pure functions and “functions” whose responses depend on some state. I left you with the promise of talking about getting the current time, reading or writing from files and some other nasty side effects.  We will now focus on reading from and writing to some persistent storage. Here we go.\n\nLet’s talk about state, again\n\nTake 1\n\nYou remember the silly example of our test of MemoryAdder, don’t you? Its linked up there. I wait for you just here. Done? Ok.\n\nSo, now imagine you have a database (of any kind) where you store your valuable data. A database basically keeps state for as long as you want and (probably) indexes it to allow you to query it in fancy ways. Now, let’s say you have a “function” that saves something to a database. I’m assuming something similar to an sql database here, and talking about rows, etc. It doesn’t matter, for the purpose of this article. We could be speaking of a document database and its documents instead.\n\nNote: You wouldn’t put Connection as a parameter of this function? Nice, me neither. Stay with me on this one. If I manage to remember what I’m just saying, which I probably won’t 🐠, I plan to write about dependency injection using this very example as our starting point.\n\nfun updateUserLastVisit(\n    conn: Connection, \n    userId: Long, \n    lastVisit: Instant\n): Boolean {\n  val updatedRows = \n    conn.execute(\n      \"update users set last_visit = ? where id = ?\",\n      lastVisit,\n      userId\n    )\n  return updatedRows &gt; 0\n}\n\n\nTo test this method you simply:\n\n\n  Prepare an actual database instance nobody else will use, tipically running it in the same computer the test runs in\n  Follow the recipe\n\n\nSo, let’s tryIt won’t work this time, keep reading for a better solution:\n\n// 1. Set initial state\nval userId = 23L\nval userName = \"John\"\nconn.execute(\"insert into users(id, name, last_visit), ?, ?, null\", userId, userName)\n// 2 and 3. Execute the method and assert\nval lastVisit = Instant.now()\nval wasUpdated = updateUserLastVisit(userId, lastVisit)\nassertTrue(wasUpdated)\n// 4. Collect the final state and assert\nval endState = conn.execute(\"select last_visit from users where id = ?\", userId).first()\nassertEquals(lastVisit, endState)\n\n\nNice, no? Nope. You may already know me. Sparing English not being my native tongue, when I say something I mean it. And I said, I quote, “Collect the final state”. That’s not what I did here.  Red flag! 🚩Alert! 🚨 Why? Well, I just checked the value I assumed I was modifying, I didn’t collect the (whole) end state.\n\nSide effects everywhere\n\n\n\nWhat’s the problem with that, you say? After all, some projects out there forget to test the final state and many of the ones that don’t,  check it like we did above. The problem, as you may already see, are… unintended side effects.\n\nWhat if updateLastUserVisit also updates the last_updated column? Would that be intended (and missing from our test) or unintended (and passing our test wrongly)? What if it deletes the row in some particular case? Or if it affects some other row?\n\nTake 2\n\nSo, let’s fix that step 4Only step 4, here. See the complete solution later.:\n\n// 4. Collect the final state and assert\ndata class User(userId: Long, userName: String, lastVisit: Instant) \nval endState = \n  conn.execute(\"select id,name,last_visit from users order by id\"){ \n    (i, n, lv) -&gt; \n      // oh dear, how I miss Scala's tuples here...\n      User(id, n, lv)\n  }\nassertEquals(listOf(User(userId, userName, lastVisit)), endState)\n\n\nOne intesting side benefit of checking the final state this way is that the auxiliary method we need to retrieve the final state is always the same, no matter the particular test at hand. That saves some nice hours of coding tests.\n\nBut why would we only check the users table? What about other tables? Sure, you could check absolutely all the end state if you want. I’ve done that sometimes. Just balance the effort against the probability a function supposed to use one table manipulating the data in another one.\n\nAnd what about the performance of querying all the rows in a table? This database is one you never share, remember? And the initial state it has is only the state you set it to have in the first step of our recipe, right? So, yes, you can probably query all of the rows in your database; in this example, it is just one.\n\nNow it’s done, right? Oh, you have seen it, right? No? Again, let’s do what we said, and we said “set initial state”. Inserting a single row in a database is not stting a known initial state. There may be other rows there. And, hopefully, our rewritten step 4 would detect that and our nice test would fail.\n\nTake 3\n\nSo let’s fix that as well. Final solution nowI’ll be considering this to be the good solution. Of course, it may have bugs, in which case I would greatly appreciate any feedback.:\n\n// 1. Set initial state\nval userId = 23L\nval userName = \"John\"\nconn.execute(\"delete from users\")\nconn.execute(\n  \"insert into users(id, name, last_visit), ?, ?, null\", \n  userId, \n  userName\n)\n// 2 and 3. Execute the method and assert\nval lastVisit = Instant.now()\nval wasUpdated = updateUserLastVisit(userId, lastVisit)\nassertTrue(wasUpdated)\n// 4. Collect the final state and assert\nval endState =\n  conn.execute(\"select id,name,last_visit from users order by id\"){ \n    (i, n, lv) -&gt; User(id, n, lv)\n  }\nassertEquals(listOf(User(userId, userName, lastVisit)), endState)\n\n\nNote: I’m assuming the database structure was fixed. We don’t need to create the users table when we run the test because it is something our code does not change.\n\nAn actual database instance nobody else will use?\n\nThose are the words I used. Test your functions using persistent state using “an actual database instance nobody else will use”. There are two main points here.\n\nUse the actual thing\n\nThe first one: Use an actual persistent storage. In fact, use the very same persistent storage technology you use in production. You have PostgreSQL 13.7 in production? Use a PostgreSQL 13.7 to store your tests data. Because, why not? The benefits of using the very same technology are crystal clear: there won’t be any difference that causes false positives (code that fails in production but passes all the tests ) or false negatives (code that works perfectly well in production but fails to pass the tests).\n\nI won’t go into details, at least not now, but you can use Docker and other virtualization solutions to run such infrastruture. Just, please, don’t make all developers in your team install a ton of software in order to run all tests in the repo.\n\nDon’t share your persistent state\n\nThe other part of that suggestion is about not sharing the state with anyone else. I already hinted about some of the problems I’ve seen when sharing the persistent state used in tests. You don’t want your tests behaviour to depend on whether someone else actions. You want them to always give the same results. Known initial state, exercise the program, collect results and assert, collect final state and assert.\n\nWhat about the tests in your test suite sharing the persistent state? No! Nein! Ni parlar-ne!\n\nGollum doesn’t want to share its preciousss… persistent state. Me neither.\n\n\n\nYou are probably using the same database for all your tests. But you can’t share state between tests. You need to be able to run a single test. You’ll maintain tests and you may remove some of them, or add one test in between existing tests. You can’t afford the result of one test depending on the state left by other tests executed before it. What do yo do? Known initial state, exercise… You know. I mean, following the recipe I gave in the last article, you guarantee each test starts with a known state, no matter what other tests have done before.\n\nDon’t simply take whatever initial state you find while trying to cleanup afterwards.\n\nFor some reason, I’ve seen cases where the recipe is different. Instead of setting a known initial state, tests make the effort to leave things as they found them: they clear whatever state they stored during the test. That tries to solve the same problem of one test affecting other tests. But it is flawled. To begin with, a simple failure to properly clean the state could trigger a failure (or worse, a false positive) in an unrelated test of the same suite. Good luck finding out what just happened. On the other hand, whenever a test fails, sometimes it is very nice to see the end state there for you to query. You are welcome.\n\nConcurrency and persistent state in tests\n\n\nhttps://xkcd.com/303/\n\nAnd… what about concurrency? I don’t know yours, but my laptop is much, much powerful than any of the nodes in the production environment that run the code I write with it. Heck, it has more cores than I can remember and long are the days when I could drink I coffee while my previous laptop struggled to compile a big Scala project.\n\nBut concurrency is not a trival one to solve, when you have persistent state in tests. Specially not as an afterthought.\n\nSo far, we avoided others (developers or the CI server) affecting our builds, by running our persistent storage (e.g. our PostgreSQL) in the same computer where the tests run. And we had the certainty that our tests run in a known state because we set that state ourselves: no test trusted whatever state it found there (from previous test executions or whatever) an it set the wanted, known initial state itself. But now, we may have several concurrent tests doing the very same. So they will affect each other.\n\nThe solution to this problem usually is to just not run tests concurrently. Let that small chat app eat that CPU as though there were no tomorrow.\n\nEvery other solution depends on the technology you use. For the sake of giving some hint at it, assuming you know a bit about relational databases, we could make each test generate a random unique identifier and, then, create and use a schema or a table with such name as part of the name. Of course, we would need to be able to create such schemas or tables from our test code.\n\n// 1. Set initial state\nval userId = 23L\nval userName = \"John\"\nval executionId = UUID.randomUUID()\nconn.execute(\"create users-$executionId(...)\")\nconn.execute(\n  \"insert into users-$executionId(id, name, last_visit), ?, ?, null\", \n  userId, \n  userName\n)\n\n\nConclusions\n\nSo we are now equiped with the perfect recipe to run tests that use persistent state without any hassle. We played a bit with it and saw what we actually mean when we say “set the initial state” and “collect and assert the final state”. We also saw how to run tests concurrently to take advantage of the large number of cores we have in our laptops nowadays.\n\nBut many open questions from the first article remain unanswered. What about testing a function that gets the current time? One that uses random values? What about something that sends HTTP requests to the world?\n\nMore on all of that to come. See you soon!\n\nAll the articles in the series\n\n\n  What is an automated test, again?\n  Testing and persistent state\n  Testing other side effects\n\n",
            "content_html": "<p class=\"marginnote\">The recipe consisted of (1) setting the initial known state, (2) executing the functionality to test, (3) collecting and asserting over results and (4) collecting and asserting over final state</p>\n\n<p>In <a href=\"/2022-05-27-what-is-an-automated-test-again.html\">our previous post about software testing</a>, we gave the perfect receipt to test something even in the presence of state. Armed with that, we were able to test pure functions and “functions” whose responses depend on some state. I left you with the promise of talking about getting the current time, reading or writing from files and some other nasty side effects.  We will now focus on reading from and writing to some persistent storage. Here we go.</p>\n\n<h2 id=\"lets-talk-about-state-again\">Let’s talk about state, again</h2>\n\n<h3 id=\"take-1\">Take 1</h3>\n\n<p>You remember the silly example of our test of <code class=\"language-plaintext highlighter-rouge\">MemoryAdder</code>, <em class=\"sidenote-number\">don’t you?</em> <em class=\"sidenote\">Its linked up there. I wait for you just here. Done? Ok.</em></p>\n\n<p>So, now imagine you have a database (of any kind) where you store your valuable data. A database basically keeps state for as long as you want and (probably) indexes it to allow you to query it in fancy ways. Now, let’s say you have a “function” that saves something to a <em class=\"sidenote-number\">database</em>. <em class=\"sidenote\">I’m assuming something similar to an sql database here, and talking about rows, etc. It doesn’t matter, for the purpose of this article. We could be speaking of a document database and its documents instead.</em></p>\n\n<p><em class=\"marginnote\">Note: You wouldn’t put <code class=\"language-plaintext highlighter-rouge\">Connection</code> as a parameter of this function? Nice, me neither. Stay with me on this one. If I manage to remember what I’m just saying, which I probably won’t 🐠, I plan to write about dependency injection using this very example as our starting point.</em></p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">updateUserLastVisit</span><span class=\"p\">(</span>\n    <span class=\"n\">conn</span><span class=\"p\">:</span> <span class=\"nc\">Connection</span><span class=\"p\">,</span> \n    <span class=\"n\">userId</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">,</span> \n    <span class=\"n\">lastVisit</span><span class=\"p\">:</span> <span class=\"nc\">Instant</span>\n<span class=\"p\">):</span> <span class=\"nc\">Boolean</span> <span class=\"p\">{</span>\n  <span class=\"kd\">val</span> <span class=\"py\">updatedRows</span> <span class=\"p\">=</span> \n    <span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span>\n      <span class=\"s\">\"update users set last_visit = ? where id = ?\"</span><span class=\"p\">,</span>\n      <span class=\"n\">lastVisit</span><span class=\"p\">,</span>\n      <span class=\"n\">userId</span>\n    <span class=\"p\">)</span>\n  <span class=\"k\">return</span> <span class=\"n\">updatedRows</span> <span class=\"p\">&gt;</span> <span class=\"mi\">0</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>To test this method you simply:</p>\n\n<ol>\n  <li>Prepare an actual database instance nobody else will use, tipically running it in the same computer the test runs in</li>\n  <li>Follow the recipe</li>\n</ol>\n\n<p>So, let’s <em class=\"sidenote-number\">try</em><em class=\"sidenote\">It won’t work this time, keep reading for a better solution</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// 1. Set initial state</span>\n<span class=\"kd\">val</span> <span class=\"py\">userId</span> <span class=\"p\">=</span> <span class=\"mi\">23L</span>\n<span class=\"kd\">val</span> <span class=\"py\">userName</span> <span class=\"p\">=</span> <span class=\"s\">\"John\"</span>\n<span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"insert into users(id, name, last_visit), ?, ?, null\"</span><span class=\"p\">,</span> <span class=\"n\">userId</span><span class=\"p\">,</span> <span class=\"n\">userName</span><span class=\"p\">)</span>\n<span class=\"c1\">// 2 and 3. Execute the method and assert</span>\n<span class=\"kd\">val</span> <span class=\"py\">lastVisit</span> <span class=\"p\">=</span> <span class=\"nc\">Instant</span><span class=\"p\">.</span><span class=\"nf\">now</span><span class=\"p\">()</span>\n<span class=\"kd\">val</span> <span class=\"py\">wasUpdated</span> <span class=\"p\">=</span> <span class=\"nf\">updateUserLastVisit</span><span class=\"p\">(</span><span class=\"n\">userId</span><span class=\"p\">,</span> <span class=\"n\">lastVisit</span><span class=\"p\">)</span>\n<span class=\"nf\">assertTrue</span><span class=\"p\">(</span><span class=\"n\">wasUpdated</span><span class=\"p\">)</span>\n<span class=\"c1\">// 4. Collect the final state and assert</span>\n<span class=\"kd\">val</span> <span class=\"py\">endState</span> <span class=\"p\">=</span> <span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"select last_visit from users where id = ?\"</span><span class=\"p\">,</span> <span class=\"n\">userId</span><span class=\"p\">).</span><span class=\"nf\">first</span><span class=\"p\">()</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"n\">lastVisit</span><span class=\"p\">,</span> <span class=\"n\">endState</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Nice, no? Nope. You may already know me. Sparing English not being my native tongue, when I say something I mean it. And I said, I quote, “Collect the final state”. That’s not what I did here.  Red flag! 🚩Alert! 🚨 Why? Well, I just checked the value I assumed I was modifying, I didn’t collect the (whole) end state.</p>\n\n<p class=\"figcaption\">Side effects everywhere</p>\n\n<p><img src=\"../assets/side%20effects.gif\" alt=\"side effects\" /></p>\n\n<p>What’s the problem with that, you say? After all, some projects out there forget to test the final state and many of the ones that don’t,  check it like we did above. The problem, as you may already see, are… unintended side effects.</p>\n\n<p>What if <code class=\"language-plaintext highlighter-rouge\">updateLastUserVisit</code> also updates the <code class=\"language-plaintext highlighter-rouge\">last_updated</code> column? Would that be intended (and missing from our test) or unintended (and passing our test wrongly)? What if it deletes the row in some particular case? Or if it affects some other row?</p>\n\n<h3 id=\"take-2\">Take 2</h3>\n\n<p>So, let’s fix that <em class=\"sidenote-number\">step 4</em><em class=\"sidenote\">Only step 4, here. See the complete solution later.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// 4. Collect the final state and assert</span>\n<span class=\"kd\">data class</span> <span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">userId</span><span class=\"p\">:</span> <span class=\"nc\">Long</span><span class=\"p\">,</span> <span class=\"n\">userName</span><span class=\"p\">:</span> <span class=\"nc\">String</span><span class=\"p\">,</span> <span class=\"n\">lastVisit</span><span class=\"p\">:</span> <span class=\"nc\">Instant</span><span class=\"p\">)</span> \n<span class=\"kd\">val</span> <span class=\"py\">endState</span> <span class=\"p\">=</span> \n  <span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"select id,name,last_visit from users order by id\"</span><span class=\"p\">){</span> \n    <span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">lv</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> \n      <span class=\"c1\">// oh dear, how I miss Scala's tuples here...</span>\n      <span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">id</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">lv</span><span class=\"p\">)</span>\n  <span class=\"p\">}</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">userId</span><span class=\"p\">,</span> <span class=\"n\">userName</span><span class=\"p\">,</span> <span class=\"n\">lastVisit</span><span class=\"p\">)),</span> <span class=\"n\">endState</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>One intesting side benefit of checking the final state this way is that the auxiliary method we need to retrieve the final state is always the same, no matter the particular test at hand. That saves some nice hours of coding tests.</p>\n\n<p>But why would we only check the users table? What about other tables? Sure, you could check absolutely all the end state if you want. I’ve done that sometimes. Just balance the effort against the probability a function supposed to use one table manipulating the data in another one.</p>\n\n<p>And what about the performance of querying all the rows in a table? This database is one you never share, remember? And the initial state it has is only the state you set it to have in the first step of our recipe, right? So, yes, you can probably query <strong>all of</strong> the rows in your database; in this example, it is just one.</p>\n\n<p>Now it’s done, right? Oh, you have seen it, right? No? Again, let’s do what we said, and we said “set initial state”. Inserting a single row in a database is not stting a known initial state. There may be other rows there. And, hopefully, our rewritten step 4 would detect that and our nice test would fail.</p>\n\n<h3 id=\"take-3\">Take 3</h3>\n\n<p>So let’s fix that as well. <em class=\"sidenote-number\">Final solution now</em><em class=\"sidenote\">I’ll be considering this to be the good solution. Of course, it may have bugs, in which case I would greatly appreciate any feedback.</em>:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// 1. Set initial state</span>\n<span class=\"kd\">val</span> <span class=\"py\">userId</span> <span class=\"p\">=</span> <span class=\"mi\">23L</span>\n<span class=\"kd\">val</span> <span class=\"py\">userName</span> <span class=\"p\">=</span> <span class=\"s\">\"John\"</span>\n<span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"delete from users\"</span><span class=\"p\">)</span>\n<span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span>\n  <span class=\"s\">\"insert into users(id, name, last_visit), ?, ?, null\"</span><span class=\"p\">,</span> \n  <span class=\"n\">userId</span><span class=\"p\">,</span> \n  <span class=\"n\">userName</span>\n<span class=\"p\">)</span>\n<span class=\"c1\">// 2 and 3. Execute the method and assert</span>\n<span class=\"kd\">val</span> <span class=\"py\">lastVisit</span> <span class=\"p\">=</span> <span class=\"nc\">Instant</span><span class=\"p\">.</span><span class=\"nf\">now</span><span class=\"p\">()</span>\n<span class=\"kd\">val</span> <span class=\"py\">wasUpdated</span> <span class=\"p\">=</span> <span class=\"nf\">updateUserLastVisit</span><span class=\"p\">(</span><span class=\"n\">userId</span><span class=\"p\">,</span> <span class=\"n\">lastVisit</span><span class=\"p\">)</span>\n<span class=\"nf\">assertTrue</span><span class=\"p\">(</span><span class=\"n\">wasUpdated</span><span class=\"p\">)</span>\n<span class=\"c1\">// 4. Collect the final state and assert</span>\n<span class=\"kd\">val</span> <span class=\"py\">endState</span> <span class=\"p\">=</span>\n  <span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"select id,name,last_visit from users order by id\"</span><span class=\"p\">){</span> \n    <span class=\"p\">(</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">lv</span><span class=\"p\">)</span> <span class=\"p\">-&gt;</span> <span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">id</span><span class=\"p\">,</span> <span class=\"n\">n</span><span class=\"p\">,</span> <span class=\"n\">lv</span><span class=\"p\">)</span>\n  <span class=\"p\">}</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"nf\">listOf</span><span class=\"p\">(</span><span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">userId</span><span class=\"p\">,</span> <span class=\"n\">userName</span><span class=\"p\">,</span> <span class=\"n\">lastVisit</span><span class=\"p\">)),</span> <span class=\"n\">endState</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Note: I’m assuming the database structure was fixed. We don’t need to create the users table when we run the test because it is something our code does not change.</p>\n\n<h2 id=\"an-actual-database-instance-nobody-else-will-use\">An actual database instance nobody else will use?</h2>\n\n<p>Those are the words I used. Test your functions using persistent state using “an actual database instance nobody else will use”. There are two main points here.</p>\n\n<h3 id=\"use-the-actual-thing\">Use the actual thing</h3>\n\n<p>The first one: Use an actual persistent storage. In fact, use <strong>the very same persistent storage technology you use in production</strong>. You have PostgreSQL 13.7 in production? Use a PostgreSQL 13.7 to store your tests data. Because, why not? The benefits of using the very same technology are crystal clear: there won’t be any difference that causes false positives (code that fails in production but passes all the tests ) or false negatives (code that works perfectly well in production but fails to pass the tests).</p>\n\n<p>I won’t go into details, at least not now, but you can use Docker and other virtualization solutions to run such infrastruture. Just, please, don’t make all developers in your team install a ton of software in order to run all tests in the repo.</p>\n\n<h3 id=\"dont-share-your-persistent-state\">Don’t share your persistent state</h3>\n\n<p>The other part of that suggestion is about not sharing the state with anyone else. I already hinted about some of the problems I’ve seen when sharing the persistent state used in tests. You don’t want your tests behaviour to depend on whether someone else actions. You want them to always give the same results. Known initial state, exercise the program, collect results and assert, collect final state and assert.</p>\n\n<p>What about the tests in your test suite sharing the persistent state? No! Nein! Ni parlar-ne!</p>\n\n<p class=\"figcaption\">Gollum doesn’t want to share its preciousss… persistent state. Me neither.</p>\n\n<p><img src=\"../assets/its-mine-lotr.png\" alt=\"Its Mine Lotr GIF - Its Mine Lotr Golem - Discover &amp; Share GIFs\" /></p>\n\n<p>You are probably using the same database for all your tests. But you can’t share state between tests. You need to be able to run a single test. You’ll maintain tests and you may remove some of them, or add one test in between existing tests. You can’t afford the result of one test depending on the state left by other tests executed before it. What do yo do? Known initial state, exercise… You know. I mean, following the recipe I gave in the last article, you guarantee each test starts with a known state, no matter what other tests have done before.</p>\n\n<p class=\"marginnote\">Don’t simply take whatever initial state you find while trying to cleanup afterwards.</p>\n\n<p>For some reason, I’ve seen cases where the recipe is different. Instead of setting a known initial state, tests make the effort to leave things as they found them: they clear whatever state they stored during the test. That tries to solve the same problem of one test affecting other tests. But it is flawled. To begin with, a simple failure to properly clean the state could trigger a failure (or worse, a false positive) in an unrelated test of the same suite. Good luck finding out what just happened. On the other hand, whenever a test fails, sometimes it is very nice to see the end state there for you to query. You are welcome.</p>\n\n<h2 id=\"concurrency-and-persistent-state-in-tests\">Concurrency and persistent state in tests</h2>\n\n<p class=\"figcaption\"><img src=\"../assets/img/compiling.png\" alt=\"Compiling\" height=\"250px\" width=\"250px\" /></p>\n<p class=\"figcaption\"><a href=\"\">https://xkcd.com/303/</a></p>\n\n<p>And… what about concurrency? I don’t know yours, but my laptop is much, much powerful than any of the nodes in the production environment that run the code I write with it. Heck, it has more cores than I can remember and long are the days when I could drink I coffee while my previous laptop <a href=\"https://xkcd.com/303/\">struggled to compile a big Scala project</a>.</p>\n\n<p>But concurrency is not a trival one to solve, when you have persistent state in tests. Specially not as an afterthought.</p>\n\n<p>So far, we avoided others (developers or the CI server) affecting our builds, by running our persistent storage (e.g. our PostgreSQL) in the same computer where the tests run. And we had the certainty that our tests run in a known state because we set that state ourselves: no test trusted whatever state it found there (from previous test executions or whatever) an it set the wanted, known initial state itself. But now, we may have several concurrent tests doing the very same. So they will affect each other.</p>\n\n<p>The solution to this problem usually is to just not run tests concurrently. Let <a href=\"https://twitter.com/leonroy/status/879710732685914112?s=20&amp;t=tT9A9Xom1JR4i1EkjMdPJw\">that small chat app eat that CPU as though there were no tomorrow</a>.</p>\n\n<p>Every other solution depends on the technology you use. For the sake of giving some hint at it, assuming you know a bit about relational databases, we could make each test generate a random unique identifier and, then, create and use a schema or a table with such name as part of the name. Of course, we would need to be able to create such schemas or tables from our test code.</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// 1. Set initial state</span>\n<span class=\"kd\">val</span> <span class=\"py\">userId</span> <span class=\"p\">=</span> <span class=\"mi\">23L</span>\n<span class=\"kd\">val</span> <span class=\"py\">userName</span> <span class=\"p\">=</span> <span class=\"s\">\"John\"</span>\n<span class=\"kd\">val</span> <span class=\"py\">executionId</span> <span class=\"p\">=</span> <span class=\"nc\">UUID</span><span class=\"p\">.</span><span class=\"nf\">randomUUID</span><span class=\"p\">()</span>\n<span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"s\">\"create users-$executionId(...)\"</span><span class=\"p\">)</span>\n<span class=\"n\">conn</span><span class=\"p\">.</span><span class=\"nf\">execute</span><span class=\"p\">(</span>\n  <span class=\"s\">\"insert into users-$executionId(id, name, last_visit), ?, ?, null\"</span><span class=\"p\">,</span> \n  <span class=\"n\">userId</span><span class=\"p\">,</span> \n  <span class=\"n\">userName</span>\n<span class=\"p\">)</span>\n</code></pre></div></div>\n\n<h2 id=\"conclusions\">Conclusions</h2>\n\n<p>So we are now equiped with the perfect recipe to run tests that use persistent state without any hassle. We played a bit with it and saw what we actually mean when we say “set the initial state” and “collect and assert the final state”. We also saw how to run tests concurrently to take advantage of the large number of cores we have in our laptops nowadays.</p>\n\n<p>But many open questions from the first article remain unanswered. What about testing a function that gets the current time? One that uses random values? What about something that sends HTTP requests to the world?</p>\n\n<p>More on all of that to come. See you soon!</p>\n\n<h2 id=\"all-the-articles-in-the-series\">All the articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-05-27-what-is-an-automated-test-again.html\">What is an automated test, again?</a></li>\n  <li><a href=\"./2022-06-17-testing-and-persistent-state.html\">Testing and persistent state</a></li>\n  <li><a href=\"./2022-07-08-testing-other-side-effects.html\">Testing other side effects</a></li>\n</ol>\n",
            "url": "https://blog.agilogy.com/2022-06-17-testing-and-persistent-state.html",
            "date_published": "2022-06-17T00:00:00+02:00",
            "date_modified": "2022-06-17T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        },
        
    
      
        
        
        {
            "id": "https://blog.agilogy.com/2022-05-27-what-is-an-automated-test-again.html",
            "title": "What is an automated test, again?",
            "content_text": "Back in the day, we used to just hack some code, run it, and give it some inputs to see whether we acomplished what we wanted or not. Naturally, this is no longer the case, and nowadays we use automated tests to automatically check our code behaves as expected.\n\n\n\n\n\nI know, I know… But let’s revisit how do we test a simple program. Bear with me, please, as many people and teams just skiped that part of the explanation when talking about tests to their juniors.\n\nBasic unit testing\n\nLet’s imagine we have a simple function like this one:\n\nfun sum(a: Int, b: Int): Int\n\n\nA classical test suite is a collection of test scenarios each of which tests one combination of inputs to the function following these simple steps:\n\n\n  Invoke the function with input values defined in the test\n  Collect the result returned by the function and assert Asserting here means that you check the value is what you expected or else make the test fail it is what we expect.\n\n\nLike this:\n\n@Test\nfun testSumPositives() {\n  assertEquals(23, sum(21, 2))\n}\n\n@Test\nfun testSumPositiveAndNegative() {\n  assertEquals(19, sum(21, -2))\n}\n\n\nYou probably already know, but just in case: assertEquals takes the expected value as the first argument and the actual value, the one your code actually returned, as the second argument. Please, please, stop doing the order of those arguments wrong, as failing tests are really confusing when they are switched.\n\nEasy peasy! Isn’t it?\n\nNot so basic unit testing: Side effects everywhere!\n\nBut, what about impure “functions”? You know I love pure functions, right?\n\nFunctional programmer with an agile background\n\n\n\nWhat happens when you want to test something that is not a pure function?\n\nTesting non total “functions”\n\nLet’s start with totality, as that one is easy. A function is total when it returns a result (of the specified type) for every possible input. When a function is not total, you can do 2 different things in your tests:\n\n\n  Avoid testing inputs for which the function is not defined\n  Test the function fails properly when it is not defined\n\n\nThe first approach is valid when you don’t care about such cases. Don’t look at me, I always care, because I don’t want my types to lie to me. But you may not care and that’s a topic for another post.\n\nThe second one is doable by hand with try ... catch, although every testing library I know offers some higher level solution:\n\nfun div(a: Int, b: Int): Int = a / b\n\n@Test\nfun divBy0() {\n  val t = assertThrows&lt;ArithmeticException&gt; { div(23, 0) }\n  assertEquals(\"/ by zero\", t.message)\n}\n\n\nThere is still a catch. Your function may be non total without you, the poor programming, knowing about it. But if you are lucky enough that one of your tests discovers such a hole in your function, the test library will usually deal with it, showing the thrown exception as a particular case of a test failure:\n\n@Test\nfun failingTestDueToUnexpectedException() {\n  assertTrue(div(23, 0) &lt; 23)\n}\n\n\nTesting non deterministic “function”: State\n\nLike you know, a “function” is not deterministic when, for the same inputs, it may return different outputs. One very good reason for it to not return the same input is having state. If you query the amount in your savings bank account you don’t expect it to be always the same. You expect the result to depend on the state of what is being test.\n\nTake this simple adder:\n\nclass MemoryAdder(){\n  var lastInput: Int\n  fun add(a: Int): Int = (lastInput + a).also{ lastInput = a }\n}\n\n\nHow do we test the add method? As the result depends on the state of the MemoryAdder, we need a new algorithm:\n\n  Set an initial state defined in the test\n  Invoke the function with input values defined in the test\n  Collect the result returned by the function and assert it is what we expect\n  Collect the final state of the system under test and assert it is what we expect\n\n\nNote that many developers and teams forget step number 4. If you don’t check the final state of the system under test, such system can behave as you expected in your test and, still, fail to end in the state you expect it to have at the end.\n\nOther teams, though, forget about step number 1. If your system uses any kind of persistent state, that means you are testing it with whatever is present in such storage when you launch the test. And that grants you some headache whenever that state is not the one you expected. That can be caused by some other test changing some state you didn’t anticipate it would change, you or some other developer running tests in concurrency with your test execution, someone doing manual tests using the same database you expected no one to use… You know. I’ve seen things you people wouldn’t believe.\n\nBut I digress… Let’s apply our new algorithm:\n\n// 1. Set initial state:\nval ma = MemoryAdder()\nma.add(23)\n// 2 and 3. Execute the method and assert\nassertEquals(25, ma.add(2))\n// 4. Collect the final state and assert\nassertEquals(2, ma.lastInput)\n\n\nGood job! Done, right? Not quite yet…\n\nWhat if your function is not deterministic because… it generates random values? Or just because it uses the current system time? And what about it doing some I/O, like reading from the file system, a database or a socket? Even more, what about procedures generating some kind of externally observable effect, like writing to the file system or a databse? 🙀 Yes, it’s a cat screaming. Yes, coming from Scala, that pun is indeed intended. I didn’t find any arrow screaming, sorry about that.\n\nLet’s talk about these dreaded scenarios in our next post about software testing!\n\nI hope you enjoyed this one. See you soon!\n\nAll the articles in the series\n\n\n  What is an automated test, again?\n  Testing and persistent state\n  Testing other side effects\n\n",
            "content_html": "<p>Back in the day, we used to just hack some code, run it, and give it some inputs to see whether we acomplished what we wanted or not. Naturally, this is no longer the case, and nowadays we use automated tests to automatically check our code behaves as expected.</p>\n\n<!--more-->\n\n<p><img src=\"../assets/bored-boring.gif\" alt=\"Bored Boring GIF - Bored Boring Ntc - Descubre &amp; Comparte GIFs\" /></p>\n\n<p>I know, I know… But let’s revisit how do we test a simple program. Bear with me, please, as many people and teams just skiped that part of the explanation when talking about tests to their juniors.</p>\n\n<h2 id=\"basic-unit-testing\">Basic unit testing</h2>\n\n<p>Let’s imagine we have a simple function like this one:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">):</span> <span class=\"nc\">Int</span>\n</code></pre></div></div>\n\n<p>A classical <strong>test suite</strong> is a collection of <strong>test scenarios</strong> each of which tests one combination of inputs to the function following these simple steps:</p>\n\n<ol>\n  <li>Invoke the function with input values defined in the test</li>\n  <li>Collect the result returned by the function and <em class=\"sidenote-number\">assert</em> <em class=\"sidenote\"><strong>Asserting</strong> here means that you check the value is what you expected or else make the test fail</em> it is what we expect.</li>\n</ol>\n\n<p>Like this:</p>\n\n<div data-runnablein=\"junit\" class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testSumPositives</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"mi\">21</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">))</span>\n<span class=\"p\">}</span>\n\n<span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">testSumPositiveAndNegative</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">19</span><span class=\"p\">,</span> <span class=\"nf\">sum</span><span class=\"p\">(</span><span class=\"mi\">21</span><span class=\"p\">,</span> <span class=\"p\">-</span><span class=\"mi\">2</span><span class=\"p\">))</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>You probably already know, but just in case: <code class=\"language-plaintext highlighter-rouge\">assertEquals</code> takes the <strong>expected</strong> value as the <strong>first</strong> argument and the <strong>actual</strong> value, the one your code actually returned, as the <strong>second</strong> argument. Please, please, stop doing the order of those arguments wrong, as failing tests are really confusing when they are switched.</p>\n\n<p>Easy peasy! Isn’t it?</p>\n\n<h2 id=\"not-so-basic-unit-testing-side-effects-everywhere\">Not so basic unit testing: Side effects everywhere!</h2>\n\n<p>But, what about impure “functions”? You know I love pure functions, right?</p>\n\n<p class=\"figcaption\"><strong>Functional programmer</strong> with an agile background</p>\n\n<p><img src=\"../assets/agile_jordi.jpg\" alt=\"agile_jordi profile as a functional programmer\" /></p>\n\n<p>What happens when you want to test something that is not a pure function?</p>\n\n<h3 id=\"testing-non-total-functions\">Testing non total “functions”</h3>\n\n<p>Let’s start with totality, as that one is easy. A function is total when it returns a result (of the specified type) for every possible input. When a function is not total, you can do 2 different things in your tests:</p>\n\n<ol>\n  <li>Avoid testing inputs for which the function is not defined</li>\n  <li>Test the function fails properly when it is not defined</li>\n</ol>\n\n<p>The first approach is valid when you don’t care about such cases. Don’t look at me, I always care, because I don’t want my types to lie to me. But you may not care and that’s a topic for another post.</p>\n\n<p>The second one is doable by hand with <code class=\"language-plaintext highlighter-rouge\">try ... catch</code>, although every testing library I know offers some higher level solution:</p>\n\n<div data-runnablein=\"junit\" class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"k\">fun</span> <span class=\"nf\">div</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"n\">a</span> <span class=\"p\">/</span> <span class=\"n\">b</span>\n\n<span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">divBy0</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"kd\">val</span> <span class=\"py\">t</span> <span class=\"p\">=</span> <span class=\"n\">assertThrows</span><span class=\"p\">&lt;</span><span class=\"nc\">ArithmeticException</span><span class=\"p\">&gt;</span> <span class=\"p\">{</span> <span class=\"nf\">div</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"p\">}</span>\n  <span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"s\">\"/ by zero\"</span><span class=\"p\">,</span> <span class=\"n\">t</span><span class=\"p\">.</span><span class=\"n\">message</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>There is still a catch. Your function may be non total without you, the poor programming, knowing about it. But if you are lucky enough that one of your tests discovers such a hole in your function, the test library will usually deal with it, showing the thrown exception as a particular case of a test failure:</p>\n\n<div data-runnablein=\"junit\" class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nd\">@Test</span>\n<span class=\"k\">fun</span> <span class=\"nf\">failingTestDueToUnexpectedException</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"nf\">assertTrue</span><span class=\"p\">(</span><span class=\"nf\">div</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">)</span> <span class=\"p\">&lt;</span> <span class=\"mi\">23</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"testing-non-deterministic-function-state\">Testing non deterministic “function”: State</h3>\n\n<p>Like you know, a “function” is not deterministic when, for the same inputs, it may return different outputs. One very good reason for it to not return the same input is having state. If you query the amount in your savings bank account you don’t expect it to be always the same. You expect the result to depend on the state of what is being test.</p>\n\n<p>Take this simple adder:</p>\n\n<div class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"kd\">class</span> <span class=\"nc\">MemoryAdder</span><span class=\"p\">(){</span>\n  <span class=\"kd\">var</span> <span class=\"py\">lastInput</span><span class=\"p\">:</span> <span class=\"nc\">Int</span>\n  <span class=\"k\">fun</span> <span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"p\">:</span> <span class=\"nc\">Int</span><span class=\"p\">):</span> <span class=\"nc\">Int</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"n\">lastInput</span> <span class=\"p\">+</span> <span class=\"n\">a</span><span class=\"p\">).</span><span class=\"nf\">also</span><span class=\"p\">{</span> <span class=\"n\">lastInput</span> <span class=\"p\">=</span> <span class=\"n\">a</span> <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>How do we test the <code class=\"language-plaintext highlighter-rouge\">add</code> method? As the result depends on the state of the <code class=\"language-plaintext highlighter-rouge\">MemoryAdder</code>, we need a new algorithm:</p>\n<ol>\n  <li>Set an initial state defined in the test</li>\n  <li>Invoke the function with input values defined in the test</li>\n  <li>Collect the result returned by the function and <strong>assert</strong> it is what we expect</li>\n  <li>Collect the final state of the system under test and <strong>assert</strong> it is what we expect</li>\n</ol>\n\n<p>Note that many developers and teams forget step number 4. If you don’t check the final state of the system under test, such system can behave as you expected in your test and, still, fail to end in the state you expect it to have at the end.</p>\n\n<p>Other teams, though, forget about step number 1. If your system uses any kind of persistent state, that means you are testing it with whatever is present in such storage when you launch the test. And that grants you some headache whenever that state is not the one you expected. That can be caused by some other test changing some state you didn’t anticipate it would change, you or some other developer running tests in concurrency with your test execution, someone doing manual tests using the same database you expected no one to use… You know. I’ve seen things you people wouldn’t believe.</p>\n\n<p>But I digress… Let’s apply our new algorithm:</p>\n\n<div data-runnablein=\"junit\" class=\"language-kotlin highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// 1. Set initial state:</span>\n<span class=\"kd\">val</span> <span class=\"py\">ma</span> <span class=\"p\">=</span> <span class=\"nc\">MemoryAdder</span><span class=\"p\">()</span>\n<span class=\"n\">ma</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"mi\">23</span><span class=\"p\">)</span>\n<span class=\"c1\">// 2 and 3. Execute the method and assert</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">25</span><span class=\"p\">,</span> <span class=\"n\">ma</span><span class=\"p\">.</span><span class=\"nf\">add</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">))</span>\n<span class=\"c1\">// 4. Collect the final state and assert</span>\n<span class=\"nf\">assertEquals</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"n\">ma</span><span class=\"p\">.</span><span class=\"n\">lastInput</span><span class=\"p\">)</span>\n</code></pre></div></div>\n\n<p>Good job! Done, right? Not quite yet…</p>\n\n<p>What if your function is not deterministic because… it generates random values? Or just because it uses the current system time? And what about it doing some I/O, like reading from the file system, a database or a socket? Even more, what about procedures generating some kind of externally observable effect, like <strong>writing</strong> to the file system or a databse? <em class=\"sidenote-number\">🙀</em> <em class=\"sidenote\">Yes, it’s a <strong>cat</strong> screaming. Yes, coming from Scala, that pun is indeed intended. I didn’t find any arrow screaming, sorry about that.</em></p>\n\n<p>Let’s talk about these dreaded scenarios in our next post about software testing!</p>\n\n<p>I hope you enjoyed this one. See you soon!</p>\n\n<h2 id=\"all-the-articles-in-the-series\">All the articles in the series</h2>\n\n<ol>\n  <li><a href=\"./2022-05-27-what-is-an-automated-test-again.html\">What is an automated test, again?</a></li>\n  <li><a href=\"./2022-06-17-testing-and-persistent-state.html\">Testing and persistent state</a></li>\n  <li><a href=\"./2022-07-08-testing-other-side-effects.html\">Testing other side effects</a></li>\n</ol>\n",
            "url": "https://blog.agilogy.com/2022-05-27-what-is-an-automated-test-again.html",
            "date_published": "2022-05-27T00:00:00+02:00",
            "date_modified": "2022-05-27T00:00:00+02:00",
            "author": {
                "name": "Jordi Pradel"
            }
        }
        
    
    ]
}