0

我尝试使用 y-combinator(在 Lua 和 Clojure 中),因为我认为这将允许我在使用递归时超出默认堆栈实现的大小。看来我弄错了。是的,它有效,但是在这两个系统中,堆栈的崩溃与使用普通的旧递归完全相同。Clojure 中的低约 3600 和我的 Android Lua 实现中的高约 333000。它也比常规递归慢一点。

那么使用 y-combinator 有什么好处,还是只是为了证明一个观点而进行的智力练习?我错过了什么吗?

===

PS。抱歉,我应该更清楚地说明我知道我可以使用 TCO 来超过堆栈。我的问题与此无关。我对此很感兴趣 a) 从学术/知识的角度来看 b) 是否可以对那些不能递归编写的函数做任何事情。

4

3 回答 3

3

Y 组合器允许递归使用非递归函数,但该递归仍然通过嵌套函数调用消耗堆栈空间。

对于不能进行尾递归的函数,您可以尝试使用延续传递样式重构它们,这将消耗堆空间而不是堆栈。

这是对该主题的一个很好的概述:https ://www.cs.cmu.edu/~15150/previous-semesters/2012-spring/resources/lectures/11.pdf

于 2018-06-20T03:14:57.590 回答
0

“尾调用”将允许您超过任何堆栈大小限制。请参阅《Lua 编程》第 6.3 节:正确的尾调用

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

于 2018-06-20T02:57:07.377 回答
0

如果你还没看过,这里有一个很好的解释: 什么是 Y-combinator?

总之,它有助于证明 lambda 演算是图灵完备的,但对于正常的编程任务是无用的。


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

于 2018-06-20T03:16:43.250 回答