Kotlin for C# Developers

5.4. Function literals with receiver (part 1)

We’ve seen extension methods:

Type.extensionMethod() {
    doStuffWith(this)
}

And we’ve seen lambdas:

fun doLongRunningTask(onDone: () -> Unit) {
    figureOutMeaningOfLife()
    onDone()
}

What happens if we put those two syntax elements together? The answer is we get a Kotlin feature called a function literal with receiver. (But if that’s too much of a mouthful you can think of it as an “extension lambda”.)

Here’s an example:

fun html(provideContent: Html.() -> Unit): Html {
    val html = Html()
    html.provideContent()
    return html
}

There’s a lot going on there so let’s unpack it piece-by-piece.

The lambda is the function literal, and the Html class is the receiver, hence function literal with receiver.

Let’s imagine our Html class is very basic indeed and looks like this:

class Html {
    private val contentBuilder = StringBuilder()

    fun div(innerText: String) = contentBuilder.appendLine("<div>$innerText</div>")

    override fun toString() = "<html>\n$contentBuilder</html>\n"
}

And now let’s put all that together and see how the html function is called:

val myHtml = html {
    // We're now inside the lambda body:
    // `this` refers to an Html object

    div("Hello world")   // Html class method call
    div("Goodbye world") // And another
}

println(myHtml)
// Output:
// <html>
// <div>Hello world</div>
// <div>Goodbye world</div>
// </html>

Look! We’ve built a very simple DSL! This is the exact equivalent of writing this:

val myHtml = Html()
myHtml.div("Hello world")
myHtml.div("Goodbye world")

println(myHtml)

Next: Function literals with receiver (part 2)