Y-combinator 并没有什么作用

我尝试使用 Y-combinator(在 Lua 和 Clojure 中)因为我认为它可以允许我在使用递归时超过默认堆栈大小实现。但是事实并非如此。是的,它能工作,但在这两个系统中,堆栈吹到与使用纯递归相同的点。在 Clojure 中是低于 3600,在我的 Android Lua 实现中是高达约 333000。它也比常规递归略慢。

那么使用 Y-combinator 是否有所收获,或只是一个证明观点的学术练习?我错过了什么吗?

===

PS. 对不起,我应该更清楚地表明我知道我可以使用 TCO 来超过堆栈。我的问题与此无关。我对此有兴趣 a) 从学术 / 知识分子的角度 b) 是否有什么可以针对那些无法写成尾递归的函数的问题。

点赞
用户4403144
用户4403144

一个“尾调用”允许您超出任何堆栈大小的限制。请参见《Lua编程》第6.3节:适当的尾调用

…在尾调用之后,程序不需要在堆栈中保留有关调用函数的任何信息。一些语言实现,例如 Lua 解释器,利用了这个事实,在执行尾调用时实际上不使用任何额外的堆栈空间。我们说这些实现支持适当的尾调用。

2018-06-20 02:57:07
用户8746216
用户8746216

Y 组合子允许非递归函数被用作递归,但是递归仍然通过嵌套函数调用消耗栈空间。

对于无法变成尾递归的函数,您可以尝试使用 continuation passing style 进行重构,这将消耗堆空间而不是栈空间。

这里有一个关于这个主题的好概述:https://www.cs.cmu.edu/~15150/previous-semesters/2012-spring/resources/lectures/11.pdf

2018-06-20 03:14:57
用户1822379
用户1822379

如果您还没有看过的话,这里有一个很好的解释:什么是 Y 组合器?

简而言之,它有助于证明λ演算是图灵完备的,但对于普通编程任务来说是无用的。


正如您可能知道的那样,在Clojure中,您只需使用loop /recur实现不消耗堆栈的循环

2018-06-20 03:16:43