[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