[Python-Dev] accumulator display syntax

Phillip J. Eby pje at telecommunity.com
Tue Oct 21 19:47:58 EDT 2003


At 04:30 PM 10/21/03 -0700, Guido van Rossum wrote:
> > Actually, I consider Samuele's example a good argument in *favor* of
> > the idea.  Because of the similarity between listcomps and generator
> > expressions (gen-X's? ;) ) it seems late binding of locals would
> > lead to people thinking the behavior is a bug.  Since a genex is not
> > a function (at least in form) a late binding would be very
> > non-obvious and counterintuitive relative to other kinds of
> > expressions.
>
>Hm.  We do late binding of globals.  Why shouldn't we do late binding
>of locals?

Wha?  Oh, you mean in a function.  But that's what I'm saying, it's *not* a 
function.  Sure, it's implemented as one under the hood, but it doesn't 
*look* like a function.  In any normal (non-lambda) expression, whether a 
variable is local or global, its value is retrieved immediately.

Also, even though there's a function under the hood, that function is 
*called* and its value returned immediately.  This seems consistent with an 
immediate binding of parameters.


>   There are lots of corners or the language where if you
>expect something else the actual behavior feels like a bug, until
>someone explains it to you.  That's no reason to compromise.  It's an
>opportunity for education about scopes!

So far, I haven't seen you say any reason why the "arguments" approach is 
bad, or why the "closure" approach is good.  Both are certainly Pythonic in 
some circumstances, but why do you feel that one is better than the other, 
here?

I will state one pragmatic reason for using the default arguments approach: 
code converted from using a listcomp to a genex can immediately have bugs 
as a result of rebinding a local.  Those bugs won't happen if rebinding the 
local has no effect on the genex's evaluation.  (Obviously, an aliasing 
problem can still be created if one modifies a mutable used in the genex, 
but there's no way to remove that possibility and still end up with a lazy 
iterator.)

Given that one of the big arguments in favor of genexes is to make 
"upgrading" from listcomps easy, it shouldn't fail so quickly and 
obviously.  E.g., converting from:

x = {}
for i in range(10):
     x[i] = [y^i for y in range(10)]

to:

x = {}
for i in range(10):
     x[i] = (y^i for y in range(10))

Shouldn't result in all of x's elements iterating over the same values!




More information about the Python-Dev mailing list