Reputation: 21
If expression evaluates to a function of one argument, I would have thought that lambda x: (expression)(x) is identical to expression - but this is not actually the case. Consider the two following definitions of the Y combinator:
def Y1(F):
left = lambda x: x(x)
right = lambda x: F(x(x))
return left(right)
def Y2(F):
left = lambda x: x(x)
right = lambda x: lambda y: (F(x(x)))(y)
return left(right)
Y2 actually works as expected, but calling Y1 raises a stack overflow. Why is there this difference in behavior?
Upvotes: 0
Views: 113
Reputation: 71119
No, lambda x: (expression)(x)
is not identical to expression
.
It is a function that will return the result of expression
when called, unlike expression
that returns its result right away.
What is that result? It is a function of one parameter. But it's not there quite yet. It needs to be constructed, calculated. And that's what expression
is doing. It calculates that recursive function representing the "next" recursive call that might need to be done by the recursive function constructed by Y combinator.
Y1
tries to find the value of right
prematurely, too soon, too eagerly -- it tries to do this before returning the calculated recursive function. Which is thus never returned, because Y1
always tries to calculate the next recursive function before returning the previous one so it can be called.
But Y2
constructs the recursive function that will calculate the next recursive function when it will be needed; but not yet, not "now". It constructs it as the lambda function, which delays the actual calculation. The construction of a lambda function is a simple one-step process which completes quickly, and then the calculated recursive function is returned, so it can be used -- and only if/when it will determine that the next level of recursive call needs to be performed, it will call that lambda at that point in time to construct that next recursive function at that point in time, i.e. just before calling it.
Not way way in advance as the Y1
is trying to do.
Upvotes: 2