Jan Kaliszewski wrote:
My propositions don't make that hack less acceptable -- proposing an alternative.
You seem to be proposing yet another feature whose main purpose is to patch over a mismatch between existing features. That's not the path to elegant language design.
Do you mean that each iteration should create separate local scope?
Or that the loop variable should be treated specially?
Yes, but in a way that you're probably not expecting. :-)
My proposal is that, if the loop variable is referenced by an inner function (and is therefore in a cell), a new cell is created on each iteration instead of replacing the contents of the existing cell.
This would mean that:
* If the loop variable is *not* referenced by an inner function (the vast majority of cases), there would be no change from current semantics and no impact on performance.
* In any case, the loop variable can still be referenced after the loop has finished with the expected results.
One objection that's been raised is that, as described, it's somewhat CPython-specific, and it's uncertain how other Pythons would get on trying to implement it.
i_lambdas, j_lambdas = ,  for i in range(10): j = i i_lambdas.append(lambda: i) j_lambdas.append(lambda: j) print(i_lambdas()) # would print 2 print(j_lambdas()) # would print 9
Yes, that's true. An extension to the idea would be to provide a way of specifying cell-replacement behaviour for any assignment, maybe something like
j = new i
Then your example would print 2 both times, and the values of both i and j after the loop would be 9.
One slightly curly aspect would be that if you *changed* the value of i or j after the loop, the change would be seen by the *last* lambdas created, and not any of the others. :-) But I find it hard to imagine anyone doing this -- if you're capturing variables in a loop, you don't normally expect to have access to the loop variable at all after the loop finishes.