Partially evaluated functions

Nick Perkins nperkins7 at home.com
Wed Jun 20 01:36:21 EDT 2001


"Rainer Deyke" <root at rainerdeyke.com> wrote:
> ...
> class curry:
>   def __init__(*args, **kwargs):
>     self = args[0]
>     self.function = args[1]
>     self.args = args[2:]
>     self.kwargs = kwargs
>   def __call__(*args, **kwargs):
>     kwargs.update(self.kwargs)
>     return self.function(self.args + args, kwargs)
> ...

This is pretty close to the cookbook version:

http://aspn.activestate.com/ASPN/Python/Cookbook/Recipe/52549
class curry:
    def __init__(self, fun, *args, **kwargs):
        self.fun = fun
        self.pending = args[:]
        self.kwargs = kwargs.copy()

    def __call__(self, *args, **kwargs):
        if kwargs and self.kwargs:
            kw = self.kwargs.copy()
            kw.update(kwargs)
        else:
            kw = kwargs or self.kwargs

        return self.fun(*(self.pending + args), **kw)


I notice that that the cookbook version makes a copy of the kwargs
dictionary.
I suppose this prevents kwargs from being modified after being supplied to
curry.
Also the actual call to the function uses the * and ** operators to 'expand'
the arguments.

I have been using this version, and it works perfectly.  I was especially
pleased to see how well it handles a mixture of positional and keyword
arguments, any comination of which can be specified at both creation-time
and at call-time.  The only requirement is that positional args specified at
creation-time must be the left-most positional arguments.  Positional
arguments supplied at call-time are inserted to the right of those specified
at creation-time.

For functions whose arguments are all keyword arguments, any comination of
arguments can be supplied at both create-time and call-time.

You can curry all of the arguments to a function, creating a callback.
You can curry a class to create a sort of 'lightweight subclass', actually,
more like a factory function, which creates instances, passing certain
arguments to the class's __init__

Curried functions are popular among 'functional language' users, and should
be more popular among Python users.  Python works pretty well with
'functional' idioms, and already borrows things like map(), zip() and
reduce(), which are known to be powerful functions.  Another good one is
compose...(also in the cookbook), which creates a single function from two
other functions.







More information about the Python-list mailing list