From: geremy condra on 12 Jul 2010 00:18 On Sun, Jul 11, 2010 at 11:39 PM, Carl M. Johnson <cmjohnson.mailinglist(a)gmail.com> wrote: > On Sun, Jun 27, 2010 at 8:25 PM, Nick Coghlan <ncoghlan(a)gmail.com> wrote: > >> The availability of "nonlocal" binding semantics also makes the >> semantics much easier to define than they were in those previous >> discussions (the lack of clear semantics for name binding statements >> with an attached local namespace was the major factor blocking >> creation of a reference implementation for this proposal back then). >> >> For example: >> >> c = sqrt(a*a + b*b) where: >> a = retrieve_a() >> b = retrieve_b() >> >> could translate to something like: >> >> def _anon(): # *(see below) >> nonlocal c >> a = retrieve_a() >> b = retrieve_b() >> c = sqrt(a*a + b*b) >> _anon() >> >> *(unlike Python code, the compiler can make truly anonymous functions >> by storing them solely on the VM stack. It already does this when >> executing class definitions): > > I like this idea, but I would tweak it slightly. Maybe we should say > > EXPRESSION where: > BLOCK > > is equivalent to > > def _(): > BLOCK > return EXPRESSION > _() > > That way, c = a where: a = 7 would be equivalent to > > def _(): > a = 7 > return a > c = _() > > One advantage of this equivalence is it would make it easier to work > around a longstanding scoping gotcha. A naïve coder might expect this > code to print out numbers 0 to 4: > > >>> fs = [] > >>> for n in range(5): > ... def f(): > ... print(item) > ... fs.append(f) > ... > >>> [f() for f in fs] > 4 > 4 > 4 > 4 > 4 > [None, None, None, None, None] > > I think we all have enough experience to know this isnt a totally > unrealistic scenario. I personally stumbled into when I was trying to > create a class by looping through a set of method names. > > To get around it, one could use a where clause like so: > > fs = [] > for n in range(5): > fs.append(f) where: > shadow = n > def f(): > print(shadow) > > This would print out 0 to 4 as expected and be equivalent to > > >>> fs = [] > >>> for n in range(5): > ... def _(): > ... shadow = n > ... def f(): > ... print(shadow) > ... fs.append(f) > ... _() > ... > >>> [f() for f in fs] > 0 > 1 > 2 > 3 > 4 > [None, None, None, None, None] > > I think a where-clause with def-like namespace semantics would be a > positive addition to Python, once the moratorium is up. > > -- Carl Johnson +1 from me, FWIW Geremy Condra
|
Pages: 1 Prev: IOError and Try Again to loop the loop. Next: Learn Python the Hard Way (online tutorial) |