<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Nicolas Comet on Medium]]></title>
        <description><![CDATA[Stories by Nicolas Comet on Medium]]></description>
        <link>https://medium.com/@nicolas.comet?source=rss-240735a14de4------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*mFd9YGG152hOKnOT5itijg.jpeg</url>
            <title>Stories by Nicolas Comet on Medium</title>
            <link>https://medium.com/@nicolas.comet?source=rss-240735a14de4------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 15:21:22 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@nicolas.comet/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Go & TestContainers]]></title>
            <link>https://medium.com/@nicolas.comet/go-testcontainers-4b5399b849d9?source=rss-240735a14de4------2</link>
            <guid isPermaLink="false">https://medium.com/p/4b5399b849d9</guid>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[go]]></category>
            <category><![CDATA[test]]></category>
            <category><![CDATA[golang]]></category>
            <dc:creator><![CDATA[Nicolas Comet]]></dc:creator>
            <pubDate>Mon, 02 May 2022 16:01:47 GMT</pubDate>
            <atom:updated>2022-05-02T16:34:27.226Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NjXzaw15-2QPs5dHRW9fmg.png" /></figure><p>I don’t think you still need to be convinced of the need of TestContainers when you write Unit Tests. There are plenty of good articles that explain why it should be done, for instance when testing against a DB, or a message broker. In short, in hexagonal architecture, providing your adapters with the real world implementation. My favorite article, that truly made me understand it, was from <a href="https://phauer.com/2017/dont-use-in-memory-databases-tests-h2/">Philip Hauer’s blog</a>.</p><p>Nothing beats real wire connection: your in memory stubs implementations will always be flawed by design. Moreover, if you’re using Postgres for instance, you can even run all your database migration scripts before running your tests, ensuring they are working as expected as part of the tests.</p><p>I recently changed tech stack from Kotlin+Springboot to a new full Golang stack in my new awesome team at Ubisoft. I had to re-learn things that were obvious to me such as dependency injection, new packages layout and so on.</p><p>But one thing was really missing from my previous experience: TestContainers. I used to use it to locally substitute production document or relational databases, AMQP message brokers. I could not live without it. The test confidence that those bring is unmatched. (I’m a big fan of <em>DDD</em>/TDD concepts, so asserting your <em>application</em>/<em>service </em>layer work as intended against an actual implementations of <em>repositories </em>is priceless)</p><p>I was astonished when I discovered <a href="https://github.com/testcontainers/testcontainers-go/">github/testcontainers-go</a> and its nice <a href="https://golang.testcontainers.org/">documentation page</a>. Here are the advice I can give you to make them work in your Golang Unit Tests environment.</p><p>If you would like to see the code first, all following code snipets are available at <a href="https://github.com/ncomet/testcontainers-go">my personal Github</a>.</p><p>Let’s say you want to test a <em>service </em>that manipulates a <em>repository </em>holding video games, at random 😉, Ubisoft games:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d5d7ebe39355aed817256cc3fe0d1d42/href">https://medium.com/media/d5d7ebe39355aed817256cc3fe0d1d42/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*qnLfkzom7JmQWYklEzQrNQ.jpeg" /><figcaption>And how will you know for sure your mongoDB implementation will work in production, Gringo? — Antón Castillo</figcaption></figure><p>The first thing you usually do is implement your tests against an in memory implementation of this repository. I’ll leave the implementation details to the <a href="https://github.com/ncomet/testcontainers-go/blob/main/infra/mem/all_games.go">Github repository</a>.</p><p>Being a DDD oriented person, you could write your tests that way, following an arrange/act/assert (AAA) pattern:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/219321b518fc60aac8c70e37a65fd339/href">https://medium.com/media/219321b518fc60aac8c70e37a65fd339/href</a></iframe><p>The tests pass, that’s nice, but you just tested against an in memory implementation… Antón would not be proud of you.</p><p>Now, where does that allGames come from? It would be nice if we could substitute any implementation to the interface.</p><p>I like to use a Golang test routines integration called <a href="https://medium.com/goingogo/why-use-testmain-for-testing-in-go-dafb52b406bc">TestMain</a> (<a href="https://pkg.go.dev/testing#pkg-overview">official doc</a>). By convention, it helps defining setup and teardown behaviour during all tests execution from the current package. It has to be declared within a _test.go file, obviously.</p><p>A small example would be:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a26d6b987cfaea87bf833a3a0fd8dca5/href">https://medium.com/media/a26d6b987cfaea87bf833a3a0fd8dca5/href</a></iframe><p>Now that you get the concept, let’s write the logic. Here we first describe what a docker image is, and the repository interface I want to satisfy. Then I reuse the testcontainers.Container struct to add a URI to it, that will hold the exposed container endpoint, with its dynamic port.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4d4422e65927d53ffffc204d63511345/href">https://medium.com/media/4d4422e65927d53ffffc204d63511345/href</a></iframe><p>Then we can concentrate on how we will prepare and run the container using the library:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/524d48f1760d06231266d08c74b61ff7/href">https://medium.com/media/524d48f1760d06231266d08c74b61ff7/href</a></iframe><p>It is pretty straightforward, and reuses the Java library terms that I was used to. You first describe the ContainerRequest that you provide to the GenericContainer . Then, on l.12 the container will already be running with a local random available port mapped on your local interface.</p><p>To get this dynamically picked port you just call the MappedPort function.</p><p>Last, we return the full scheme mongodb://host:port that will now be ready to satisfy your testing needs.</p><p>I use this prepareContainer function in a setup function to create a container struct that we previously described:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/585f5ba06c86e35b9682f7104f184ed2/href">https://medium.com/media/585f5ba06c86e35b9682f7104f184ed2/href</a></iframe><p>All remains is to integrate it. I chose the following strategy:</p><p>If I get an error running the container — that most likely will be caused by an environment without an up and running docker daemon — or if for some reason the database is not reachable, I fall back to an in-memory (mem) implementation of the <em>repository</em>. It’s up to you to decide what to do here.</p><p>The nice thing here is that the tests we previously wrote in the AAA pattern will not have to be rewritten, they should run the same against any implementation of the repository, should it be the mongo one or the mem one.</p><p>You could also enforce that any dev on your team runs docker to locally test your services and I won’t even be mad at you 😇.</p><p>To get to the point, here is the final implementation of the TestMain function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c5cfd95387d064fb6aa295bbc2bd9f5/href">https://medium.com/media/8c5cfd95387d064fb6aa295bbc2bd9f5/href</a></iframe><p>Then, when we run the tests, we get the following output:</p><pre>2022/05/02 17:15:22 Starting container id: 9d9d56e5bcf1 image: docker.io/testcontainers/ryuk:0.3.3<br>2022/05/02 17:15:22 Waiting for container id 9d9d56e5bcf1 image: docker.io/testcontainers/ryuk:0.3.3<br>2022/05/02 17:15:22 Container is ready id: 9d9d56e5bcf1 image: docker.io/testcontainers/ryuk:0.3.3<br>2022/05/02 17:15:22 Starting container id: 4a1e5d93a03f image: mongo:5.0.8<br>2022/05/02 17:15:23 Waiting for container id 4a1e5d93a03f image: mongo:5.0.8<br>2022/05/02 17:15:24 Container is ready id: 4a1e5d93a03f image: mongo:5.0.8<br>2022/05/02 17:15:24 TestContainers: container mongo:5.0.8 is now running at mongodb://localhost:54970<br>=== RUN   Test_Add<br>--- PASS: Test_Add (0.02s)<br>=== RUN   Test_Replace<br>--- PASS: Test_Replace (0.01s)<br>=== RUN   Test_By<br>--- PASS: Test_By (0.00s)<br>=== RUN   Test_All<br>--- PASS: Test_All (0.00s)<br>PASS</pre><p>🎉 Congratulations Gringo 🎉, you’ve successfully used TestContainers to run your Go unit tests against an actual instance of a database!</p><p>It opens a lot more, anything that can be containerised could be used. In my current project, we use it to spin up a <a href="https://hub.docker.com/_/postgres">Postgres</a> and an <a href="https://hub.docker.com/r/amazon/dynamodb-local">AWS DynamoDB</a> at the same time for a full test suite.</p><p>If you want to access, compile or run the code used in this article, <a href="https://github.com/ncomet/testcontainers-go">feel free to go and clone it from my personal Github</a>.</p><p>Adiós!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4b5399b849d9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Koson : A Kotlin DSL To Write And Serialize JSON]]></title>
            <link>https://medium.com/@nicolas.comet/koson-a-kotlin-dsl-to-write-and-serialize-json-1569125ebaa0?source=rss-240735a14de4------2</link>
            <guid isPermaLink="false">https://medium.com/p/1569125ebaa0</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[libraries]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[dsl]]></category>
            <category><![CDATA[serialization]]></category>
            <dc:creator><![CDATA[Nicolas Comet]]></dc:creator>
            <pubDate>Wed, 16 Sep 2020 09:15:26 GMT</pubDate>
            <atom:updated>2022-05-03T09:16:43.215Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/947/1*qpYotEkta1EUenEGhBwreQ.png" /></figure><h3>Koson: A Kotlin DSL To Write And Serialize JSON</h3><h3>The Scene</h3><p>When you write code for distributed apps, especially in the all mighty microservices era, there is one word that keeps showing up during technical conceptions: <em>format</em>.</p><blockquote>“What human readable <em>format</em> will our services use to exchange messages?”</blockquote><blockquote>“What <em>scheme</em> will we be using to provide the standard output with logs?”</blockquote><p>Very often nowadays, the answer lies within four letters: <a href="https://www.json.org/json-en.html">JSON</a> (JavaScript Object Notation). Although there are other human readable alternatives (yaml is less verbose, but indentation sensitive; XML is more verbose etc.) more and more people tend to suggest (and use) JSON.</p><p>Our technical stack, as far as the JVM is concerned, is now completely implemented with Kotlin+SpringBoot services. These services produce their logs according to a specific format, that is described using JSON. They also use JSON to serialize and deserialize outgoing and incoming messages. These messages are then also validated using JSON schemas.</p><p>Long story short, JSON has become key to how we communicate, manage logs, provide and consume APIs to/from different teams.</p><h3>The Problem</h3><p>We all tend to like things <strong>simple</strong>. However when you are not in a JavaScript first class citizen technical stack, it can be tedious to always have to write classes just for the sole purpose of serializing and deserializing JSON. You very often have to rely on a serialization library like Jackson. To add insult to injury, sometimes when writting unit tests, you just want to provide a method, an endpoint, a <a href="https://en.wikipedia.org/wiki/Behavior-driven_development">BDD</a> test with a simple JSON object.</p><p>What are your choices if you want to avoid relying on a library or a framework?</p><p>You could always use Kotlin&#39;s multiline Strings to format your objects, especially since there is a pretty good integration in IntelliJ IDE. You could even inject language reference (Alt+Enter → Inject language or reference → JSON) and would benefit from some coloration/completion while creating your object.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b92aa5474a6940d5a893a2fc32654386/href">https://medium.com/media/b92aa5474a6940d5a893a2fc32654386/href</a></iframe><p>But ultimately, every developer has to remember there is such a functionality in their IDE to benefit from these tools. However, if you want to play a bit more with formatting and still keep the code maintainance easy for future developers, this is not ideal. You can then decide to switch to a trimMargin() version.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/024bd225f57ddc666e2afc1ef88011e7/href">https://medium.com/media/024bd225f57ddc666e2afc1ef88011e7/href</a></iframe><p>But then JSON language injection would be lost because of the introduced | chars.</p><p>These solutions may suit you perfectly. But keeping up with upcoming code change while keeping indentation the way you want can be tricky.</p><h3>The Idea</h3><p>It all started from a rather simple observation: Kotlin internal DSLs allow its users to design APIs that fit well with the language, obviously.</p><p>But other interesting aspects arise. Since Kotlin allows for a very good interop with Java, it is also possible to wrap existing libraries into a nicer looking Kotlin hierarchical syntax, or even use the language as core descriptor for a build tool, such as Gradle &#39;s <a href="https://docs.gradle.org/current/userguide/kotlin_dsl.html">Kotlin DSL</a>.</p><p>The advantages are numerous: you’ll get code completion &amp; formatting for free while benefiting from the compiler’s type checks.</p><p>Without digging too deep into Kotlin &#39;s design, DSLs heavily rely on these 5 language specificities :</p><ul><li><a href="https://kotlinlang.org/docs/reference/extensions.html#extensions">extension functions</a></li><li><a href="https://kotlinlang.org/docs/reference/functions.html#infix-notation">infix notation</a></li><li><a href="https://kotlinlang.org/docs/reference/lambdas.html#higher-order-functions">higher order functions</a></li><li><a href="https://kotlinlang.org/docs/tutorials/kotlin-for-py/functional-programming.html#receivers">lambdas with receiver</a></li><li><a href="https://kotlinlang.org/docs/reference/lambdas.html#passing-a-lambda-to-the-last-parameter">the trailing lambda rule</a></li></ul><p>Koson was created using these functionalities only. No other third party libraries are used, resulting in a very lightweight Kotlin library.</p><h3>Koson</h3><p><a href="https://github.com/lectra-tech/koson">lectra-tech/koson</a></p><p>Koson was open sourced under the MIT licence in 2018. Some functionalities have been added over the years, but mainly, this is how you use it:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*MMt8soV1czUSZcudFjBcrg.gif" /></figure><p>obj and arr are the main entry points of the library, allowing to start describing your JSON content.</p><p>Here is another example:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bf52f04a57e4e6d909e4ca7c6a5b6087/href">https://medium.com/media/bf52f04a57e4e6d909e4ca7c6a5b6087/href</a></iframe><p>// 1 Will output a single line formatted JSON String:</p><pre>{&quot;key&quot;:3.4,&quot;anotherKey&quot;:[&quot;test&quot;,&quot;test2&quot;,1,2.433,true],&quot;nullValue&quot;:null,&quot;emptyObject&quot;:{},&quot;emptyArray&quot;:[],&quot;custom&quot;:&quot;2020-07-15T10:59:19.042965+02:00[Europe/Paris]&quot;}</pre><p>// 2 Will output a 2 whitespaces indented JSON String:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8c60bba0c3a157295da1c0baf7c864d0/href">https://medium.com/media/8c60bba0c3a157295da1c0baf7c864d0/href</a></iframe><p>Now the good thing is you will benefit from <strong>syntax highlighting</strong>, <strong>code completion</strong>, <strong>formatting</strong> and even <strong>type safety</strong>.</p><p>For instance the library prevents errors at compile time:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/704/1*d3w2xfQjw2OWEqYPYT0SsA.png" /></figure><p>Koson also allows the user to feed an <a href="https://github.com/lectra-tech/koson#alternative-arr-syntax">Iterable as a source for an array</a>, <a href="https://github.com/lectra-tech/koson#raw-json">external JSON source embedding</a> and <a href="https://github.com/lectra-tech/koson#custom-types-serialization">custom types definition</a> if you are not happy with the way Koson <a href="https://github.com/lectra-tech/koson#strong-type-constraints">serializes</a> all “primitive” types.</p><h3>How does it work?</h3><p>Long story short, everything you use is defined in a single Koson.kt file.</p><p>The obj is a function with a lambda with receiver parameter that operates over a Koson type. The Koson class is used to produce an ObjectType, that can add a finite instance type list to the object.</p><p>The arr is in fact a singleton (object in Kotlin) that uses the operator overload to permit the use of the [] as a function. It returns an ArrayType when invoked.</p><p>To sum it up, here is a diagram to show the full type hierarchy.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ba86Dlm5ndrzD18A-DA1Og.png" /></figure><p>If you are curious and want to check out the implementation details, or why not contribute to improve this library, feel free to check the official github repository here : <a href="https://github.com/lectra-tech/koson">https://github.com/lectra-tech/koson</a></p><p>If you want to learn more about how Kotlin DSL can be written, you can watch this <a href="https://youtu.be/2PDiZsw4YhE">video (<em>FR only</em>)</a> by Benoit introducing Kotlin DSLs.</p><p>There also is a <a href="https://youtu.be/yjjWGzZFvQY">video of a talk I gave (<em>FR only</em>)</a> explaining how a private company can contribute to OSS and why they should, even if they think they don’t have material to do so. It also shortly explains how Koson’s publication process works.</p><h3>Performance</h3><p>Now that’s nice, but how does it behave? Is it faster than using your favorite serialization library?</p><p>To try answering that question, we’ve built 4 different benchmarks using the <a href="https://openjdk.java.net/projects/code-tools/jmh/">JMH OpenJDK tool</a>. If you want to have a look or run the benchmarks on your machine, you’ll find all the details on our <a href="https://github.com/lectra-tech/koson#benchmarks">github page</a> and in the following embedded <a href="https://github.com/lectra-tech/koson/tree/master/benchmarks">project</a>.</p><p>To sum it up, here are the results in operations/second (throughput mode), higher = better.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J2eoDpAvftaNJpRMTL2Haw.png" /><figcaption>Testing environment : <em>3.3 GHz Intel Core i5–6600, 4 cores, VM version: OpenJDK 11.0.1, 64-Bit Server VM, 11.0.1+13</em></figcaption></figure><h3>Conclusion</h3><p>If your only need is having to create JSON String representations from scratch in Kotlin, Koson is made for you. Feel free to ⭐ <a href="https://github.com/lectra-tech/koson">the project</a> if you enjoy it, use it, and why not suggest improvements using issues !</p><p>Kotlinly yours ;)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1569125ebaa0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Power Of Kotlin Sealed Classes]]></title>
            <link>https://medium.com/@nicolas.comet/the-power-of-kotlin-sealed-classes-74f1ad5e0c7c?source=rss-240735a14de4------2</link>
            <guid isPermaLink="false">https://medium.com/p/74f1ad5e0c7c</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[sealed-classes]]></category>
            <category><![CDATA[api]]></category>
            <dc:creator><![CDATA[Nicolas Comet]]></dc:creator>
            <pubDate>Fri, 12 Apr 2019 06:13:41 GMT</pubDate>
            <atom:updated>2019-04-19T11:55:59.454Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YsKI-lT951JlOwFrc82iZg.jpeg" /></figure><p>At my company (Lectra), an increasing number of backend Cloud applications use Kotlin. The need of using a strongly typed language came from a simple fact : it drastically reduces bugs, since <em>everything your compiler/IDE does for you is something you don’t have to think about. </em>Then you can simply focus on the domain code, and more importantly what your application is supposed to do. Kotlin was designed with this idea as ground rule.</p><p>Kotlin bundles a very powerful syntax : <em>sealed classes. </em>We will only focus on one aspect of it in this article.</p><p>A sealed class can be considered as a type with a finite set of subtypes. It is simply defined this way :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3637bd0df7d5c63468989021ae0c70b7/href">https://medium.com/media/3637bd0df7d5c63468989021ae0c70b7/href</a></iframe><p>This class is by default abstract, and cannot be instantiated.</p><p>Now we can define sub-classes. However you don’t have to think about these sub-classes as inheritance (event if it is generated this way in the bytecode) but more like a type catalog, a type enum, or a kind of distinct union types (as in TypeScript)</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/15fa5afabba67a13aeff991064dedc60/href">https://medium.com/media/15fa5afabba67a13aeff991064dedc60/href</a></iframe><p>Note the <strong>() constructor</strong> for each of these types. Now we have a concrete class to represent a booking, two singleton instances to improve the expressiveness of the different choices. You could also choose to use a <em>data class </em>if needed.</p><p>Now, here is the interesting part. In Kotlin, the compiler/IDE is aware of this sealed class hierarchy exhaustiveness. What this means is, when you will provide a service for your consumers, it reveals all its power :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/74902706c292c96f8d7c88e0049e86da/href">https://medium.com/media/74902706c292c96f8d7c88e0049e86da/href</a></iframe><p>Now for the fun part. For every consumer of your service, the sealed class <em>BookingOutcome</em> becomes the contract. Meaning every caller will benefit from the compiler checks whether they exhaustively planned (or not) to handle all your possible outcomes !</p><p>For instance :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9547e1efdcd5fd134b3dcfae646750da/href">https://medium.com/media/9547e1efdcd5fd134b3dcfae646750da/href</a></iframe><p>Now IntelliJ and Kotlin compiler will come to the rescue ! When combined with the <em>when</em> keyword, it is a very strong way to enforce the way an API is used. (‘<em>when’</em> is Kotlin’s version of Java’s ‘<em>switch’ </em>, with a pattern matching-like syntax)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/284/1*LbHPH7wdMqiNVnkPlFxUWg.png" /></figure><p>It even does the beginning of the work for the consumer :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/298/1*6EjrLRu3qzbxo7kd6dgUCA.png" /></figure><p>More importantly, it will not compile if the branches are not complete, or without a willingly declared <em>else -&gt; </em>branch !</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/810/1*a0go185NzdTXd4FUiX_3tw.png" /></figure><p>Since it is a “pattern matching”-like friendly language, it will even auto smartcast on the right side.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/562/1*2TCw4j6j8aLCcl5BhERTrQ.png" /></figure><p>We’ve only seen one aspect of sealed classes in this article, but it should really become a reflex when you think about enumerations that carry any kind of useful information for your services/APIs or any kind of type expressiveness you want to achieve.</p><p>Kotlinly yours ;)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=74f1ad5e0c7c" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>