Fundamentals 11 min read

Kotlin Functions, Closures, and Lambdas – Chapter 5

This article explains Kotlin's function syntax, special return types Unit and Nothing, nested functions, operator overloading, infix expressions, closures, self‑executing closures, lambda expressions, higher‑order functions, and inline functions, illustrating each concept with clear code examples.

Hujiang Technology
Hujiang Technology
Hujiang Technology
Kotlin Functions, Closures, and Lambdas – Chapter 5

Kotlin's series continues with a deep dive into functions and closures, highlighting that functions are one of Kotlin's most distinctive features.

5.1 Functions – Functions are declared with the fun keyword. Example:

fun say(str: String): String {
    return str
}

The Unit type represents a value-less return, similar to Java's void , while Nothing denotes a function that never returns (e.g., always throws an exception).

5.2 Advanced Features

5.2.1 Nested Functions – Kotlin allows functions to be defined inside other functions, granting access to the outer function's local variables.

fun function() {
    val str = "hello!"
    fun say(count: Int = 10) {
        println(str)
        if (count > 0) say(count - 1)
    }
    say()
}

5.2.2 Operator Overloading – The in keyword and the .. range operator are implemented via overloaded functions such as iterator and rangeTo . Example of a ranged loop:

fun main(args: Array
) {
    for (i in 1..100 step 20) {
        print("$i ")
    }
}

The underlying implementation uses IntProgressionIterator and the rangeTo operator function.

5.2.3 Infix Expressions – Functions marked with infix can be called without dots or parentheses, e.g., the step function on IntProgression .

public infix fun IntProgression.step(step: Int): IntProgression {
    checkStepIsPositive(step > 0, step)
    return IntProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)
}

5.3 Closures – In Kotlin, closures (especially lambdas) are first‑class citizens. A self‑executing closure can be used for immediate initialization:

{ x: Int, y: Int ->
    println("${x + y}")
}(1, 3)

5.3 Lambda Expressions – Lambdas are anonymous functions with a dedicated type. Example:

val printMsg = { msg: String ->
    println(msg)
}
fun main(args: Array
) {
    printMsg.invoke("hello")
}

When a lambda has a single parameter, it can be used; unused parameters can be replaced with underscores. The last expression in a lambda determines its return value.

5.3.2 Higher‑Order Functions – Lambdas can be passed as arguments, turning the receiving function into a higher‑order function.

fun main(args: Array
) {
    log("world", printMsg)
}
val printMsg = { str: String -> println(str) }
val log = { str: String, printLog: (String) -> Unit ->
    printLog(str)
}

5.3.3 Inline Functions – Marking a higher‑order function with inline reduces runtime overhead by inserting the function body at call sites, though large inline functions can increase bytecode size.

5.4 Summary – Closures are a core Kotlin feature that can dramatically reduce boilerplate, as demonstrated by libraries like Anko, but overuse may harm readability.

ProgrammingKotlinfunctionsoperator overloadingClosuresLambdas
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.