[Python-Dev] Vote No on 318

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