avatarGabriel Shanahan

Summary

The web content provides an in-depth exploration of the let scope function in Kotlin, detailing its practical applications, common use cases with nullable values, and potential misuse, while also introducing related functions takeIf and takeUnless.

Abstract

The article titled "Scope Functions: let() & takeX()" serves as a comprehensive guide to understanding and effectively utilizing the let function in Kotlin. It emphasizes the function's ability to streamline calculations by eliminating the need for intermediate variables, particularly when the input needs to be referenced multiple times. The let function is also highlighted for its idiomatic use in handling nullable values in Kotlin, which is a common scenario in Kotlin development. The article further explores the synergistic use of let with takeIf and takeUnless to refine conditional logic. Additionally, it touches on the destructuring capabilities of lambdas in conjunction with let and how let can be used to symmetrize binary functions where the receiver and arguments have equivalent roles. The author cautions against the overuse of let, particularly when simpler constructs like if/else would suffice, advocating for simplicity over unnecessary complexity.

Opinions

  • The author believes that let is a powerful tool for simplifying code, especially in scenarios involving repetitive references to the input or nullable types.
  • The article suggests that combining let with takeIf and takeUnless can lead to more expressive and concise conditional logic.
  • There is an opinion that let can improve the readability and symmetry of binary functions by treating the receiver and arguments equally.
  • The author warns that let can be misused, leading to unnecessarily complex code when a simple if/else statement would be more appropriate.
  • The author advocates for a judicious use of let, emphasizing the principle of keeping solutions simple unless complexity is justified (DMICWIAS, as a counterpoint to KISS).

Scope Functions: let() & takeX()

An introduction to let() and how to combine it with takeIf() and takeUnless() to greatly simplify calculations, level the playing field when defining symmetrical binary functions, and how it can also be easily misused.

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

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.

The definition of let is essentially:

From a practical standpoint, let allows you to do a calculation without introducing an intermediate variable. This is especially handy in situations where the calculation needs to reference its input more than once.

However, probably the most common and idiomatic Kotlin use-case for let is when dealing with nullable values:

You will see this used all over the place, so get used to it.

The above is also commonly combined with uses of takeIf and takeUnless:

The ability of lambdas to destructure objects is commonly used in conjunction with let:

However, this is not specific to let, it's a capability of lambdas in general.

A more subtle use of let is to "level the playing field" when defining binary functions where one of the arguments is the receiver and a symmetry exists between the receiver and the arguments:

In both of the above examples, there is no difference in the roles of the receiver and argument — both the operations are commutative i.e. x.myFun(y) == y.myFun(z) and neither argument is "more special" than the other. However, the way we are forced to write the implementation suggests otherwise. A simple let can make it clearer that's the case:

While let can really make things better, it is probably misused most often. One instance that is often encountered is using a pair of ?.let/?: instead of a simple if/else:

Everything has a time and place, and while ?.let can objectively be better in some cases, especially when simplifying long call chains, always remember: Don't Make It Complicated When It's Already Simple (or DMICWIAS, the complicated sibling of KISS).

Go back to Scope Functions: also & apply, jump to the Table of Contents, or continue to Scope Functions: run & with.

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