[Python-Dev] A usability argument for list-after-def
Phillip J. Eby
pje at telecommunity.com
Thu Aug 5 22:48:09 CEST 2004
Guido has stated he'll accept one community syntax proposal as an
alternative to "@". He's also ruled out his own previous proposal
(list-before-def), and a variety of new-keyword alternatives involving such
things as 'as' and 'with'.
There doesn't appear to be a downside for decorator supporters to put forth
another syntax, if they like it better than "@"; it seems the worst case is
that we still end up with "@", if we end up with any syntax at all.
Of the options on the Wiki page ( at
http://www.python.org/moin/PythonDecorators ), this seems to leave only
list-after-def, the previous community favorite and the first PEP 318
syntax to have been implemented.
Guido's principal argument against list-after-def, if I recall correctly,
was that it is ugly when multiple or lengthy decorators are involved. But,
"ugly" isn't an argument any more, so that shouldn't rule out
list-after-def. :)
I only have one usability argument to favor list-after-def over "@": the
former looks more like executable pseudocode than the latter. If I pretend
that I do not know Python, that I am a programmer who has never written in
Python and is reading a Python program found in a magazine or downloaded
from somewhere, then if I look at:
@events.taskFactory
def monitorProcess(self,process):
...
It is not immediately obvious that the previous line is part of the
function definition; I am put off reading this code, because how do I know
what "@" does?
Brackets are normally used in English to indicate an annotation or "aside"
of some sort; such as a commentary *about* the surrounding material. When
I see this:
def monitorProcess(self,process) [events.taskFactory]:
...
My impression is that the decorator is somehow annotating or subscripting
the function. In this specific example, I might wonder if this is how
Python specifies a function return type. But if I see:
def do_something(cls,data) [classmethod]:
...
I am quickly alerted to this being some kind of annotation about the method
itself, probably akin to public/private/static/friend etc. in other
languages. And, if I look for the definition of 'events.taskFactory' or
'classmethod', I will quickly realize that this is an extensible annotation
facility, as well. By contrast:
@classmethod
def do_something(cls,data):
...
is also suggestive, but I personally find it far less conclusive, even with
'classmethod' as a semantic cue. Drawing on my experience of other
languages and typical uses of "@", I think:
* Is this some sort of array thing? (Perl)
* Is this some sort of documentation tag? (Java... but then I think no,
it's not in a comment, so that can't be it)
* Is this some sort of escape character for literate programming? (e.g.
FunnelWeb and other such tools)
* Is it being used in place of the word "at"? (But what does it mean to
be "at" a class method? It's on a different line; surely if it were
related there would be some sort of syntactic indication like indentation
or a colon or braces or a comma or *something* between it and the definition?)
After some weighing of the evidence, I think I would most likely guess that
this was some sort of documentation markup, rather than semantic
markup. But my train of thought in reading the code has now been quite
disrupted, and if I was reading this code casually I might be discouraged
from continuing, unless I had some reason for wanting to learn Python
besides just reading the code in question or hacking up a quick fix to
something.
Now, I don't know if my thought process here is at all typical or
representative of anything, other than my own idiosyncratic self. But, it
is the one nagging thing that I have against "@", and I suspect that it may
be implicitly behind a lot of the general outcry against it. In other
words, I think that "ugly" is just a pejorative term for the emotional
reaction engendered by being forced to go through the above mental process
for figuring it out. And, to a lesser extent, I think list-before-def
required some of the same mental processing overhead, although I personally
think it was somewhat less than that of "@".
So there it is, my personal argument for list-after-def as better than "@",
even if the list is over multiple lines: it's still much more clearly part
of the function definition, and that IMO is the most important thing the
syntax should convey, apart from listing the decorators themselves.
More information about the Python-Dev
mailing list