JavaScriptで実装した末尾再帰パスファインディングアルゴリズムがあり、(すべて?)ブラウザでスタックオーバーフロー例外が発生する可能性があるかどうかを知りたいです。
6 に答える
ECMAScript 4仕様は、もともとTCOのサポートを追加する予定でしたが、削除されました。
私の知る限り、JavaScriptの広く利用可能な実装は現在自動TCOを実行していません。ただし、これは役立つ場合があります。
基本的に、アキュムレータパターンを使用すると同じ効果が得られます。
今のところ喜びはありませんが、ありがたいことに、Harmony(ECMAScriptバージョン6) http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_callsに適切な末尾呼び出しが予定されています。
遭遇するほとんどすべてのブラウザは、「再帰が多すぎる」と言ってしまいます。これがV8バグトラッカーのエントリで、おそらく興味深い読み物になるでしょう。
単純な自己再帰の場合は、末尾呼び出しの除去を期待するのではなく、明示的な反復を使用することをお勧めします。
末尾呼び出しの最適化は、将来ECMAScript6の厳密モードでサポートされる予定です。詳細については、 http://www.2ality.com/2015/06/tail-call-optimization.htmlを確認してください。
現在のエンジンサポートについては、http://kangax.github.io/compat-table/es6/を確認してください。
現在(18-07-2019)、次のエンジンが末尾呼び出しの最適化をサポートしています。
- Safari> = 10
- iOS> = 10
- キノマXS6
- Duktape 2.3
「実験的なJavaScript機能」の場合のサポート-フラグがオンになっている場合:
- ノード6.5
Chrome 54 /Opera41現在のバージョンのcompatテーブルには表示されなくなりました
JavaScriptにコンパイルされるLispyScriptで末尾呼び出しの最適化が利用できるようになりました。あなたはここでそれについてもっと読むことができます。
現在、末尾再帰を認識するJavaScript実装はありません。ECMAScript 6で変更が行われており、他の人が言っているように、 V8にはオープンチケットがあります。
ここでは、末尾再帰関数用にV8で生成されたアセンブラーを確認できます。
それをClangがCで同じ関数をコンパイルした方法と比較してください
V8は再帰呼び出しを保持しますが、Cコンパイラは末尾再帰を認識してループに変更しました。