[Python-ideas] Tweaking closures and lexical scoping to include the function being defined
Ron Adam
ron3200 at gmail.com
Sat Oct 1 18:58:21 CEST 2011
On Sat, 2011-10-01 at 13:44 +0200, Jan Kaliszewski wrote:
> Jan Kaliszewski dixit (2011-09-30, 23:32):
>
> > Nick Coghlan dixit (2011-09-30, 14:14):
> >
> > > If a "function state decorator" approach is used, then yeah, I agree
> > > it should come immediately before the main part of the function
> > > header.
> >
> > Yes, it seems to be a necessary requirement.
> >
> > > However, I'm not seeing a lot to recommend that kind of syntax
> > > over the post-arguments '[]' approach.
> >
> > IMHO @(...) has two advantages over '[]' approach:
> >
> > 1. It keeps all that 'additional scope'-stuff in a separate line, making
> > the code probably more clear visualy, and not making the crowd of
> > elements in the '...):' line even more dense (especially if we did use
> > annotations, e.g.: '...) -> "my annotation":').
> >
> > 2. It is more consistent with the existing syntax (not introducing
> > '='-based syntax within []; [] are already used for two different
> > things: list literals and item lookup -- both somehow leading your
> > thoughts to sequence/container-related stuff).
>
> And also -- what maybe is even more important --
>
> 3. Placing it before (and beyond) the whole def statement makes it
> easier to *explain* the syntax:
>
> @(x=1, lock=Lock())
> def do_foo(y):
> nonlocal x
> with lock:
> x += y
> return x
Supposedly the @ decorator syntax is supposed to be like a pre-compile
substitution where..
@decorator
def func(x):x
Is equivalent to...
def func(x):x
func = decorator(func)
IF that is true, it doesn't make the python core more complex. It would
just be a source rewrite of the effected block in memory just before
it's compiled.
But it seems it's not implemented exactly that way.
def deco(func):
def _(f):
return func(f)
return _
@deco(foo)
def foo(f):
return f
print(foo('python'))
Results with ... NameError: name 'foo' is not defined
def foo(f):
return f
foo = deco(foo)
print(foo('python'))
Prints "Python" and doesn't cause a name error.
Is this a bug, or by design?
I thought, if the @@ wrapper idea could be put in terms of a simple
substitution template like the @ design, then it may be more doable.
Cheers,
Ron
> as being equivalent to:
>
> def _closure_provider():
> x = 1
> lock = Lock()
> def do_foo(y):
> nonlocal x
> with lock:
> x += y
> return x
> return do_foo
> do_foo = _closure_provider()
> del _closure_provider
More information about the Python-ideas
mailing list