avatarGabriel Shanahan

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

2687

Abstract

<code>also</code> when you need to do "something on the side" with an object, but then want to continue working with it when you're done. Often, using <code>also</code> communicates that <b>what's happening there isn't part of the essence of what you're implementing</b> - it's more like "hey, BTW, <code>also</code> do this". Validations, logging, etc. often fall into this category. The documentation states that <code>also</code> should be used for "additional effects", which seems to express the same thing.</p><p id="ea79">Another situation where <code>also</code> can…also…be considered (as opposed to <code>apply</code>) is:</p><ul><li>the effect isn’t closely tied to the receiver of <code>also</code></li><li>readability would benefit from introducing an explicit name.</li></ul><p id="7fc2">The following illustrates both:</p> <figure id="072e"> <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%2FXAfynNile&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FXAfynNile&amp;image=https%3A%2F%2Fplay.kotlinlang.org%2Fassets%2Fog-image.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="a075">I feel the first way is better for two reasons:</p><ul><li>it names the result, which gives us a better idea of what we’re working with. This would be especially true if the result somehow communicated success or failure (e.g. using <code>Optional</code> or a nullable or just a plain <code>Boolean</code>) - using <code>this.isPresent</code>, <code>this?.</code> or <code>this == false</code> in such situations feels awkward</li><li>it doesn’t put the result on a pedestal. In the call to <code>validate</code>, it is very likely that <code>resultOfDoingBusinessStuff</code> and <code>someCalculatedValue</code> are "on the same level" which gets expressed much better in the first way than in the second</li></ul><p id="cc45">In contrast, I would consider using <code>apply</code> in the opposite scenarios, i.e. <b>when the effect actually is a key part of what's going on or when the effect is intimately tied to the receiver</b>.</p><p id="25e1">This goes well with the documentation, that states <code>apply</code> should be used for object configuration.</p><p id="561f">Take a look at the following:</p> <figure id="51ca"> <div> <div> <img class="r

Options

atio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2Flmh6NJleF&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2Flmh6NJleF&amp;image=https%3A%2F%2Fplay.kotlinlang.org%2Fassets%2Fog-image.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="2f34">We managed to both save some keystrokes, redefine the function as an expression, therefore taking advantage of type inference for the return value, and also arguably made the code more elegant.</p><h2 id="98aa">Summary</h2><p id="debe">I would say that the main thing I think about when deciding whether to use <code>apply</code> or <code>also</code> is how the block of code relates to the receiver, and to the scenario I’m implementing. Is it a key part of what’s going on? Then I would consider using <code>apply</code>. Is it just a “side-gig”, a “chore” that has no bearing on the essence of the calculation itself? That’s when I consider using <code>also</code>.</p><p id="e2a6">Doing this has the major benefit of immediately telling a future maintainer what to concentrate on — in a sense, we’re emphasizing the <a href="https://en.wikipedia.org/wiki/Happy_path">happy path</a>. When trying to understand what’s going on in a piece of code, and what the author was thinking when they were writing it, it is very useful to be able to say “<i>oh, okay, so the author didn’t consider this an essential part of what’s going on here, so let me ignore it for now and concentrate on what they thought was important for me to understand, and then I can come back and deal with the details</i>”. Keep this in mind when writing your own code.</p><p id="269a">Go back to <a href="https://readmedium.com/scope-function-also-apply-f4c13f23079c">Scope Functions: <code>als</code><code>o() </code>& apply()</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/scope-functions-let-takex-c69481215fc4">Scope Functions: <code>le</code><code>t() </code>& takeX()</a>.</p><figure id="8ecd"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*biBSB579iezsNvEQ_NMLBg.png"><figcaption><a href="https://www.etnetera.cz/prace-u-nas?utm_source=medium&amp;utm_medium=GabrielShanahan&amp;utm_campaign=KotlinPrimer&amp;utm_content=join-our-team&amp;utm_term=KotlinPrimer#pozice">Join me in Etnetera</a></figcaption></figure></article></body>

Scope Functions: also() vs. apply()

A thorough discussion on the differences between also() and apply(), when to use which and how to use them to show future readers what’s important

— — — — — — — — — — — — — — —

THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.

— — — — — — — — — — — — — — —

Tags: #FUNDAMENTAL CONCEPT

This article is part of the Kotlin Primer, an opinionated guide to the Kotlin language, which is indented to help facilitate Kotlin adoption inside Java-centric organizations. It was originally written as an organizational learning resource for Etnetera a.s. and I would like to express my sincere gratitude for their support.

It is recommended to read the Introduction before moving on. Check out the Table of Contents for all articles.

In the previous article, we introduced the apply() and also() scope functions, and discovered that they were nearly identical.

The following are functionally identical.

So when should we use which, and why? The difference between the two, as you might have guessed, is in the intent — how a reader interprets your code based on which function you use.

In general, you would use also when you need to do "something on the side" with an object, but then want to continue working with it when you're done. Often, using also communicates that what's happening there isn't part of the essence of what you're implementing - it's more like "hey, BTW, also do this". Validations, logging, etc. often fall into this category. The documentation states that also should be used for "additional effects", which seems to express the same thing.

Another situation where also can…also…be considered (as opposed to apply) is:

  • the effect isn’t closely tied to the receiver of also
  • readability would benefit from introducing an explicit name.

The following illustrates both:

I feel the first way is better for two reasons:

  • it names the result, which gives us a better idea of what we’re working with. This would be especially true if the result somehow communicated success or failure (e.g. using Optional or a nullable or just a plain Boolean) - using this.isPresent, this?. or this == false in such situations feels awkward
  • it doesn’t put the result on a pedestal. In the call to validate, it is very likely that resultOfDoingBusinessStuff and someCalculatedValue are "on the same level" which gets expressed much better in the first way than in the second

In contrast, I would consider using apply in the opposite scenarios, i.e. when the effect actually is a key part of what's going on or when the effect is intimately tied to the receiver.

This goes well with the documentation, that states apply should be used for object configuration.

Take a look at the following:

We managed to both save some keystrokes, redefine the function as an expression, therefore taking advantage of type inference for the return value, and also arguably made the code more elegant.

Summary

I would say that the main thing I think about when deciding whether to use apply or also is how the block of code relates to the receiver, and to the scenario I’m implementing. Is it a key part of what’s going on? Then I would consider using apply. Is it just a “side-gig”, a “chore” that has no bearing on the essence of the calculation itself? That’s when I consider using also.

Doing this has the major benefit of immediately telling a future maintainer what to concentrate on — in a sense, we’re emphasizing the happy path. When trying to understand what’s going on in a piece of code, and what the author was thinking when they were writing it, it is very useful to be able to say “oh, okay, so the author didn’t consider this an essential part of what’s going on here, so let me ignore it for now and concentrate on what they thought was important for me to understand, and then I can come back and deal with the details”. Keep this in mind when writing your own code.

Go back to Scope Functions: also() & apply(), jump to the Table of Contents, or continue to Scope Functions: let() & takeX().

Join me in Etnetera
Java
Kotlin
Programming
Kotlin Scope Functions
Functional Programming
Recommended from ReadMedium