Maybe, just maybe @decorator syntax is ok after all

Mark Bottjer mark_bottjer at
Mon Aug 9 01:28:37 CEST 2004

AdSR wrote:
> You know what, I'm starting to feel the same. Yesterday Anthony
> Baxter mentioned this URL:
> where GvR says:
> """ Given that the whole point of adding decorator syntax is to move
> the decorator from the end ("foo = staticmethod(foo)" after a
> 100-line body) to the front, where it is more in-your-face, it should
> IMO be moved all the way to the front. """

I saw this quote, too, but it did not sway me. I've felt ever since the 
C89 days that having too much stuff before the name being defined is an 
impediment to understanding the code:

   So, let's see here. We have a class method. It's memoized, it's
   transacted, and it's ACID. Okay, so far, so good. It's takes two ints,
   and returns an Exception. Okay. It was created on July 17, 2005, at
   3:13:32 in the morning EST, by a guy named Guido. Good to know.

   And it's named 'foo'. Which sucks, because I was looking for 'bar'.

   Where was I again?

Having all this stuff before the *name* of the thing being defined is 
distracting. First tell me what it's *called*, then I'll decide if I 
want to know more or not.

Ever look at Java code? Abominations like "public static final 
synchronized f() {}" litter the code. *shudder* How is one supposed to 
navigate code like this?

> And I had the sudden feeling that I finally got it. You see, for me, 
> the @decorator syntax is a declaration - first thing that came to my 
> mind was Pascal's "forward". So it says "take the def that follows
> and insert a (old style) decoration line in the code after it." Note
> that here the "def" is recursive - it may have other @decorators
> before it.

That is the intent as I understand it. It even sounds reasonable, at 
first blush. But Python is not supposed to need forward declarations. 
And the other way of looking at it (an implicit stack of decorators held 
by the parser, to be applied to the "next X" found) is equally strange.

Also, psychology tells us that people like to pick a starting location, 
and move in one direction from there. We're all familiar with this: this 
is how books are laid out. Having to scan *both* directions to see all 
the pertinent information is like having the chapter title in the middle 
of the chapter.

I'll kick this horse once more: if we were take this prefix idea to it's 
logical conclusion, we'd put the function body before the function name!

     global x
     x *= a
   def f( a)

This ain't Python to me.

People don't do well with prefix or postfix; we want infix or 
sequential. That is why so many people still use "algebraic" calculators 
even when RPN is often faster and requires less button presses. 
Everything else in Python is either infix or sequential, why start 
prefixing stuff now?

> Speaking of loop statements, they have an optional else clause that 
> isn't obvious either. It means "do this if there was no break-exit 
> from the loop." Yet for me the obvious meaning would be "if there
> were no loop passes" - that is, the while condition was false on the
> first entry or the for list was empty. I think the word "finally"
> would be more to the point here (and it's a keyword anyway).

Except that finally blocks *always* get executed; while else blocks get
executed only if the loop completes normally. I agree that it is an odd
word choice, but I assume they were simply trying to reuse a keyword.

> I think having some obscurity in the language is inevitable. The 
> present way of applying decorators (x = decor(x)) is equally cryptic 
> to a newbie as the @decor syntax will be - first you have to know
> what a decorator is. There even aren't any decorators used in the
> standard lib - or at least grep doesn't show any static/classmethod
> rebindings.

Right. The only benefit of decorators is that they get the decoration 
closer to the start of the decorated. Locality matters when trying to 
understand code.

   -- Mark

More information about the Python-list mailing list