[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