@decorators
Mark Bottjer
mark_bottjer at hotmail.com
Fri Aug 6 17:01:42 EDT 2004
David Fraser wrote:
> I like this idea. What about using the list syntax instead of the @
> syntax:
>
> [static, synchronized, types(int, int), returns(None) ]:
> def foo():
> pass
<rant level="hysterical">
No, no, NO! Lists are value expressions: not statements, not
declarators, and most certainly not suites!!!
</rant>
Sorry, just had to get that out of my system... :)
Seriously, though, one problem I see is that this can get obfuscative
really fast as the number or complexity of decorators grows:
[static,
synchronized,
types(int, int),
returns(None),
yet,
more,
decorators,
go,
here,
making(this),
quite,
the( (pain, to, read, past))
]:
def foo():
pass
By the time I've read all of that, I've likely forgotten what it was I
was looking for in the first place. Of course, the @ syntax as it stands
has the same problem, but at least it doesn't introduce spurious
indentation in the process.
> This would then take away the argument against a valid list before a
> def being valid python but not previously having any effect...
Right. At the expense of a grammar that is nonsensical when viewed in
the context of how those symbols work elsewhere in the language. Here we
have a list (okay), containing a bunch of function names (okay), which
get called via side-effect on something not explicitly indicated
(er...), and starts a block of code (say what???).
The (){}[] symbols all already *mean* something in python (often more
than one thing, actually). The @ doesn't mean anything yet, so it is a
perfect candidate for a completely new concept such as this. I just
think that they put it in the wrong spot.
> declare [static, synchronized, types(int, int), returns(None)]:
> def foo():
> pass
> def bar():
> pass
People keep suggesting this one, and I just don't see it. Yes, it's
shorter (marginally, sometimes). But is it really clearer? I don't think
so. Now, instead of just having to look at the preceding few lines to
figure out what decorators are being used, you have to look up an
arbitrary number of lines. Not fun when one's functions start getting
real-world sized.
I understand the desire to reduce the redundancy, but even this small
example shows a fundamental problem with this approach. In all but the
most simple cases, most functions will end up with *different* sets of
decorators. Case in point: both foo and bar above take (int, int) and
return None. Such parity rarely survives in the wild. This leaves us
with even more of a mess:
declare [static, synchronized]:
declare [returns(None)]:
declare [types(int)]:
def foo(a):
pass
declare [types(int, int)]:
def bar(a, b):
pass
declare [returns(int)]:
def baz():
pass
I *shudder* to think of trying to sort this out when these functions
contain real code.
(FYI: None of this is directed at you, personally. Your post just
happened to be the first post I found suggesting this kind of syntax.)
-- Mark
More information about the Python-list
mailing list