繁体   English   中英

Javascript引擎中的尾调用优化实现

[英]Tail Call Optimization implementation in Javascript Engines

截至2019年2月,在Mac上的Chrome版本71.0.3578.98中,以下程序抛出Uncaught RangeError: Maximum call stack size exceeded error. 数量为16516

const a = x => {
  console.log(x)
  a(x + 1)
}

a(1)

我已经做了很多谷歌搜索,但无法找到任何文章讨论Chrome或其他浏览器支持尾部呼叫优化(TCO)或任何未来实施它的计划。

我的两个问题是:

  1. Chrome或任何其他浏览器或Javascript引擎目前是否支持TCO
  2. 是否有计划在不久的将来在任何Javascript引擎中实施TCO

我发现的帖子大多是旧的(2016年或更早),或者只是令人困惑。 例如https://www.chromestatus.com/feature/5516876633341952

TCO,或者更确切地说,JavaScript中的尾部呼叫消除 - 在讨论中通常被称为正确的尾部呼叫(PTC) - 是一个漫长而悲伤的故事。

2011年左右,TC39(JavaScript标准委员会)决定对即将推出的ES6标准采用强制性TCE,并得到所有主要浏览器厂商的一致认可。

2015年,新标准正式采用,名称为EcmaScript 2015.此时,没有任何浏览器实际实施过TCE,主要是因为ES2015中有太多新功能被认为更重要。 (今天的JS功能提案及其采用的过程,包括生产引擎中两个实现的要求,ES6尚不存在。)

2016年初,Safari和Chrome都实施了TCE。 Safari宣布发布它,而Chrome则将其置于实验功能标志之后。 其他浏览器(Firefox和Internet Explorer / Edge)也开始研究它并且有了第二个想法。 毕竟,讨论是否是一个可行的特征。 Edge在为Windows ABI高效实现它时遇到了问题,Firefox担心开发人员在堆栈跟踪中“丢失”调用的经历(这个问题已在2011年详细讨论过)。

在尝试解决尾部调用功能时解决其中一些问题时,包括Chrome和Edge团队在内的几个成员建议将尾调用显式化 ,即需要使用附加关键字注释return语句以选择尾调用语义。 这些所谓的“ 语法尾调用 ”(STC)在Chrome中实现,作为概念验证。

在2016年5月的TC39会议上,尾部呼叫问题已被广泛讨论了将近一整天而没有解决方案。 Firefox和Edge明确表示他们不会按照标准中的规定实施TCE。 Firefox成员建议将其删除。 Safari和Chrome不同意这一点,Safari团队明确表示他们无意取消TCE。 语法尾部调用的提议也被拒绝,尤其是Safari。 该委员会处于僵局。 您可以阅读本次讨论会议记录

从技术上讲,就我所知,这种僵局至今仍然存在。 实际上,尾部调用JavaScript几乎已经死了,目前还不清楚它们是否会再次出现。 至少那是在灾难性会议之后Chrome团队的结论,这导致决定从Chrome中删除尾部调用的实现,以简化引擎并防止有点腐烂。 它们仍可在Safari中使用。

披露:我是TC39和Chrome / V8团队的成员,直到2017年,所以我的观点可能有偏见。

即使TCO似乎是我们所有人的梦想,通过使用trampoline技术,您可以轻松地将代码转换为运行,就好像它是尾部优化的一样。

 const a = x => { if(x > 500000) { console.log(x); return; } return ()=> a(x + 1); //you return a function, it hasn't been called yet } const trampoline = fn => (...args) => { let result = fn(...args) //repeatedly call the function till you hit your base case while (typeof result === 'function') { result = result(); } return result; } var t = trampoline(a); t(1); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM