androidengineers.Book a session

Functional Programming

Closures and Captured Variables

article15 minMedium

Captured variables outlive their original call

A closure retains access to values from its surrounding scope. Capturing a mutable variable means later invocations can observe and change shared state.

fun counter(): () -> Int {
    var value = 0
    return { ++value }
}

fun main() {
    val first = counter()
    val second = counter()
    check(first() == 1)
    check(first() == 2)
    check(second() == 1)
}

Each call to counter creates independent captured state. The returned function keeps that state reachable after counter has returned. This is useful for callbacks but can also retain large objects unintentionally.

Incrementing the captured integer is not thread-safe. If multiple threads invoke the same function, use an appropriate synchronization strategy or avoid shared mutable state. A closure does not provide a concurrency guarantee.

Exercise

Create a running-total closure and test independent instances. Then redesign it as a pure function returning the next total from an explicit prior total.

Check: compare which design is easier to replay, test, and share between concurrent callers.

Reference: Closures

YOUR LEARNING JOURNEY

0 of 110 available lessons completed

Progress saved in this browser. No account needed.
Closures and Captured Variables | Kotlin Core Programming | Android Engineers