I'm trying to implement the Y-combinator like in the definition by Curry.
This code does not work. It causes infinite recursion.
F = (lambda f: (lambda x: (1 if x == 0 else (x * (f(x-1))))))
Y = (
lambda f:
(lambda x: f(x(x)))
(lambda x: f(x(x)))
)
Y(F)(3)
However, this one does work:
Y = (
lambda f:
(lambda x: f(
lambda v: x(x)(v)
))
(lambda x: f(
lambda v: x(x)(v)
))
)
Y(F)(3)
Why is the first one not working, but the second one is?
Python evaluates all function arguments eagerly and this is what causes infinite recursion for the Y-combinator. As stated in the linked Wikipedia article:
In a strict programming language the Y combinator will expand until stack overflow, or never halt in case of tail call optimization.
In order to prevent that "eagerness", one can replace the direct function call x(x)
with another lambda function. Being hidden inside that lambda function prevents it from evaluating straightaway. That's what you've done in your second version: lambda v: x(x)(v)
. This form is then known as the Z-combinator (see the Wikipedia article above).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With