【问题标题】:Can't enable tail call optimization in node v6.4.0无法在节点 v6.4.0 中启用尾调用优化
【发布时间】:2016-09-21 13:25:35
【问题描述】:

我不想在 node/es2015 中使用尾调用优化,但我不断收到RangeError: Maximum call stack size exceeded。于是我尝试了一个很简单的测试函数:

  function countTo(n, acc) {
    if(n === 0) {
      return acc;
    }
    return countTo(n - 1, acc + n);
  }

  console.log(countTo(100000 , 0))

它仍然失败。我尝试在函数体内和文件顶部添加'use strict';。我试过使用--harmony--harmony-tailcalls

同样的功能在球拍中按预期工作:

#lang racket
(define count-to
  (lambda (n acc)
    (cond
      ((= n 0) acc)
      (else (count-to (- n 1) (+ acc n))))))
(count-to 100000000 0)
; ~> 5000000050000000

编辑:

正如@MatthieuLemoine 建议的那样。它在 v6.5.0+ 中使用 "use strict";--harmony--harmony-tailcalls

【问题讨论】:

    标签: javascript node.js recursion ecmascript-6


    【解决方案1】:

    使用节点 v6.5.0,以下工作:

    function countTo(n, acc) {
      'use strict';
      if(n === 0) {
        return acc;
      }
      return countTo(n - 1, acc + n);
    }
    console.log(countTo(100000 , 0));
    

    使用--harmony-tailcalls 标志运行:

    node --harmony-tailcalls tco.js
    

    【讨论】:

    • 那行得通。我升级到 v6.6.0 并且它工作。我认为 v6.4.0 就足够了。
    【解决方案2】:

    即使在旧节点上,您也可以使用tco 模块来模拟尾调用优化。稍后我将使用您的代码向此答案添加一个示例。

    稍微改变你的代码,你甚至可以运行 1000 万级递归:

    var tco = require('tco');
    var countTo = tco(function (n, acc) {
      if (n === 0) {
        return [null, acc];
      }
      return [countTo, [n - 1, acc + n]];
    });
    console.log(countTo(10000000, 0));
    

    您可以使用 Sweet 宏使其看起来更像:

    var countTo = tco(function (n, acc) {
      if (n === 0) {
        ret acc;
      }
      ret countTo(n - 1, acc + n);
    });
    console.log(countTo(10000000, 0));
    

    这基本上是将return 更改为ret,但目前我以前使用的宏似乎不适用于当前版本的 Sweet.js - 我有时间时必须对其进行调查。

    免责声明:我是该模块的作者。

    【讨论】:

    • 酷模块!我对 sweet.js 感兴趣有一段时间了,但从未使用过它。我的代码应该可以工作。我正在使用 v6.4.0
    • @sheepdog 谢谢。一年前我出于沮丧或其他原因写了它。感谢您发布您的问题,因为实际上我不知道在当前版本的 Node 中应该提供尾调用优化 - 我想知道为什么它没有成为新闻,因为它是我一直在等待的一个重要功能。在我看来,缺乏尾调用优化一直是 JavaScript 的最大缺点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 2014-04-06
    • 1970-01-01
    • 2012-08-19
    • 2011-05-27
    • 2019-04-20
    • 1970-01-01
    相关资源
    最近更新 更多