Opening Scenario
You're writing a factory that builds button handlers in a loop:
# Python
handlers = []
for i in range(3):
handlers.append(lambda: print(f"clicked {i}"))
for h in handlers:
h()You expected clicked 0, clicked 1, clicked 2. You got:
clicked 2
clicked 2
clicked 2A colleague suggests handlers.append(lambda i=i: print(f"clicked {i}")). It works, and they mutter something about "closures capturing by reference, not by value." Another colleague says "Java's lambdas would have rejected this at compile time because i isn't effectively final." A third says "in C++ you have to write [i] instead of [&i]."
Three languages, three flavors of the same underlying question. What is a closure actually capturing, and what makes a "higher-order function" the natural home for it?
Question Progression
Q1: What does a function "remember" from the place it was defined?
Question: A plain function is just code you can call. A closure is described as "a function that remembers…
In the full tutorial
- When to Reach for This