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 2

A 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

Glossary history

Click dotted jargon to save explanations here.