Skip to content Skip to sidebar Skip to footer

Python Function Composition (max Recursion Depth Error, Scope?)

What is wrong with this function? It seems like a scope error (although I thought I had fixed that by placing each callable in the list, instead of using it directly). Error is max

Solution 1:

The lambda function you create builds a closure over the composed variable:

composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))

This means that composed[-1] isn't evaluated when you create the lambda function, but when you call it. The effect is, that composed[-1] will be calling itself recursively again and again.

You can solve this problem by using a helper function (with its own scope) to create the lambda functions:

def comp2(f1, f2):
    return lambda *args, **kwargs: f1(f2(*args, **kwargs))

...
for func in funcs:
     composed.append(comp2(func, composed[-1]))

Solution 2:

I don't know why you generate to many functions to begin with. There is a simple version of your code:

def compose(*funcs):
    if len(funcs) in (0,1):
        raise ValueError('need at least two functions to compose')

    # accepting *args, **kwargs in a composed function doesn't quite work
    # because you can only pass them to the first function.
    def composed(arg):
        for func in reversed(funcs):
            arg = func(arg)
        return arg

    return composed

# what's with the lambdas? These are functions already ...
def inc(x):
    print("inc called with %s" % x)
    return x+1
def dbl(x):
    print("dbl called with %s" % x)
    return x*2
def inv(x):
    print("inv called with %s" % x)
    return -x

if __name__ == '__main__':
    f = compose(inv,dbl,inc)
    print f(2)
    print f(3)

Post a Comment for "Python Function Composition (max Recursion Depth Error, Scope?)"