Scope Functions | Kotlin

Hamza Oban
Orion Innovation techClub
4 min readFeb 19, 2023
Kotlin Scope Functions

The Kotlin standard library contains several functions whose sole purpose is to execute a block of code within the context of an object. When you call such a function on an object with a lambda expression provided, it forms a temporary scope. In this scope, you can access the object without its name.

As you can see in the table above, there are 5 scope functions.

These functions do the same: execute a block of code on an object. What’s different is how this object becomes available inside the block and what is the result of the whole expression.

Function selection

Table showing the differences

Object References

Inside a lambda of a scope function, this (lambda receiver) is used to access the context object. The same object can be accessed by using it (lambda argument). In general, both can perform similar things.

This

Inside a scope function, you will be able to reference the context object by a short word (this), instead of the name itself.

run, apply, with use ‘this’ to access the context object.

It

let’ and ‘also’ functions refer to the object’s context as a lambda argument.

Let

Executing a lambda on non-null objects: let

Introducing an expression as a variable in local scope: let

Person("Alice", 20, "Amsterdam").let {
println(it)
it.moveTo("London")
it.incrementAge()
println(it)
}

If we write it without “let” it should look like this:

We create a new variable and make changes using that variable.

val alice = Person("Alice", 20, "Amsterdam")
println(alice)
alice.moveTo("London")
alice.incrementAge()
println(alice)

“Let” is usually used for a null check.

private val text : String ?= null

fun main() {
//null check
if(text!=null){
print(text)
}

//We have done the null check using let.
text?.let{
print(it)
}
}

Run

Object configuration and computing the result: run

Running statements where an expression is required: non-extension run

val service = MultiportService("https://example.kotlinlang.org", 80)

val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}

// the same code written with let() function:
val letResult = service.let {
it.port = 8080
it.query(it.prepareRequest() + " to port ${it.port}")
}

run which is an extension to the Template class is similar to let but the only difference is in let we get a reference as it whereas, in the run, the reference is this.

The best use case of this run function is to avoid the null check. the run function used with ? . ensures the execution only if the expression is non-null.

Apply

Object configuration: apply

class Employee {
var firstName: String = ""
var age: Int = 0
}

val employee = Employee().apply{
firstName = "Suneet Agrawal"
age = 27
}

apply is recommended for lambdas that mainly operate on the object members or call its functions or assign properties. In short, it is mostly used for object configurations.

With

The grouping function calls on an object: with

class Game() {
lateinit var name: String
lateinit var type: String
lateinit var company: String
}

fun main() {
val lol = Game().apply {
name = "League of Legends"
type = "MOBA"
company = "RIOT GAMES"
}

// with function
with(lol) {
// similar to println( "${this.name} ${this.type} ${this.company}" )
println(" $name $type $company ")
}
}

The with function has a return type as the lambda result, and the context object is this keyword, which refers to the object itself.

Also

Additional effects: also

also is good for performing some actions that take the context object as an argument. Use also for actions that need a reference to the object rather than its properties and functions, or when you don’t want to shadow this reference from an outer scope.

fun main() {
// initialized
val list = mutableListOf<Int>(1, 2, 3)

// later if we want to perform
// multiple operations on this list
list.also {
it.add(4)
it.remove(2)
// more operations if needed
}
println(list)
}

When you see also in the code, you can read it as "and also do the following with the object."

Thanks for reading, I hope it was helpful.

--

--