Understand Kotlin Function Literal with Receiver by Example
Tags: kotlin, beginners, android, programming
Published: 2022-02-11 22:06:19

**This article provides some simple code examples of using function literal with receiver (also known as lambda/anonymous function with receiver).**

I came across this lambda syntax - `NavGraphBuilder.() -> Unit` and it turns out it is called **Function Literal with Receiver**, which is also known as **Lambda/Anonymous Function with Receiver**.

The syntax looks like this:

> Receiver.(Parameters) → ReturnType

The following shows some examples of building a custom string using function literal with receiver.

## Example 1: Function Literal With Receiver

```kotlin
fun buildCustomStringExample1(
    action: StringBuilder.(String) -> Unit): String {
    
    val stringBuilder = StringBuilder()
    stringBuilder.action("Example1")
    return stringBuilder.toString()
}
```
`action` is the function literal / lambda function with receiver. `StringBuilder` is the receiver. It acts like an [extension function](https://vtsen.hashnode.dev/complete-c-to-kotlin-syntax-comparisons#heading-extension-methods-functions) of `StringBuilder` which takes in the `string` as input parameter.

To call `action`, `StringBuilder` is instantiated, call it like an extension function - `stringBuilder.action("Example1")`

> You can imagine `action` is like a callback function that belongs to `StringBuilder`.

### Usage
This is the usage of function literal with receiver:
```kotlin
val output1 = buildCustomStringExample1 { content ->
    this.append("<tag>")
    append("$content") 
    append("</tag>")
}
println("$output1")
```
We call the `buildCustomStringExample1 ` with function literal / lambda function parameter. In this lambda function, we specify how we build the custom string - wrap the content with `"<tag>"` and `"</tag>"`.

`content` is the input parameter which is passed in from the `buildCustomStringExample1` function. `this` is the `StringBuilder` instance that created in `buildCustomStringExample1()` function, and it can be omitted. `append()` is the function that belongs to `StringBuilder`.

> **[Updated - Jun 12, 22]:** I recently learned that this type of usage is called domain-specify language (DSL). So, function literal with receiver is used to build DSL. The main purpose is for readability.

### Output

The output looks like this:
```xml
<tag>Example1</tag>
```

## Example 2: Function Literal Without Receiver

Function literal / lambda function with receiver can be rewritten without using the receiver based on the following syntax:

> (Receiver, Parameters) → ReturnType

This is the usual [lambda expressions](https://vtsen.hashnode.dev/complete-c-to-kotlin-syntax-comparisons#heading-lambda-methods-functions) which takes in 2 parameters. The first parameter is, `StringBuilder` which is the receiver in example 1 above.

```kotlin
fun buildCustomStringExample2(
    action: (StringBuilder, String) -> Unit
): String {

    val stringBuilder = StringBuilder()
    action(stringBuilder, "Example2")
    return stringBuilder.toString()
}
```
`action` is the usual callback function which takes in 2 parameters.  To call `action`, `StringBuilder` is instantiated, and passed in as the first parameter of the `action` callback function - `action(stringBuilder, "Example2")`

### Usage
This is the usage of function literal without receiver:
```kotlin
val output2 = buildCustomStringExample2 { stringBuilder, content ->
    stringBuilder.append("<tag>")
    stringBuilder.append("$content")
    stringBuilder.append("</tag>")
}
println("$output2")
```
This is similar to example 1 except we no longer use `this` which has been replaced by `stringBuilder` as the first lambda parameter. `content` is the second parameter of the lambda function. 

### Output

The output looks like this, which has the same output as example 1:

```xml
<tag>Example2</tag>
```

## Conclusion
It is not hard to understand function literal with receiver. It is basically a simplified way to write normal function literal / lambda function without additional parameter.

**Function Literal with Receiver** can be rewritten as  **Function Literal without Receiver**.

`Receiver.(Parameters) → ReturnType` ---> `(Receiver, Parameters) → ReturnType`

---

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/understand-kotlin-function-literal-with-receiver-by-example)*.