[Python-Dev] Vote No on 318 (original) (raw)

Jack Diederich jack at performancedrivers.com
Thu Apr 1 20:11:41 EST 2004


On Thu, Apr 01, 2004 at 03:47:26PM -0500, Raymond Hettinger wrote:

[Jeremy] > There's no particular reason to believe that effort alone will arrive > at > an elegant solution. On the other hand, maybe there isn't a good > syntax > for arbitrary decorators.

IMHO, the best syntax is what we have now. Its only weakness is being distant from the first line in the definition. Other than that, it is understandable, unambiguous, simple, backward compatible, and flexible. A failing common to all of the proposals is that they turn action words (like classmethod) into adjectives with implicit actions. By making them implicit, it becomes less obvious what is occurring, when it is occurring, and, for multiple decorators, which order they occur. That will make the wrapped functions harder to debug. I think of them as annotations instead of adjectives. I sympathize for the 'when it is occuring' but I much prefer it included in the func def than very far away. If it is way after the func/class def it is obvious the action happens afterwards. The trick is noticing it happens at all.

As for implicit, def foo(cls, arg1, arg2): pass # implicitly a classmethod def foo(cls, arg1, arg2) [classmethod]: pass # unambiguously classmethod

A second failing is introducing a second way to do it. The current approach will always be there for some purposes, properties, metaclasses, existing code, or dynamic wrapping. This is a prime example where two ways to do something is especially bad; if you do not see [staticmethod] in the definition, can you presume that it is not a staticmethod -- the answer is clearly no. So, why create optical illusions. Decorators will be unifying, there is currently more than one equal way to do it (metaclasses, frame hacks, inspection, eval'ed docstrings). 'import this' says there should be one obvious way to do it. Decorators (especially the before-colon kind) are obvious. I think 'classmethod' when I've typed 'def foo(cls' next thought classmethod I don't think foo = classmethod(foo) when I've typed 'return'

A third failing is clashing with a design preference for functions/expressions over statements/keywords/syntax. This concept was at the foundation for discussions about having a print() function, using sorted() in an expression, or implementing if-then-else expressions. My understanding of language design history is that of regrets for not using functions wherever possible. 'readability counts', this helps readability for the places where you need it. I'll use decorators more often than genexps, but I like not having to import itertools and calling a function to make an iterator. genexps read like intention, uneccessary function calls read like a recipe. Java is a recipe language, we've all seen comments like "I'm about to do the boilerplate for X, page down for the important stuff" in Java (if you haven't been exposed to Java, feel lucky).

def foo(cls): # see modifiers below a = 1 + 1 b = a * 10 return true foo = classmethod(foo) # boilerplate foo.doc = "This function returns true" # boilerplate (which was rectified)

Also, some proposed uses were strange enough that I wonder whether the syntax encourages people to do weird things with their code. As above, we're cutting out the weird ways people do things now (eval'ing docstrings, examining stackframes, abusing metaclasses) to achieve decorator functionality by making decorators standard. They already had plenty of rope, let's make it all the same color.

-jackdied



More information about the Python-Dev mailing list