[Python-ideas] 'Injecting' objects as function-local constants
Greg Ewing
greg.ewing at canterbury.ac.nz
Tue Jun 14 00:19:01 CEST 2011
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?
No...
> 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[2]()) # would print 2
> print(j_lambdas[2]()) # 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.
--
Greg
More information about the Python-ideas
mailing list