[Python-ideas] Syntax for defining parametric decorators

Steven D'Aprano steve at pearwood.info
Thu Jul 12 09:05:02 CEST 2012


On Wed, Jul 11, 2012 at 10:19:01PM -0400, Terry Reedy wrote:

> For people 'raised' with imperative languages without nested functions 
> and currying, function currying is definately *not* 'self-explaining'. 
> The difficultly is conceptual, not syntactical. I am 99% sure it would 
> result in more confusion, not less.

I was raised on Pascal, Fortran and Hypertalk, with some Forth-like 
languages (Forth and HP's RPL). None of which are functional, and I had 
never even heard of currying until *long* after starting with Python.

But the idea of a function creating and returning a function was easy to 
understand once it was suggested to me. Once you have the right language 
to talk about a concept, some pretty complex concepts become simple.

I suspect that most of the difficulty people have is because they don't 
clearly distinguish between a decorator and a decorator-factory. Once 
you make the conceptual leap to a function making a function (a 
decorator, which is a kind of function-factory), it is easy to think 
about a decorator-factory, a decorator-factory-factory, and so on. But 
if you don't cleanly distinguish them, in my opinion it becomes 
confusing and unclear whether you need one inner function or two.

Of course, the book-keeping needed to make this all work is not 
necessarily trivial, but it's just book-keeping. New syntax won't make 
that easier.

Singling out decorator-factories for special treatment is, in my 
opinion, a no-go. If this idea is to be sold, decorator-factories may be 
given as just one use-case for syntax for currying.

But frankly, I don't think we need it, or should want it. Python is not 
Haskell, and while it's great to borrow ideas from Haskell (e.g. list 
comprehensions), it is notable that Python hasn't used the exact same 
syntax as Haskell. Compare:

[toUpper c | c <- s]  -- Haskell
[c.upper() for c in s]  # Python

and tell me that "for c in s" isn't more readable than "| c <- s".

I think syntax for currying

def func(a)(b)(c)(d):
    ...

f = func(1)(2)(3)
f(4)

is too Haskell-ish for my taste. I prefer the Python way:

def func(a, b, c, d):
    ...

f = functools.partial(func, 1, 2, 3)
f(4)

even though it is less concise.

I prefer a stronger tool set in functools, including a way to use 
partial on arguments from the right. Perhaps there is a clean API for 
simplifying decorator factories. That could start as a published recipe 
on (say) ActiveState, and then move to functools if there was demand 
for it.

But as usual, the bar to justify new syntax is rightly set much higher 
than the bar to justify new functionality.


-- 
Steven



More information about the Python-ideas mailing list