What is a closure, and what does it capture?
LanguagesJunior
In shortA closure is a function that can use variables from where it was defined and keeps them alive. Swift, Kotlin and JavaScript capture the variables themselves (later changes are visible); Java captures only effectively final values. Captures are also why closures cause retain cycles and leaks.
Model answer
A closure (or lambda) is a function value that can use variables from the scope where it was created:
fun makeCounter(): () -> Int {
var count = 0
return { ++count } // captures count; it lives on after makeCounter returns
}
What is captured differs by language. Swift, Kotlin and JavaScript/TypeScript capture the variable: if it changes later, the closure sees the new value, and the closure can change it. Swift’s capture list ([x]) takes a snapshot instead. Java lambdas may only use effectively final locals, captured by value, so changing state has to live in an object.
Why it matters: a closure keeps everything it captures alive. In Swift, a closure stored on self that uses self is a retain cycle (fix: [weak self]). On the JVM and in JavaScript, a callback registered with something long-lived (a singleton, a timer, a global event) keeps the whole screen alive until it’s removed.
What they're looking for
A plain definition with an example (a counter or a callback), the difference in capture semantics between languages, and awareness of the memory consequences.
Common mistakes
- Confusing closures with anonymous classes only.
- Not knowing that captured variables live as long as the closure.
- Missing the retain cycle ([weak self]) or listener-leak consequence.
More languages questions
- How is memory managed in Swift compared to Kotlin or Java?Mid-level
- What is the difference between a value type and a reference type?Junior
- What is the difference between checked and unchecked exceptions, and how do Kotlin and Swift handle this?Mid-level
- What are type erasure and variance in generics, and how do Swift, Kotlin and Java differ?Senior