Dr Rauschmayerの説明 es6の再帰的末尾呼び出しの最適化を読んで、私は彼が詳述する再帰的階乗関数の「ゼロスタック」実行を再現しようと試みてきました。
Chromeデバッガーを使用してスタックフレーム間を移動すると、末尾の最適化が発生せず、再帰ごとにスタックフレームが作成されていることがわかります。
また、デバッガなしで関数を呼び出すことで最適化をテストしようとしましたが、代わりに100000
階乗関数に。これにより、「最大スタック」エラーがスローされます。これは、実際には最適化されていないことを意味します。
ここに私のコードがあります:
const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )
結果:
Uncaught RangeError: Maximum call stack size exceeded
ChromeのJavaScriptエンジンであるV8はしばらくの間TCOをサポートしていましたが、この更新された回答(2017年11月)の時点ではサポートされておらず、この記事の執筆時点では、V8でのTCOの積極的な開発はなく、予定されていません。詳細は V8追跡バグ で確認できます。
TCOサポートは、ある時点でV8で適切なレベルに達したようですが、いくつかの理由(デバッグの問題、バグ)のためにフラグの後ろに残りました。しかし、その後、いくつかのことが起こりました。特に、 V8チームはTCOで重大な問題を提起しました と呼ばれる仕様変更を強力にサポートしました 構文の末尾呼び出し(STC) ソースコードで意図的にフラグを立てる(たとえば、return continue doThat();
)。ただし、その提案は2017年7月に inactive になりました。また、7月にTCOの作業が行われていなかったため、V8チームは、TurboFan *のソースからTCOをサポートするためのコードを削除しました。 (例えば、メンテナンスの痛みやバグの原因になります。)
そのため、現時点(2017年11月)では、「見えない」TCOがV8に含まれるのか、ある種のSTCが入ってくるのか、それともどうなるのかは明確ではありません。 Chromeプラットフォームステータスページ は、TCOのサポートに関するMozilla(Firefox/SpiderMonkey)およびMicrosoft(Edge/Chakra)からの「混合」パブリックシグナル、SafariがTCOとともに出荷されていること、およびWeb開発者が機能について「ポジティブ」。ここからどこに行くのかがわかります。どこでも。
*(TurboFan = V8の現在の最先端JITコンパイラ、今では switched Full-Codegen [JIT] + Crankshaft [aggressive optimize JIT]からIgnition [interpreter +]およびTurboFan [aggressive optimize JIT])
V8(ChromeのJSエンジン)チームは、当面はTCOを実装していません。最新バージョンから削除されました( このスレッドを参照 )。
主要なブラウザのうち、 Safariのみが実際に機能を実装しています 。
Node.JSバージョン8以降では、- TCOは利用できません 。
最近のWebAssemblyミーティング では、Googleと参加している他のすべてのグループは、TCOの実装をさらに探求することに中立的または積極的でした。