On Fri, 2011-09-30 at 11:39 -0600, Eric Snow wrote:
On Fri, Sep 30, 2011 at 10:45 AM, Jan Kaliszewski
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