Search code examples
pythonlambda-calculus

python lambda : maximum recursion depth exceeded in comparison


I wrote the following code in Python:

func = lambda x : x * 2
func = lambda x : func(x)
func(6)

When I ran the code above, I got

RecursionError: maximum recursion depth exceeded in comparison

I think the reason maybe : when it runs, it looks like this :

func = lambda x : lambda x: lambda x: (bula bula ...)

But why shouldn't it be like this :

func = lambda x : lambda x : x * 2

Or any other reasons?


Solution

  • When you write func = lambda x : func(x), you are redefining func to be that lambda, which just calls itself repeatedly until it bottoms out at the recursion limit. Consider a def version of the same:

    def i_call_myself_forever(x):
        return i_call_myself_forever(x)
    

    Your lambda is doing the same thing.

    I think what you are trying to do is call the first definition of func from the second. That being the case, just give them distinct names and you'll be fine.

    Additionally, you're not correctly understanding what func = lambda x : lambda x : x * 2 means. What's happening is that the top level lambda is returning another lambda, namely lambda x : x * 2. That second level lambda uses the same parameter name x and as such shadows the x from the top level lambda. You could call it as follows

    func = lambda x : lambda x : x * 2
    intermediate_func = func(5) # 5 is captured but never used
    assert intermediate_func(6) == 12 # this is calling lambda x : x * 2
    

    Let's also try a def version to be as clear as possible:

    def i_return_a_function(x):
       def im_an_inner_function(x):
           # my x shadows i_return_a_function's x
           return x * 2
       return im_an_inner_function # notice how i_return_a_function's x is never used
    

    Finally, I want to emphasize @tdelaney's comment: Sure, there are plenty of examples of people assigning lambdas to a name out there in the wild, but that doesn't mean that doing so is considered good practice. There's some disagreement in the community about how strict to be about this, but my rule of thumb is to only use lambda when the function is a single expression (which is all you can express with a python lambda) that I'm using exactly once.