Python 为什么不可能实现定义中的定点组合器?
我正在尝试实现Y组合器 此代码不起作用。它导致无限递归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
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确实做到了这一点,它会无限地计算自递归参数。