For the most part you've taken the words out of my mouth! Some more details...
On Saturday, October 1, 2016 at 6:16:32 AM UTC+5:30, Gregory Ewing wrote: > Steve D'Aprano wrote: > > Giving for-loops their own namespace is a grossly unintuitive and a very > > weird thing to do. > > > > It would be terribly inconvenient and surprising for if...else blocks to be > > separate namespaces: > > There's an important difference between a for-loop and an > if-statement that's relevant here: a for-loop binds a name, > whereas an if-statement doesn't. > > Whenever there's binding going on, it's necessary to decide > whether it should be creating a new binding or updating an > existing one. > > This is actually a *different* issue from one of scope. > List comprehensions were changed so that the loop variable > lives in a different scope from the containing function. > However, they still have the same unintuitive behaviour > with regard to capture of the loop variable by a lambda. > > >> l = [lambda: i for i in range(3)] > >>> for f in l: print(f()) > ... > 2 > 2 > 2 > > Most people consider *this* behaviour to be far weirder > than anything that would result from giving for-loop > variables their own scope. > > Even if you don't think it's weird, it's hard to argue > that it's *useful* in any significant number of cases. > > > To me, "make for-loops be their own scope" sounds like a joke feature out of > > joke languages like INTERCAL. > > Which is a straw man, since that's not actually what we're > talking about doing. It's neither necessary nor sufficient > to solve the problem. > > What *is* necessary and sufficient is to make each iteration > of the for-loop create a new binding of the loop variable > (and not any other variable!). Yes one basic problem with comprehensions in python is that they are defined by assignment not binding to the comprehension variable > > > I'm not aware of any sensible language that > > does anything like this. > > Scheme and Ruby come to mind as examples of languages in > which the equivalent of a for-loop results in each iteration > getting a new binding of the control variable. Although > you could argue that these languages are not "sensible". :-) Python copied comprehensions from haskell and copied them wrong Here are all the things (that I can think of) that are wrong: 1. Scope leakage from inside to outside the comprehension 2. Scope leakage from one value to the next 3. The name 'for' misleadingly associates for-loops and comprehensions 4. The for-loop based implementation strategy made into definitional semantics 5. The absence of simple binding inside comprehensions: [f(newvar) for v in l newvar = rhs] 1 was considered sufficiently important to make a breaking change from python2 to 3 2 is what causes the lambda gotcha 3 is what makes noobs to take longer than necessary to grok them 4 is what causes a useless distinction between 1 and 2 — scope leakage is scope leakage. The explanatory mechanisms of why/whither/what etc should at best be secondary 5. is workaroundable with a [... for newvar in [rhs]] Possible and clunky -- https://mail.python.org/mailman/listinfo/python-list