【问题标题】:Can this use of the spread syntax use tail call optimisation?这种使用扩展语法可以使用尾调用优化吗?
【发布时间】:2021-10-26 16:57:51
【问题描述】:

这个函数会使用尾递归吗?

function doStuff(param) {
  if (someExitCondition) {
    return [];
  }
  // maybe manipulate param somehow
  return [...doStuff(param - 1), value]; // spread the recursive function's result and append 1 item.
}

如果没有,是否可以对其进行重构,使其可以使用尾递归?

我怀疑递归函数的结果大小未知这一事实阻止了尾递归在这里的可能,但我不确定。

注意在我的情况下,最大迭代可能很低,因此尾递归的影响可以忽略不计甚至可能为 0?因此,我将其归类为过早的微优化。

所以这主要是一个学术问题,我很好奇答案。

【问题讨论】:

  • 我还没有设法让 JavaScript 成为尾递归。至少不在浏览器中。见,stackoverflow.com/questions/37224520/…
  • 旁注:... 不是运算符。操作员不能做... 所做的事情。这是主要语法。
  • 我想知道生成器是否会发生尾递归? function *doStuff(param) { if (param < 1) return; yield param; yield* doStuff(param-1); } console.dir([...doStuff(5)]);(我知道this

标签: javascript tail-recursion


【解决方案1】:

doStuff 的调用不在尾部位置,所以不,这不会从尾部调用优化中受益。结尾处的order of operations一些东西(略过一些细节):

  • 开始创建数组
  • 计算param,从中减去1,计算doStuff,然后使用param - 1 中的值调用结果函数
  • 从返回值中获取迭代器
  • 循环遍历该迭代器提供的值,将它们添加到数组中
  • 评估 value 并将结果值添加到数组中
  • 返回数组

还要注意,大多数 JavaScript 引擎都没有实现 TCO(尽管它是规范的一部分),而且不太可能实现;我的其他答案herethis question 的答案中的详细信息。

【讨论】:

  • 假设代码是按字面意思理解的,这与我对操作顺序的理解差不多。但我知道优化器有时会操纵操作顺序以利用优化。但是,如果 TCO 甚至没有实施,那么当然没有多大意义!这不是我所知道的事情,鉴于解释其有用性的 JS 相关内容的数量,我感到很惊讶。
猜你喜欢
  • 1970-01-01
  • 2013-07-18
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
相关资源
最近更新 更多