Python 为什么不可能实现定义中的定点组合器?

Python 为什么不可能实现定义中的定点组合器?,python,python-3.x,lambda-calculus,Python,Python 3.x,Lambda Calculus,我正在尝试实现Y组合器 此代码不起作用。它导致无限递归 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) 但是,这个方法确实有效: Y = ( lambda f: (lambda x: f( lambda v: x(x)(v

我正在尝试实现Y组合器

此代码不起作用。它导致无限递归

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)
但是,这个方法确实有效:

Y = (
    lambda f: 
    (lambda x: f(
        lambda v: x(x)(v)
    ))
    (lambda x: f(
        lambda v: x(x)(v)
    ))
)
Y(F)(3)

为什么第一个不起作用,而第二个不起作用?

第一个字符串打印出以下错误:

RecursionError:比较中超出了最大递归深度
致命的Python错误:_Py_CheckRecursiveCall:无法从堆栈溢出中恢复。
Python运行时状态:已初始化

它会导致一个无限循环。

Python急切地求值所有函数参数,这就是导致Y-combinator无限递归的原因。如合同所述:

在严格的编程语言中,Y combinator将一直扩展到堆栈溢出,或者在尾部调用优化的情况下永远不会停止


为了防止这种“渴望”,可以用另一个lambda函数替换直接函数调用
x(x)
。由于隐藏在lambda函数中,因此无法直接计算。这就是您在第二个版本中所做的:
lambdav:x(x)(v)
。这种形式被称为Z-combinator(参见上面的维基百科文章)。

是的,我知道。但是为什么呢?顺便问一下,你从哪里得到其余的错误信息?我只得到第一行(忽略堆栈跟踪ofc)。引用自维基百科文章:“应用于具有一个变量的函数,Y组合符通常不会终止。”以及:“定点组合器可用于实现函数的递归定义。然而,它们很少用于实际编程中。强规范化类型系统(如简单类型的lambda演算)不允许非终止,因此不动点组合子通常不能被分配类型或需要复杂类型系统特性。”。因此这似乎是意料之中的。YF应该是教员,因此终止。
Y(F)
产生无限递归,因为Python会计算热切提及的beta缩减:
YF=F(YF)=F(F(YF))=…
虽然这是本文中的形式化表示法,但Python确实做到了这一点,它会无限地计算自递归参数。