簡體   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