What you'll learn
Kotlin has five little functions — let, run, with, apply, and also — that run a block of code in the context of an object. They're a huge part of what makes Kotlin so concise and expressive. This module demystifies them.
By the end you'll be able to:
- Use the five scope functions confidently
- Understand
itvsthisand result vs receiver - Pick the right one for each situation
The five at a glance
They differ in just two ways: how they refer to the object (as it or as this), and what they return (the lambda's result, or the object itself):
| Function | Object is | Returns | Typical use |
|---|---|---|---|
let | it | lambda result | null-safe transforms |
run | this | lambda result | configure then compute a result |
with | this | lambda result | operate on an object (not an extension) |
apply | this | the object | configure and return the object |
also | it | the object | side effects like logging |
let
let is the most common. It runs a block with the object as it and returns the block's result — perfect with a safe call for "do this only if not null" and for transforming a value into something else:
val name: String? = "Sara"
val length = name?.let {
println("Processing $it") // 'it' is the value, non-null here
it.length // the last line is what let returns
}
println(length) // 4apply & also
Both return the object (so you can chain), but differ in reference. apply uses this, making it ideal for configuring an object — you call its members directly with no prefix:
val sb = StringBuilder().apply {
append("Hello") // 'this' is the StringBuilder — no prefix needed
append(", ")
append("Kotlin!")
} // apply returns the StringBuilder itself
println(sb)also uses it and is meant for side effects that don't change the object — logging, validation, debugging — slotted into a chain:
val numbers = mutableListOf(1, 2, 3)
numbers
.also { println("Before adding: $it") } // a side effect; returns the list
.add(4)
println("After: $numbers")Choosing one
Two questions decide it: do you want the object back or a computed result, and is it or this nicer to read?
let
transform / null checks
object is it · returns lambda result
run / with
configure + compute
object is this · returns lambda result
also
side effects (logging)
object is it · returns the object
apply
configure & return it
object is this · returns the object
Tip
Recap & quick check
Key takeaways
- Scope functions run a block in the context of an object; they differ by reference (it/this) and return (result/object).
- let: object is 'it', returns the lambda result — great for null-safe transforms.
- apply: object is 'this', returns the object — ideal for configuration.
- also: object is 'it', returns the object — ideal for side effects like logging.
- run/with: object is 'this', return the lambda result. Pick the one that reads best; avoid nesting them.
Quick check
1. In a 'let' block, how do you refer to the object?
2. Which scope function is best for configuring an object and returning it?
3. What does 'also' return?
4. Which two things distinguish the scope functions?
5. What's a good use of 'let'?
Great — these little functions unlock very idiomatic Kotlin. Next up: Module 11 — Extension Functions & Properties.