Search code examples
pythondecoratorcurrying

Currying decorator in python


I am trying to write a currying decorator in python. I got this far:

def curry(fun):    
    cache = []
    numargs = fun.func_code.co_argcount
    
    def new_fun(*args, **kwargs):
        print(args)
        print(kwargs)
        cache.extend(list(args))        
        if len(cache) >= numargs: # easier to do it explicitly than with exceptions            
            temp = []
            for _ in xrange(numargs):
                temp.append(cache.pop())
            fun(*temp)
            
    return new_fun

@curry
def myfun(a,b):
    print(a,b)

While for the following case this works fine:

myfun(5)
myfun(5)

For the following case it fails:

myfun(6)(7)

How can I do this correctly?


If you're just looking to bind arguments to a function and aren't interested in a specific design or the underlying computer science principles, see Python Argument Binders.


Solution

  • The below implementation is naive, google for "currying python" for more accurate examples.

    def curry(x, argc=None):
        if argc is None:
            argc = x.func_code.co_argcount
        def p(*a):
            if len(a) == argc:
                return x(*a)
            def q(*b):
                return x(*(a + b))
            return curry(q, argc - len(a))
        return p
    
    @curry
    def myfun(a,b,c):
        print '%d-%d-%d' % (a,b,c)
    
    
    
    myfun(11,22,33)
    myfun(44,55)(66)
    myfun(77)(88)(99)