问题
Scala特别不支持尾调用消除,除了自递归函数,这限制了你可以做的组合种类(这是JVM的一个基本限制)。
这是真的?如果是这样,那么创建这个基本限制的JVM是什么呢?
#1 热门回答(72 赞)
简而言之,由于安全模型以及始终需要堆栈跟踪的需要,在JVM中很难进行尾调用优化。理论上可以支持这些要求,但可能需要一个新的字节码(见John Rose's informal proposal)。
在Sun bug #4726340还有更多的讨论,其中评估(从2002年)结束:
我相信这可以做到,但这不是一项小任务。
目前,Da Vinci Machine项目正在进行一些工作。尾调用子项目的状态列为"proto 80%";它不太可能进入Java 7,但我认为它在Java 8上有很好的机会。
#2 热门回答(27 赞)
基本限制只是JVM不在其字节代码中提供尾调用,因此,构建在JVM上的语言本身没有提供尾调用的直接方法。有一些解决方法可以达到类似的效果(例如蹦床),但是它们会带来糟糕的性能和混淆生成的中间代码,这使得调试器无用。
因此,在Sun实现JVM本身的尾调用之前,JVM不能支持任何生产质量的函数式编程语言。他们多年来一直在讨论它,但我怀疑它们是否会实现尾调用:它将非常困难,因为它们在实现这些基本功能之前过早地优化了它们,并且Sun的工作主要集中在动态语言而不是函数语言上。
因此,有一个非常强烈的论点,即Scala不是一种真正的函数式编程语言:自从30多年前首次引入Scheme以来,这些语言一直认为尾调用是一个必不可少的特性。
#3 热门回答(21 赞)
Scala 2.7.x支持对最终方法和本地函数的自递归(一个函数调用自身)进行尾调用优化。
Scala 2.8也可能带有对trampoline的库支持,这是一种优化相互递归函数的技术。
有关Scala递归状态的大量信息可以在Rich Dougherty's blog中找到。