[Python-Dev] Yet Another Decorator Syntax Suggestion (YADSS)
Mike Thompson
mike.spam.filter at day8.com.au
Mon Mar 29 02:11:09 EST 2004
I wonder if, as a lurker, I might make YADSS ... I'm not confident
enough to argue my case too strongly, but thought I'd toss it into the
ring as part of the creative process.
Background
----------
I believe that cognitively speaking, when a function is first being
understood by a reader, decorators need to be seen BEFORE the other
details of the function (even its name). Understanding that a function
is a 'classmethod', provides crucial context for understanding the
function's name, argument list, documentation and body. So, I believe
'classmethod' should be seen first in the function definition.
I believe this requirement has motivated some to support syntax where
the decorator list is promoted to be 'early' in the 'def':
def [classmethod] func(args)
OR def func [classmethod] func(args)
etc.
That would be fine except that there is another 'competing' use case:
once a function is known and understood, a programmer often needs to
quickly look up its argument list.
This use case has tended to support syntax which places the function's
decorators 'late' in the 'def', out the way, after the arguments:
def func(args) [ decorators ]:
OR def func(args) as decorators:
I believe the 'syntactic tension' between these two use cases(1. first
understanding, 2. later argument look up) will be impossible to resolve
with any 'inline' syntax solution. (By 'inline' I mean syntax which
tries to cram decorators into the 'def' line as is).
Finally, both the 'early' and 'late' decorator syntax have another
problem: they don't scale nicely. The argument and decorator lists
could be long; far too long for one line. That means the 'def' line has
to be split and while solutions have been found for this in 'late'
syntax form, I can't believe that anyone is really *that* happy with the
look of the them. 'early' syntax and long decorator lists look
particularly ugly, IMO.
YADSS
-----
SO. For all these reason, I propose another approach. I'd argue that a
multi line, more stuructured 'def' solution is required.
I propose that the 'as' keyword be used together with whitespace
indentation before the 'def' to *optionally* decorate the def, something
like this:
as:
classmethod
def func(arg):
pass
This solution scales up reasonably to multiple decorators:
as:
runOnExit
staticmethod
syncronisedWith(attr='lock')
attributedBy(
author='MT',
release='5.4'
)
returns(int)
takes((int, int))
def func(args):
pass
Can be used with classes as well ...
as:
providerOfInterface(IBar)
syncronsiedWith(attr='_lock')
singleton
class K
pass
For simple functions, perhaps the entire 'function header' can be folded
onto two lines:
as: classmethod
def func(args)
pass
OR, perhaps even one line (possible with parser?):
as: classmethod def func(arg):
pass
Not too sure about this last suggestion.
Pros
----
- use of white space indentation and ':' consistent with
other blocks in Python.
- simple cases present simply, but it scales well to complex cases
- places decorator upfront, but leaves function arg list easy
to scan
- does not require new keyword
Cons
----
- 'as' might not be the perfect word. Then again what would be?
- some won't like that 'def' is not the first word in a definition
I hope this is useful food for thought, amongst those that know more
(and do more for) Python than I.
<later>
Damn. I just re-read PEP-318 and found it included a syntax similar to
that which I propose. Something from Quixote which uses 'using' where I
have used 'as'.
I'm going to post this anyway because:
1. This approach is not getting much air-play and I
belive it should; and
2. Because the use of 'as' I propose does not require a new
keyword, which is a significant bonus over making a new
keyword 'using'.
--
Mike
More information about the Python-Dev
mailing list