問題タブ [tail-call]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
f# - F# テール コールが括弧の欠如によって壊れている
F# チームのブログ記事で F# テール コールをテストしているときに、コード内の括弧だけが異なるだけで、ほぼ同じコードの結果は同じですが、 ILが異なることがわかりました。
次のコードはコンパイラによって最適化されbr.s IL_0000
、IL の最後に表示され、呼び出しはありません。sumSoFar
しかし、その部分はコンパイラによって最適化されておらずcall bla_bla.loopAndSum
、IL の終わりに近づいています。
これらの例は、 を囲む括弧のみが異なりますsumSoFar + x
。それをいじって、 .NET Fiddleで IL を見ることができます。
かっこが重要な理由を知っている人はいますか?
haskell - すべての Haskell 関数は末尾呼び出しを行いますか?
Haskell のすべての関数は末尾再帰であるべきだと思いました。
非末尾再帰関数として実装された階乗関数:
すべての演算子も関数なので、これは次と同等です
しかし、これは明らかに私にとってテールコールです。すべての呼び出しがヒープに新しいサンクを作成するだけなのに、なぜこのコードがスタック オーバーフローを引き起こすのか疑問に思います。ヒープ オーバーフローは発生しませんか?
lua - 私のテール呼び出し関数が出力を一時停止およびフラッシュしないのはなぜですか?
私はlua-users Sleep Functionリファレンスを調べて、スリープの問題に対する非ビジー待機ソリューションを見つけようとしましたが、それらのどれにも満足していません。それにもかかわらず、テールコールを使用する関数の最後に遅延を提供するためにいくつかを使用しようとしました。
通常、私は末尾呼び出しを使用しませんが、lua は末尾呼び出しのためにスタックを残さないので、私には適しています。
残念ながら、プロセッサの使用率が約 20% に急上昇し、プログラムが開始されるとすぐに応答しなくなり、出力がフラッシュされることはありません。
問題 (簡略化) は次のようになります。
ソケット選択メソッド、os.execute、そしてもちろんビジー待機を試しました。これらのうち、ビジーな待機のみが期待される動作を提供します。
これらの他の非ビジー待機ソリューションも非ブロックですか? つまり、遅延にもかかわらずテール コールの処理が許可されますか?
出力をフラッシュし、ビジー待機なしで再開する前に関数を 10 秒待機させるにはどうすればよいですか?
recursion - リストの途中に挿入し、末尾呼び出しに適しているが、パフォーマンスを損なうことなく挿入する方法は?
それで、テールコールに適していないように見えるこの関数がありますよね?
次に、アキュムレータを使用して、関数によって最後に実行されるのが自分自身を呼び出す方法を見つけようとしましたが、次のように思いつきました。
ただし、私が理解している限り、List.concat を使用すると、この関数の効率が大幅に低下しますよね? では、この変換を適切に行うにはどうすればよいでしょうか。
ecmascript-6 - バインドされた関数は ES6 で適切な末尾呼び出しをサポートしていますか?
ECMAScript 2015 言語仕様では、Function.prototype.apply
とのFunction.prototype.call
両方の定義にステップの 1 つとして「Perform PrepareForTailCall()」が含まれているため、これらの関数が適切なテール コール (つまり、テール コールの最適化) をサポートしていることがわかります。
ただし、バインドされた関数オブジェクトの [[Call]]の定義では、PrepareForTailCall() が省略されています。これは、バインドされた関数が適切な末尾の呼び出しをサポートしていないこと、およびバインドされた関数が自分自身を再帰的に呼び出すと、スタックが爆発する可能性があることを意味しますか?
recursion - Erlang、ラスト コールの最適化、ラムダ関数、およびスタックの増大を防ぐ方法
Erlang コードを書いているときに、理解できない奇妙な状況に遭遇しました。
コード:
出力:
この記事から私が理解していることから、Erlang は Last Call Optimization を使用します。関数が最後に行うことが別の関数を呼び出すことである場合、BeamVM は代わりに、新しいスタックをプッシュする代わりに、プログラム カウンターを新しい関数の先頭にジャンプします。フレーム。これは、上記のようなパターンでは、スタックではなくヒープを処理していることを意味するのでしょうか? これにより、これらの関数で以前に保持されていたメモリが解放されますか?時間)?このパターンを使用すると、(明らかなデバッグの苦労以外に) 悪影響はありますか?