Exercise 2: Reassignment Between Declaration and Call — Possible Solution ==================================================================== THE PROGRAM ------------------------------ var x = "before"; fun show() { print x; } x = "after"; show(); RESULT ------------------------------ after WHY THIS WORKS AS AN ANSWER ------------------------------ "before" would be the answer if closures captured a SNAPSHOT of variable VALUES at declaration time -- as if Python evaluated `x` right then and baked the string "before" permanently into the function. That is not what happens. WispFunction.closure holds a reference to the global Environment OBJECT itself (the one active when `fun show()` executed), not a copy of what that environment happened to contain at that instant. When `x = "after";` runs, it's Environment.assign() being called on that exact same global environment object -- the identical object `show`'s own closure already points to. No new environment is created, nothing is copied; the one global environment's `values` dict simply has its `x` entry overwritten in place. By the time `show()` actually executes and its body evaluates `x` via `self.env.get('x')` walking up through the closure chain, it reaches that same, now-updated dict entry and reads "after" -- the current value, not whatever value happened to exist at the moment `show` was declared. This is the same mechanism the chapter's own counter-factory example relies on (a closure seeing count go 1, 2, 3 across repeated calls), just demonstrated here with a plain reassignment instead of a `+= 1` style increment, and with the mutation happening BEFORE the closure is ever called rather than between two calls to it. Both cases boil down to the identical fact: `self.closure` is a reference to a live, mutable Environment object, and "capturing" a variable means capturing a place to look it up later, not a value to remember right now.