[Python-Dev] Decorators with arguments are curries!

Andrew Durdin adurdin at gmail.com
Sat Aug 7 14:36:59 CEST 2004


Having waded through all the decorator syntax discussions recently,
and some of the historical ones, I haven't found this point mentioned
before, so I'll bring it up now:

Consider the following code:

def foo(bar):
   return 1

a = foo
a = foo(bar)

The first assignment to a is binding a reference to a function; the
second is calling the function. This is a very significant difference
in python, and I'm concerned that all the current proposed decorator
syntaxes[*] are liable to cause confusion on this point. For example:

def foo_decorator(func):
    print "no params to this"
    return func

def bar_decorator(func, param):
    print param
    return func

@foo_decorator
@bar_decorator("one param here")
def decorated_func():
    pass

Here the first decorator statement is bare, while the second one
includes parentheses and an argument; the first one looks like a
function reference, while the second looks like a function call.
I find this confusing; semantically, this appears to equivalent to
(assuming expressions are allowed in decorator statements):

# using curry as proposed in PEP 309 [**]
@foo_decorator
@curry(bar_decorator, "one param here")
def decorated_func():
    pass

Most of my concern here is that this aspect of decorator syntax
appears to be implicitly introducing a currying syntax in one special
circumstance, which is then *not* transferable to currying functions
in normal situations, as it would conflict with function calling. And
if a currying syntax (or built-in) was introduced down the track, then
these decorators would be inconsistent with them.

Has anyone else noticed this issue?

Andrew Durdin

[*] Except those which don't allow for arguments
[**] For a nice coincidence, PEP 309 suggested using '@' to mark curries


More information about the Python-Dev mailing list