Wikipedia article on the Y combinator提供了Y组合子的以下JavaScript实现:
function Y(f) {
return (
(function (x) {
return f(function (v) { return x(x)(v); }); })
(function (x) {
return f(function (v) { return x(x)(v); }); })
);
}
JavaScript中Y组合子的存在应该意味着每个JavaScript函数都有一个固定点(因为对于每个函数g
,Y(g)
和g(Y(g))
应该相等。)
但是,如果没有违反Y(g) = g(Y(g))
的固定点(参见here),就很难找到功能。甚至某些功能也没有固定点(见here)。
如何证明每个函数都有一个固定点与给定的反例一致? JavaScript不是一个无类型的lambda演算,其中Y(g) = g(Y(g))
适用的证据是什么?
答案 0 :(得分:4)
据我理解维基百科的文章,它并不意味着“每个JavaScript函数都有一个固定点”的任何地方,这个例子只是简单地说明了如何根据规范为它提供Y组合器。
不,根据该文章和an article on fixed point中的定义,JavaScript不能是无类型的lambda演算,因为它可以制定显然无法“有固定点”检查的函数,如{{1} }或function f(x){ return x + 1 }
如果你想包含非数字,那么“每个函数至少有一个固定点”也会失败。
答案 1 :(得分:3)
定点理论有各种各样的风格。编程语言的那些是在指称语义的标题下研究的。它们依赖于形成具有特殊属性的结构化可数集的值。 Lattices和Complete Partial Orders就是两个例子。所有这些集合都有一个“底部”元素,结果证明是“没有用的结果”的固定点。实际上,您对计算机程序感兴趣的唯一定点运算符是最少定点运算符:那些找到结构化值集中最低的唯一最小定点点的运算符。 (注意所有整数在这些结构化集合中处于相同的“级别”。只有底部元素位于下面。其余的层由更复杂的类型组成,如函数和元组类型,即结构。)如果你有一些离散的数学,this很好地解决了这个问题。 Tarsky的不动点定理实际上表示每个单调(或者交替连续)的函数都有一个固定点。有关定义,请参阅上面的参考。在操作计算机程序中,底部元素对应于非终止计算:无限递归。
所有这一切的要点是,如果你有一个严格的计算数学模型,你就可以开始证明关于类型系统和程序正确性的有趣事情。所以这不仅仅是一次学术练习。
答案 2 :(得分:3)
lambda表达式的问题在于它们不能被解释为数学意义上的函数,即从一个集合映射到另一个集合。
原因是集合A
本身的函数集的基数总是大于A
的基数,因此并非所有函数都从A
到{{1 }}可以是A
的元素。也就是说,有一个函数A
,表达式f: A -> A
没有意义。
这就像“不包含自身的所有集合的集合”,这在逻辑上没有意义。
JavaScript不是lambda演算的模型。
你的例子的问题是
f(f)
应该相当于
(lambda x.g(x x)) (lambda x.g(x x))
但它不在您的JavaScript程序中g((lambda x.g(x x)) (lambda x.g(x x)))
是g
的指标函数。
0
始终为x x
。因此,第一行评估为undefined
。
第二行评估为g (undefined) = 0
。这意味着你的lambda演算的JavaScript模型实际上并不是真正的模型。
因为对于每个非空集g (g (undefined)) = g (0) = 1
,有一个函数从D
到D
没有固定点,显然不存在lambda演算的模型。我认为应该甚至可以证明在任何图灵完备语言中都不能实现Y-combinator。