Thanks for the concise review of Python’s closure behavior. It seems like Python is the main language that people are coming from when they find Julia’s closure behavior to be unexpected, especially since Julia’s closure behavior is, as @Tamas_Papp and I have both noted, completely standard for Lisp and most other programming languages that allow inner functions that capture local variables — it is the standard notion of what a “closure” is. When people over the decades have complained that functional programming in Python is hard because it doesn’t have closures, this is what they’re complaining about.
It’s interesting that Rust makes a distinction between an inner function and a closure based on syntax. I can see the logic behind that, but it adds complexity to the language: in Julia there is only one kind of inner function / closure and the do syntax is a purely syntactic convenience; in Rust there are at least two different kinds of inner function that behave differently and that programmers have to understand.