Free AI web copilot to create summaries, insights and extended knowledge, download it at here
4437
Abstract
however this is not rich enough for us. Nullables/optionals are fine for representing success, but if something goes wrong, we probably want to encode some information about what went wrong - the '<i>oops instance</i>', so to speak. And nullables/optionals only have the ability to communicate "something" vs "nothing". What we want is <code>Success(value: T)</code> vs <code>Failure(oops: Throwable)</code>.</p><p id="ccb5">So…let’s do exactly that! Let’s create a type <code>Result<out T></code> and two subclasses <code>Success<T>(val value: T): Result<T></code> and <code>Failure(val error: Throwable) : Result<Nothing></code> and use those to wrap all of our calculations.</p>
<figure id="87e0">
<div>
<div>
<img class="ratio" src="http://placehold.it/16x9">
<iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2Fus1wVviSO&display_name=Kotlin+Playground&url=https%3A%2F%2Fpl.kotl.in%2Fus1wVviSO&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800">
</div>
</div>
</figure></iframe></div></div></figure><p id="64cd">Hmmm…could we do better? Yes we could:</p>
<figure id="d53d">
<div>
<div>
<img class="ratio" src="http://placehold.it/16x9">
<iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FfYB0JFFqQ&display_name=Kotlin+Playground&url=https%3A%2F%2Fpl.kotl.in%2FfYB0JFFqQ&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800">
</div>
</div>
</figure></iframe></div></div></figure><p id="00f2">By introducing two simple types and a function, we were able to:</p><ul><li>recover normal execution flow</li><li>get rid of spooky “action-at-a-distance” exception handlers</li><li>write code that is shorter, cleaner, and almost as simple as code where we completely ignore exceptions</li><li>deal with <b>all possible errors</b>, now and in the future</li><li>be explicit that this operation can fail, and use types to force calling code to deal with these failures (incidentally, this is what checked exceptions were trying, and <a href="https://news.ycombinator.com/item?id=827540">mostly</a> <a href="http://twistedoakstudios.com/blog/Post399_improving-checked-exceptions">failing</a>, <a href="https://www.ckwop.me.uk/Why-Exceptions-Suck.html">to do</a>)</li></ul><p id="c8e0">However, most importantly, we have shifted our mindset. We no longer view exceptions as control flow constructs, we view them as simple carriers of information — basically data classes. We don’t immediately feel the need to translate or chain them, unless there is an actual need to provide more information or react to them — for the most part, the type won’t matter.</p><p id="69f2">The benefit of this approach gets multiplied when you start dealing with libraries that represent errors in different ways.</p><p id="e725">Here’s an example:</p>
<figure id="d6d9">
<div>
<div>
<img class="ratio" src="http://placehold.it/16x9">
<iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2Frr7HKMygP&display_name=Kotlin+Playground&url=https%3A%2F%2Fpl.kotl.in%2Frr7HKMygP&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800">
</div>
</div>
</figure></iframe></div></div></figure><p id="c245">Given those functions, we are tasked with creating <code>ratioOfLibFuns()</code> which returns the <code>Int</code> ratio of both library functions, and deals with errors appropriately. In this specific scenario, if the <code>Int</code> returned by <code>libFun2</code> is missing, it means that the user forgot to do something, and we want to convey this information somehow.</p><p id="40e2">Here’s how we would probably implement this up until now:</p>
<figure id="c55c">
<div>
<div>
<img class="ratio" src="http://placehold.it/16x9">
<iframe class="" src="https://cd
Options
n.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2Fuaox6kG6x&display_name=Kotlin+Playground&url=https%3A%2F%2Fpl.kotl.in%2Fuaox6kG6x&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800">
</div>
</div>
</figure></iframe></div></div></figure><p id="bebe">Ugh, what a mess. Thankfully, using what we just discovered, we can do better:</p>
<figure id="450c">
<div>
<div>
<img class="ratio" src="http://placehold.it/16x9">
<iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FsdsN6dBgC&display_name=Kotlin+Playground&url=https%3A%2F%2Fpl.kotl.in%2FsdsN6dBgC&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800">
</div>
</div>
</figure></iframe></div></div></figure><p id="7995">By introducing a super simple type, we managed to make to code about 4x shorter, increase its readability and maintainability, and become explicit about the fact that it can fail.</p><p id="925f">In fact, we could go further — we could combine this approach with what we learned about <a href="https://readmedium.com/sealed-hierarchies-strongly-typed-illegal-states-3d3c50c9a77b">strongly typed illegal states</a>, and avoid using <code>UserRatioException</code> completely:</p>
<figure id="6941">
<div>
<div>
<img class="ratio" src="http://placehold.it/16x9">
<iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2Fsiyxi50Pg&display_name=Kotlin+Playground&url=https%3A%2F%2Fpl.kotl.in%2Fsiyxi50Pg&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800">
</div>
</div>
</figure></iframe></div></div></figure><p id="15a2">Notice how much information you gain just by reading the signature of the function: it returns a <code>Ratio</code> instance, which recognizes a single type of business error (<code>Int2Missing</code>), and is wrapped in <code>Result</code>, which signifies that the method can fail unexpectedly. Without even looking at the implementation, you immediately know about all the things that can possibly happen in this method.</p><p id="c9b6">This is one of the incredibly powerful consequences of using types which have implicit <i>meaning</i>/<i>behavior</i> associated with them. You actually know this very well, but might not realize it. Think about it — <code>Optional</code> means a presence or absence of a value, <code>List</code> means multiple values, <code>Future</code> is a value which will exist at some point in time, <code>Function</code> is a value that can be<i> produced</i>, <code>Result</code> is a value or a failure, and so on.</p><p id="8f77">This is actually one of the core principles of <i>actual</i> functional programming — using these datatypes, as well as many other ones such as <code>Either</code>, <code>Writer</code>, <code>State</code>, <code>Eval</code> and many, many others, to represent <i>behavior</i> in a program, and building what we need as a composition of these fundamental, provably correct behaviors. This topic is far beyond the scope of this article, but I thought it was worth mentioning that there was a close connection with what we’re doing here with <code>Result</code>.</p><p id="20a7">It turns out that the <code>Result</code> hierarchy and the <code>runCatching</code> method are already part of the standard library. In the next article, we’ll explore what’s included in the standard library more closely.</p><p id="3c25">Go back to <a href="https://readmedium.com/programming-with-result-motivation-dec875787a7">Programming with Result: Motivation</a>, jump to the <a href="https://readmedium.com/table-of-contents-c52573cfa291">Table of Contents</a>, or continue to <a href="https://readmedium.com/programming-with-result-kotlin-result-836972cfb29e">Programming with Result: <code>kotlin.Res</code>ult</a>.</p><figure id="8ecd"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*biBSB579iezsNvEQ_NMLBg.png"><figcaption></figcaption></figure></article></body>