[Python-ideas] Tweaking closures and lexical scoping to include the function being defined

Ron Adam ron3200 at gmail.com
Fri Sep 30 20:11:58 CEST 2011


On Fri, 2011-09-30 at 11:39 -0600, Eric Snow wrote:
> On Fri, Sep 30, 2011 at 10:45 AM, Jan Kaliszewski <zuo at chopin.edu.pl> wrote:
> > Ron Adam dixit (2011-09-30, 00:25):
> >
> >> How about anonymous wrappers?
> >>
> >>   @@(x=0)
> >>   def adder(y):
> >>       nonlocal x
> >>       x += y
> >>       return x
> >>
> >> which would be the same as...
> >>
> >>   def _(x=0):
> >>       def adder(y):
> >>           nonlocal x
> >>           x += y
> >>           return x
> >>       return adder
> >>   adder = _()
> >
> > +1, though I'd rather prefer simply:
> >
> >    @(x=0)
> >    def adder(y):
> >        nonlocal x
> >        x += y
> >        return x
> >
> > And, of course, if you don't need to rebind the variable, `nonlocal`
> > would not be needed:
> >
> >    @(lock=threading.RLock())
> >    def my_foo():
> >        with lock:
> >            "do foo"
> >
> > IMHO it is better than @nonlocal because it uses already settled
> > @-decorator idiom and at the same time it does not pretend to be a
> > normal fuction-based decorator.
> >
> > I like it. :) I think it would be not only clear and useful but also
> > beautiful.
> 
> On its own it actually looks very appealing.  And it may still be
> fine.  However, when mixed with decorators, it may be too ambiguous:
> 
>    @(lock=threading.RLock())
>    @does_something_else
>    def my_foo():
>        with lock:
>            "do foo"
> 
> or
> 
>    @does_something
>    @(lock=threading.RLock())
>    @does_something_else
>    def my_foo():
>        with lock:
>            "do foo"
> 
> What does "@(lock=threading.RLock())" do here?  It would be easy to
> miss that it affects "my_foo" (at compile-time) and not the result of
> "@does_something_else" (at def-time).  This is the problem with mixing
> the syntax for a compile-time directive with that of a def-time
> directive, particularly when they can show up right next to each
> other.

I was thinking it would only be allowed just before def statement,
(Thats why I used '@@' instead of just '@')  If it's out of place then
it would be treated just like any other decorator.

>>> @_()
... @deco
... def foo():pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_' is not defined

And of course cause an error. ;-)

(Just maybe not that exact one.)

Cheers,
   Ron


> This is a possible solution: a syntax requirement that no real
> decorators come after this new syntax.  I'm still cautious about the
> idea of sharing syntax between compile-time and def-time directives.
> However, default arguments sort of do this already.
> 
> -eric





More information about the Python-ideas mailing list