remaining decorator syntax options

Steven Bethard steven.bethard at gmail.com
Tue Aug 10 15:33:36 EDT 2004


So here's the state of the decorator debate as I see it:


*** Location

GvR pretty strongly wants decorators before the function:

http://mail.python.org/pipermail/python-dev/2004-August/047112.html
http://mail.python.org/pipermail/python-dev/2004-August/047279.html

The idea being that decorators and other function properties should
not look like part of the function's code.  I don't think there's much
chance of swaying GvR on this count.


*** Indentation

Since location has been pretty much decided, I see three options here:

(1)
<indicator> dec
def f():
    pass

(2)
<indicator>
    dec
def f():
    pass

(3)
<indicator> dec
    def f():
        pass

GvR definitely disliked the third version because it meant that class
functions could all be at different indentation levels.  The PEP
suggests that the second version was disliked because it suggests that
"using" is introducing a new scope (although arguments about if/else
behavior seemed to counter this somewhat).  There didn't seem to be
any arguments that made version 2 drastically better than version 1
though, so it seems most likely that a BDFL pronouncement will give us
version 1.


*** List notation

Assuming a pre-def, non-indented decorator, here are the remaining
list notations:

(1)
<indicator> dec1
<indicator> dec2
<indicator> dec3

(2)
<indicator> [dec1, dec2, dec3]

(3)
<indicator> dec1, dec2, dec3

I believe that version 3 was vetoed because it makes it too hard to
break lists of decorators across lines.  GvR's preference is
definitely for 1, but that may be influenced by his decision for the
indicator.  I have a feeling that how long the indicator is directly
affects which of (1) or (2) is preferred.  Compare:

@dec1
@dec2
@dec3

vs.

@[dec1, dec2, dec3]

and

using dec1
using dec2
using dec3

vs.

using [dec1, dec2, dec3]

It seems like with a single symbol character, the non-list syntax is
much more concise, and probably clearer.  However with a keyword
syntax the list seems the better option.

Which brings us, of course to the final section:

*** Indicator

The options seemed to be:

(1) a symbol (@, |, etc.)
(2) a keyword (using, decorate, etc.)
(3) similar to function
(4) no indicator

Options (3) and (4) were ruled out because (given that we're already
relegated to a before-def syntax) they are already valid syntax, and
redefining them for decorators means changing the expected semantics
of the statements.

Option (1), with @, is GvR's favorite, and does have something of a
Java backing.  It has the substantial disadvantage that there is no
particular reason (or even some sort of mnemonic) for which @ (or |
for that matter) should mean "decorator".

With option (2), we can choose a keyword that does suggest a
decorator.  Even "using", which is not an outstanding choice, is at
least more intuitive than '@'.  Option (2) does have the disadvantage
that it requires introducing a new keyword, but this is not
insurmountable -- it was done before for generators.  And GvR even
said that he would consider this option if there enough support for
it.

----

So here's my suggestions:

Let's leave the location and indentation arguments behind.  We're not
making much progress on them, and I don't think there's much chance of
swaying GvR.  Reiterating all the old arguments won't get us closer to
a syntax we're happy with.

I think once the indicator argument is decided, the list-structure
decision will fall out of it.

So I'd suggest that we put all our effort into the indicator
discussions.  If you have a good argument for why a keyword is better
than a symbol, or why a symbol is better than a keyword, please voice
them now.  And remember that 'because it's prettier' or 'because it's
uglier' are not aguments GvR will consider.  We need strong arguments,
that argue on the basis of readability or learnability or
maintainability, etc.


... and my opinion:

A keyword is much more Pythonic than a symbol:

A well chosen keyword can suggest the meaning of the construction,
e.g. "using ... def ..." suggests that the decorators are used as part
of the definition of the function.  A symbol like '@' or '|' cannot
easily suggest the meaning in this manner.

For this reason, a keyword makes both reading and learning Python
decorator syntax easier.  If you encounter "using ... def ..." and
have to guess at it's meaning, your knowledge of English "using" can
now be applied to guess the meaning of Python "using".  This is not
true of a symbol like '@' or '|'.

(An additional argument might be that it will be at least /possible/
to Google "using", but impossible to do so for "@" or "|".  This was
one of the frustrating things about Perl for me -- if I didn't know
what a symbol did, I couldn't Google it because it wasn't a word. 
Remember that if you don't know it's a decorator, you don't know to
search for "decorate" ;)


hoping-to-keep-this-dicussion-productive-ly-yrs,

Steve



More information about the Python-list mailing list