Kotlin Primer

Higher-Order Functions

A "higher-order function", in programming or math, is a function that takes other functions as parameters or returns a function.

These are incredibly useful, as they allow you to swap out parts of the logic inside a function with external logic that can be passed in, or create functions on the fly. (If you're familiar with the Strategy Pattern, this will feel very familiar.)

fun createPage(
    title: String,
    year: Int,
    header: (String) -> String = { it },
    footer: (String, Int) -> String = { _, year -> "Copyright $year" },
    body: () -> String,
) =
    """
        ${header(title)}
        ${body()}
        ${footer(title, year)}
    """.trimIndent()

fun main() {
    println(
        createPage(
            title = "My title", 
            year = 2026,
            body = {
                "This is the body"
            }
        )
    )
    println("--------")
    println(
        createPage(
            title = "My title", 
            year = 2026,
            header = { "!!!$it!!!"},
            body = {
                "This is the body"
            },
            footer = { title, year -> "$title. Copyright $year"},
        )
    )
}

There's a lot going on here, and it should start looking familiar, but let's dig in...

Three of the parameters have function types:

header: (String) -> String = { it },
footer: (String, Int) -> String = { _, year -> "Copyright $year" },
body: () -> String,

The header and footer parameters have default values, which are defined using lambdas.

The header parameter's default only has a single parameter passed, and is just returning that parameter, so we use the it form rather than { title -> title }.

The footer parameter's default doesn't use the title parameter, so we specify _ instead to make it clear we didn't intend to use it (otherwise the compiler will add a warning for an unused parameter).

The body parameter has no default; it must always be specified.

When run, the createPage() function runs all three functions and combines them using a multi-line string. The calls are enclosed in ${...} to evaluate them inside the string.

"""
    ${header(title)}
    ${body()}
    ${footer(title, year)}
""".trimIndent()

When we call createPage, we can explicitly override the header and footer parameters with lambdas, but we must always specify the body lambda.

createPage(
    title = "My title", 
    year = 2026,
    header = { "!!!$it!!!"},
    body = {
        "This is the body"
    },
    footer = { title, year -> "$title. Copyright $year"},
)

A really nifty feature in Kotlin functions is that if the last parameter is a lambda, the argument can be specified outside of the calling parentheses.

createPage("My title", 2026) {
    "This is the body"
}

If there are no other required parameters, you can even omit the parentheses entirely! This can make the function feel more like a control structure. We'll see this quite often in Jetpack Compose user interfaces:

Column {
    Text(...)
    Text(...)
}

The Column function only requires its last parameter (called content), which has a function type.

Note

In Android's Jetpack Compose user-interface library, you'll often see higher-order functions called "Slot APIs", as they're being used to specify which content goes into which "slot" (area) of the user interface. Each "slot" is a function that defines the content for that area.