【问题标题】:Why do no javascript engines support tail call optimization?为什么没有 javascript 引擎支持尾调用优化?
【发布时间】:2015-07-07 15:41:29
【问题描述】:

我最近了解了 Haskell 中的尾调用优化。我从以下帖子中了解到这不是 javascript 的功能:

javascript 的设计中是否有一些固有的东西使得尾调用优化特别困难?为什么这是像 haskell 这样的语言的主要功能,但现在才作为某些 javascript 引擎的功能进行讨论?

【问题讨论】:

  • 我认为 ES6 会提供它。
  • 是的,我相信你是对的。我更想知道为什么它只是现在被添加为一项功能?
  • 参见this article 解释尾调用优化的困难。是的,它肯定会在 ES6 中实现。
  • 最大的区别在于 TCO 在 haskell 中是必要,而在其他语言中它只是增加编译器复杂性的一个特性
  • 另外,海量递归也会遇到调用栈限制,默认很小。我认为 JS(从 ES5 开始)过去并不是主要针对递归。

标签: javascript recursion tail-recursion tail-call-optimization


【解决方案1】:

JavaScript 支持尾调用优化。目前还没有浏览器实现它,但随着规范 (ES2015) 的最终确定以及所有环境将不得不实现它,它即将到来。像 BabelJS 这样将新 JavaScript 转换为旧 JavaScript 的转换器已经支持它,你现在就可以使用它。

Babel 的翻译非常简单:

function tcoMe(x){
    if(x === 0) return x;
    return tcoMe(x-1)
}

转换为:

function tcoMe(_x) {
    var _again = true;

    _function: while (_again) {
        var x = _x;
        _again = false;

        if (x === 0) return x;
        _x = x - 1;
        _again = true;
        continue _function;
    }
}

那是 - 一个while循环。

至于为什么它只是支持,社区并没有很大的需要尽快这样做,因为它是一种带有循环的命令式语言,因此对于广大大多数情况下,您可以自己编写此优化(不像在 ML 中需要这样做,正如 Bergi 指出的那样)。

【讨论】:

  • 你不是说机器语言吧?
  • @Bergi hehe,不,我的意思是 [ML](en.wikipedia.org/wiki/ML_(programming_language)s,它是像 OCaml 和 F#(直接方言)和 Haskell(具有非严格评估但相同想法的 ML)这样的语言家族),尽管该声明对于其他函数式语言(如 scheme)同样适用。
  • 是的,这就是我的怀疑,但复数让我感到困惑。我从未将 ML 称为语言的家族s :-)
  • 尾调用可以重用其封闭函数的堆栈帧(相同的返回点)。只有包含参数的内部变量必须被初始化。这是否意味着,对于 JS 引擎,尾调用同样可以很好地优化为命令式循环?通常我不关心微优化,但说到迭代......
  • @IvenMarquardt 是的,尾调用可能as快。
猜你喜欢
  • 2019-07-10
  • 2017-05-15
  • 2011-04-09
  • 2017-07-23
  • 1970-01-01
  • 2012-03-31
  • 2021-05-30
  • 1970-01-01
相关资源
最近更新 更多