Implicit Receivers

Unlike the let() and also() methods, the run() and apply() methods executed their lambdas in the context of their own target. What’s cool about Kotlin is that the language and library implementors didn’t keep that as a privileged execution for themselves. Instead, they made it accessible very elegantly to every one using the language. If you’re eager to learn and execute such methods for your own code, the wait is over. And this technique is one of the most essential to create fluent syntax for DSLs, so it’s all the more exciting.

Passing a receiver

In JavaScript, functions may take zero or more parameters, but you may also pass a context object—a receiver—using either the call() method or apply() function. Kotlin’s ability to tie a receiver to a lambda expression is heavily influenced by that JavaScript capability.

Before we dive into dealing with receivers, let’s look at a regular lambda expression for a moment.

Press + to interact
var length = 100
val printIt: (Int) -> Unit = { n: Int ->
println("n is $n, length is $length")
}
printIt(6)

In this code, printIt refers to a lambda, which receives an Int as its parameter and returns nothing. Within the lambda we print a property named length and the value of the parameter n. It’s clear what n is, but where does length come from? The variable length isn’t in the internal scope of the lambda. Thus, the compiler binds length to the variable in the lexical scope—that is, from above the lambda expression. Let’s confirm that from the output:

n is 6,
...