What? It's not a big fat lie, it's the exact truth. The same truth you'd get in any language, even Scheme:
> (define a 1)
> (define (f) a)
> (f)
1
> (define a 2)
> (f)
2
That's just how closures work...What? It's not a big fat lie, it's the exact truth. The same truth you'd get in any language, even Scheme:
> (define a 1)
> (define (f) a)
> (f)
1
> (define a 2)
> (f)
2
That's just how closures work...Your example is true at the top level in scheme, but semantics in top (REPL) are different (at least in Racket [0, 1]). In a source file you have to explicitly use set! to mutate a so it is harder to shoot yourself in the foot. In theory the implementation of closures is the same, but in python's case you are free to mutate yourself into unexpected situations. Whereas I'm actually not even sure it is possible to construct a situation in scheme (not at the top level) where you could induce a situation similar to the one in python.
0. https://gist.github.com/samth/3083053 1. https://groups.google.com/d/msg/racket-users/0BLHm18YUkc/BwQ...
In many cases, the "FP paradigm" is very sensible and makes closures safe to work with and easy to reason about, especially in contexts where concurrently running processes could alter the memory underneath you.
iex(1)> a = 1
1
iex(2)> f = fn x -> x + a end
#Function<7.91303403/1 in :erl_eval.expr/5>
iex(3)> f.(1)
2
iex(4)> a = 2
2
iex(5)> f.(1)
2