JVM 是否会阻止尾部调用优化?

2022-08-31 10:30:02

我在这个问题上看到了这句话:构建Web服务的良好函数式语言是什么?

特别是Scala不支持尾部调用消除,除非在自递归函数中,这限制了你可以做的组合类型(这是JVM的基本限制)。

这是真的吗?如果是这样,那么JVM是什么造成了这种基本限制?


答案 1

这篇文章:递归还是迭代?可能会有所帮助。

简而言之,由于安全模型以及需要始终具有可用的堆栈跟踪,因此在JVM中很难进行尾部调用优化。这些要求在理论上可以得到支持,但它可能需要一个新的字节码(参见John Rose的非正式提案)。

Sun bug #4726340 中还有更多讨论,其中评估(从 2002 年开始)结束:

我认为,这仍然是可以做到的,但这不是一项小任务。

目前,达芬奇机器项目正在进行一些工作。尾部调用子项目的状态列为“原型80%”;它不太可能进入Java 7,但我认为它在Java 8上有很好的机会。


答案 2

根本的限制只是JVM在其字节代码中不提供尾部调用,因此,基于JVM构建的语言没有直接的方式来提供尾部调用本身。有一些解决方法可以达到类似的效果(例如,蹦床),但它们会以糟糕的性能和混淆生成的中间代码为代价,从而使调试器无用。

因此,在 Sun 在 JVM 本身中实现尾部调用之前,JVM 无法支持任何生产质量的函数式编程语言。他们已经讨论了多年,但我怀疑他们是否会实现尾部调用:这将是非常困难的,因为他们在实现这些基本功能之前过早地优化了他们的VM,而Sun的努力主要集中在动态语言而不是函数式语言上。

因此,有一个非常有力的论点认为Scala不是一个真正的函数式编程语言:自30多年前Scheme首次推出以来,这些语言一直将尾部调用视为一个基本功能。


推荐