私の知る限り、先行評価/適用順序は、関数に適用する前にすべての引数を評価しますが、遅延評価/通常順序は、必要な場合にのみ引数を評価します。
では、先行評価と適用順序、および遅延評価と通常の順序の2つの用語の違いは何ですか?
ありがとう。
私の知る限り、先行評価/適用順序は、関数に適用する前にすべての引数を評価しますが、遅延評価/通常順序は、必要な場合にのみ引数を評価します。
では、先行評価と適用順序、および遅延評価と通常の順序の2つの用語の違いは何ですか?
ありがとう。
遅延評価では、用語を最大1回評価しますが、通常の順序では、表示される頻度で用語を評価します。したがって、たとえば、持っていて、それf(x) = x+x
をそのように呼び出す場合、遅延評価または適用順序では1回呼び出されますが、通常の順序では2回呼び出されます。f(g(42))
g(42)
少なくとも、コンピュータプログラムの構造と解釈にある適用順序の定義を使用する場合は、熱心な評価と適用順序は同義であり、あなたと一致しているようです。(ウィキペディアでは、適用順序の定義が少し異なり、熱心な評価の特殊なケースとして示されています)。
私もSICPを読んでいて、著者によって与えられた通常の順序の定義に興味がありました。それは私には遅延評価にかなり似ているように見えたので、私は両方に関するいくつかの詳細情報を探しに行きました。
この質問はずっと前に聞いたことがありますが、よくある質問を見て、古い質問に答えるという言及がなかったので、他の人が将来使用できるように、ここで見つけたものを残しておくと思いました。
これは私が見つけたものであり、私はそれらに同意する傾向があります:
私は(他の人と同じように)遅延評価とNormalOrderEvaluationは2つの異なるものであると主張します。違いは上記でほのめかされています。遅延評価では、引数の評価は必要になるまで延期され、必要になった時点で引数が評価され、その結果が保存(メモ化)されます。関数で引数をさらに使用すると、計算値が使用されます。C / C ++演算子||、&&、および?:どちらも遅延評価の例です。(一部の初心者のC / C ++プログラマーが&&または||をオーバーロードするのに十分な知識を持っている場合を除き、オーバーロードされたバージョンは厳密な順序で評価されます。そのため、&&および||演算子はC ++でオーバーロードしないでください)。
言い換えると、各引数は最大で1回評価され、場合によってはまったく評価されません。
一方、NormalOrderEvaluationは、式が使用されるたびに式を再評価します。Cマクロ、それをサポートする言語のCallByName、ループ制御構造のセマンティクスなどを考えてみてください。通常の順序の評価は、適用可能な順序の評価よりもはるかに時間がかかり、副作用が複数回発生する可能性があります。(もちろん、副作用のあるステートメントは、通常、C / C ++のマクロへの引数として指定されるべきではないのはそのためです)
引数が不変で副作用がない場合、2つの違いはパフォーマンスだけです。実際、純粋に関数型言語では、遅延評価は通常の順序の評価の最適化と見なすことができます。副作用が存在する場合、または再評価時に異なる値を返す可能性のある式がある場合、2つの動作は異なります。特に通常の順序の評価は、ReferentialTransparencyなしでそのようなプログラムについて推論することが難しいため、手続き型言語では評判が良くありません。
また、厳密な順序の評価(および遅延評価)は、明示的なメモを介した通常の順序の評価をサポートする言語で実現できることにも注意してください。逆は真実ではありません。評価を延期/繰り返すために、呼び出し/メッセージを送信できるサンク、関数、またはオブジェクトを渡す必要があります。
と
遅延評価は、通常の順序の評価と共有を組み合わせたものです。
•必要になるまで、何かを評価しないでください(通常の順序)
•何かを2回以上評価しないでください(共有)
Kevin Sookocheffの通常、適用、および遅延評価の投稿から(強調、文体の変更は私のものです):
遅延評価
通常の順序の評価では、関数の引数を複数回評価する必要があるため、余分な作業が発生する可能性がありますが、 適用可能な順序の評価では、プログラムが通常の順序で終了しない場合があります。実際には、ほとんどの関数型プログラミング言語は、遅延評価を使用してこの問題を解決します。
遅延評価では、同じ関数の複数の評価を回避する方法で関数の評価を遅らせます。したがって、通常の順序と適用可能な順序の評価の利点を組み合わせます。
遅延評価では、必要なときに値を評価し、評価後、その式のすべてのコピーが新しい値で更新されます。実際には、関数に渡されたパラメーターはメモリ内の1つの場所に格納されるため、パラメーターを評価する必要があるのは1回だけです。つまり、特定の引数が使用されるすべての場所を覚えており、関数を評価するときに、引数を値に置き換えます。
その結果、遅延評価では、すべてのパラメーターが最大で1回評価されます。
これは質問の下にコメントとして投稿するには長すぎ、既存の回答をそれで更新することは不適切であるように思われたため、この回答。