[Python-ideas] Syntax for defining parametric decorators

Haoyi Li haoyi.sg at gmail.com
Mon Jul 9 11:07:49 CEST 2012


I admit calling it all at once would be very strange, but i still think
the "call me three times to get result" comes across waaaay more
clearly than with nested defs.

Multiple arguments in one list is about the same, it's true, until you
really need the curried version, like in decorators, then you end up
with the nasty tower-of-defs which sparked this discussion.

Regarding "not knowing how many times it should be called", the idea is
that you break it up when you have a meaningful, reusable unit. That's
to say you wouldn't do a

def f(a)(b)(c)

Unless

f
f(1)
f(1)(2)
f(1)(2)(3)

Are all meaningful, useful functions. Doesn't happen very often,
granted, but when it does (e.g. for decorator factories and decorators)
it'd be nice to have.

I view curried defs like default parameters: Doesnt add anything that
cant already be done (you can emulate default args with telescoping
methods) but cuts boilerplate, makes things clearer and overall nice to
have. Whether it's nice enough to justify extra syntax is of course
open for debate.

From: Stephen J. Turnbull
Sent: 7/9/2012 1:48 AM
To: Haoyi Li
Cc: Nick Coghlan; Python-Ideas
Subject: Re: [Python-ideas] Syntax for defining parametric decorators
Haoyi Li writes:

 > However, I think that in the general case, being able to define
 > curried functions in one line, a.l.a.
[...]
 > def f(a)(b)(c)
 >
 > looks much more similar to how you would use it:
 >
 > f(1)(2)(3)

I don't understand.  I wouldn't use it that way!  I would think if
that were common usage, and the curried form only occasional,

    def f(a,b,c):
        pass

    f(1,2,3)

would be more natural in Python (and use functools.partial for the
occasional currying).  Presumably if you were using this syntax, you'd
be doing something more like

    def f(a)(b)(c):
        pass

    def g(h, x):
        h(x)

    g(f(1)(2), 3)

which doesn't look very nice to me, nor do I find the def to be a
particularly intuitive way of reminding me that the proper usage is a
call of a function in curried form (specifically, I would not be
reminded of whether the expected curried form is a 1st-, 2nd-, or
3rd-order function).

I also suppose that you wouldn't be able to do

    def f(a)(b)(c):
        pass

    def g(x,y):
        pass

    h(f(1))
    h(g)

(ie, without LBYL or EAFP constructs in h, which would simply be
throwing the complexity into the caller's backyard).  Even though

    def bar(a)(b):
        pass

    def baz(x):
        pass

    quux(bar(1))
    quux(baz)

would work fine.

So to me, there may be something in this syntax, but my initial
impression is that it's trying to turn Python into something it's not.



More information about the Python-ideas mailing list