Implementing Partials in Python

A colleague of mine was wistfully pining for Haskell-style currying in Python. This sounded like an interesting syntactic feature, so I decided to see if I could toss together something that would at least emulate the behavior of returning functions when a function is called with too few arguments. I've always admired the flexibility of python, so it seemed like an interesting challenge to prove that.

Using a decorator seemed like a bit of a copout due to the additional syntax required, but was otherwise ideal, as it made checking arguments fairly trivial.

def partial(f):
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except TypeError, t:
            return lambda *_args,**_kwargs:f(*(args+_args), **(dict(kwargs.items()+_kwargs.items())))
    return wrapper

And that's pretty much it, there's some additional overhead incurred by the try block, and decorators tend to make stack traces somewhat unreadable, but it functions well enough for a demonstration of what can be done with this particular hack.

@partial
def greet(salutation, entity):
  return "%s, %s" % (salutation, entity)

hello = greet("Hello")
print hello("world")

>>> Hello, world

Granted, it's not the most useful invocation.

I foolishly googled "python currying" after writing this chunk of code — it turns out that this has been done a lot of times with various methods, and is being added to python 3.0 in the functools module.

Leave a Reply

Your email address will not be published. Required fields are marked *