Fair enough, I think my complaint is more about the fact that closures and python are not accompanied by a safety net the way they are in some other languages, that doesn't make them not closures, it just makes them a less useful abstraction (I've basically given up on using anything other than full objects and list comprehensions in python due to the countless subtle and often silent irregularities in how a form behaves when used in different contexts).
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.
In all brutal honestly I think you just need to realize this is just you being upset at having shot yourself in the foot at some point (don't worry, we've all done it) and then trying to blame it on closures somehow, in this case by saying this makes them a "less useful abstraction". In all honesty, no, it just doesn't. It makes them more useful. If I can make an analogy, it's a bit like saying bicycles should only have fixed gears as a "safety net" because you've broken or slipped your variable gears in the past and now you've just learned to take a car or train if you want to go faster than first gear. I mean, that's definitely one way to live your life, but most people don't do it that way... they just realize their mistakes are a natural artifact of being in the learning process and instead of abolishing gears, they keep practicing more so that they eventually get the muscle memory to use their vehicle properly and don't have to think about this problem every time. That's the way to solve the problem for good -- so you can avoid the downsides while reaping the benefits at the same time.
It's not categorically how closures work, it's just that in python (and most other languages, including julia), you bind to effectively "a pointer to the value". In FP paradigm, you typically bind to "the value at function creation time".
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
Elixir doesn't have mutable variables though. Is there any language that has mutable variables and closes over the value of a variable and not a "pointer to the value"?
What? It's not a big fat lie, it's the exact truth. The same truth you'd get in any language, even Scheme:
That's just how closures work...