【问题标题】:Does ES6 Tail Call Optimization Cover Generators?ES6 尾调用优化是否涵盖生成器?
【发布时间】:2015-07-20 01:59:39
【问题描述】:

ES6 对尾调用优化的支持是否涵盖生成器中的尾调用?

假设我有这个整数生成器 >= 0:

var nums = function* (n) {
    n = n || 0;
    yield n;
    yield* nums(n + 1);
};

目前,在 Chrome 和 Firefox 中,它会为每个递归调用添加一个堆栈级别,最终会遇到“超出最大调用堆栈大小”错误。一旦 ES6 完全实现,这种情况还会发生吗?

(我知道我可以迭代地编写上面的生成器而不会遇到错误。我只是好奇 TCO 是否会处理递归定义的生成器。)

【问题讨论】:

  • 不确定 ES6 中的生成器和 TCO,但根据 this compatibility table,TCO 尚未在任何浏览器中实现(截至 2015 年 5 月 8 日),这解释了(部分)为什么你'重新看到调用堆栈爆炸..
  • 只是说,您可以通过为n 赋予默认值0(即function* (n = 0) {)来删除函数的第一行。

标签: javascript generator ecmascript-6 tail-recursion


【解决方案1】:

当进行函数调用时,根据Function call evaluation部分,

  1. tailCall 为 IsInTailPosition(thisCall)
  2. 返回? EvaluateCall(func, ref, arguments, tailCall)

将根据IsInTailPosition 的结果评估调用。如果我们检查IsInTailPosition

  1. 如果 body 是 GeneratorBodyFunctionBody,则返回 false

因此,如果函数体是生成器,则不会进行尾调用优化。

【讨论】:

  • 你认为这个限制的原因是什么?
猜你喜欢
  • 2020-10-21
  • 2010-10-23
  • 2012-04-18
  • 2011-07-16
  • 2010-11-16
  • 2014-02-13
  • 2017-07-23
  • 2018-08-30
  • 2021-05-27
相关资源
最近更新 更多