[Python-Dev] Re: A syntax for function attributes?
Paul Moore
pf_moore@yahoo.co.uk
Thu, 31 Jul 2003 19:58:40 +0100
"Phillip J. Eby" <pje@telecommunity.com> writes:
> I agree with the need to put information about a method near the
> definition, but I don't think that we need a separate syntax
> specifically for function attributes. I think that with PEP 318 or
> some variant thereof, it is trivial to create an 'attrs(foo=bar,
> baz=spam)' function that can be used as a decorator, eg. in
> conjunction with classmethod.
To be honest, the *only* serious reason for any of this syntax (PEP
318, something for attributes, whatever) is to keep metadata near the
definition (or at least, the def statement, rather than after the
code...)
I like Michael Hudson's variation on PEP 318,
def f() [mod1, mod2]:
pass
It's minimal, flexible, and has an implementation.
The downsides that I see are:
1. It doesn't help with properties. To be honest, I don't see this as
much of an issue, as properties are a very different beast (they
effectively combine multiple functions in one). People have
demonstrated clever hacks to make properties possible, which leads
me nicely to...
2. It's possibly *too* flexible. The temptation to define clever hacks
may be just a little high. The example of attrs() mentioned above
is a good example. It satisfies a real need, it's simple, and it's
easy to implement via the [...] syntax. But is it really the best
way of handling function attributes? I really don't know, without
trying it out. And that leads me onto...
3. It's almost impossible to tell whether it will look right in
practice, without implementing it and trying it out. And once that
happens, it'll probably never get removed, even if it's *not* the
right answer.
The canonical function modifier is classmethod (or staticmethod), and
for that, Michael's syntax
def f(...) [classmethod]:
pass
looks great.
My canonical case for function attributes comes from the parser Spark,
which (mis-)uses docstrings to contain the grammar rule for which the
function is an action:
def p_expr_term(self, args):
'''
expr ::= expr + term
term ::= term * factor
'''
return AST(type=args[1],
left=args[0],
right=args[2])
To me, this certainly *isn't* going to work with something like
attrs() - imagine
def p_expr_term(self, args) [attrs(
rule='''
expr ::= expr + term
term ::= term * factor
''')]:
return AST(type=args[1],
left=args[0],
right=args[2])
Yuk.
The current function attribute syntax
def p_expr_term(self, args):
return AST(type=args[1],
left=args[0],
right=args[2])
p_expr_term.rule = '''
expr ::= expr + term
term ::= term * factor
'''
looks better than that, IMHO.
I'm sorry, this rambled on a bit. I think that, in summary, my points
are:
* My preferred solution for PEP 318 is Michael Hudson's patch.
* It may be too general, in tempting people to mis-use the feature
in inappropriate ways (but what the heck, anything can be
misused, at some level).
* I don't think there's an obvious solution for function
attributes yet.
* I think properties are another unsolved problem.
It's also interesting to note that classmethod/staticmethod and
properties get used in spite of the lack of syntactic support, whereas
function attributes generally don't seem to. I'm not quite sure what
this implies about the usefulness of function attributes...
Hope this was useful,
Paul
--
This signature intentionally left blank