PEP 309 - Built-in closure type (with tentative syntax proposal)

Peter Harris scav at
Tue Feb 18 13:41:34 CET 2003

Carl Banks <imbosol at> wrote in message news:<lKB2a.32074$F25.10142 at>...
> I hope you're aware that Python (staring from 2.1) already has
> closures (and they're quickly becoming my favorite thing ever).  As
> others have mentioned, what you're proposing is a built-in curry,
> which is just a closure that calls a given function with given
> arguments.
> In fact, the better way to do the above (2.1+) is to use a real
> closure (I'm surprised Martelli didn't point this out):
>     from __future__ import nested_scopes
>     def curry(fn,*cargs,**ckwargs):
>         def call_fn(*fargs,**fkwargs):
>             d = ckwargs.copy()
>             d.update(fkwargs)
>             return fn(*(cargs+fargs),**d)
>         return call_fn
Sweet. I was thinking more of a type though, so that you could sub-class
it and do introspection on it. Maybe even pickle it. (Although what a
pickled curry would taste like I shudder to imagine).

> Concerning the semantics: I have two issues.  First, I generally
> dislike incomplete solutions, and your proposal is incomplete because
> it only allows currying from the left.  Second, there is an
> inconsistency between keyword and position arguments: the curried
> keyword arguments can be overriden by the caller.  I don't like it,
> even if it could be useful.

In languages like Miranda (and in general, for accurate use of the
term 'currying') you can only have left-currying because a function
only ever has one argument. Functions that look as though they take
2 args really take one and return a function that takes another.

Currying from the right leaves you with the problem of what it means
for a right-curried function to take a variable number of arguments,
except in trivial cases where all the positional arguments are treated
the same way.

Overriding the keyword arguments is so useful, what's not to like
about it? If dicts supported __add__ as a copy-and-update union, then
there would be a pleasing symmetry in:
   return f(*(cargs+fargs),**(ckwargs + fkwargs))
Inconsistency is in the eye of the beholder. I think dicts should work
like that, but that's another issue...

> I would like to be able to curry arbitrary arguments.  Something like:
>     curry(fn,__,arg,__)
> where the __ parameters become arguments of the curried function.
> Functions like curryleft could be special cases or something.

Now that is nearly as ugly as my brain-dead @ notation ;)

More information about the Python-list mailing list