web-dev-qa-db-ja.com

「通常の順序」と「名前による呼び出し」は同じものですか?

私は本 コンピュータプログラムの構造と解釈 およびセクション 1.1.5プロシージャアプリケーションの置換モデル で、著者はの概念を説明しています通常の順序適用順序、私はよく理解していると思います。

さて、私は Coursera と呼ばれる Scalaの関数プログラミング原則 のコースを受講しています。そこで、Martin Odersky教授(上記の本の中で彼のコースの多くに基づいています)は、 call-by-nameおよびcall-by-valueという名前の同じ概念.

彼のコースでは、Odersky教授は置換モデルはラムダ計算に基づいていると言っているので、私は自分のライブラリーの本を調べた ラムダ計算による関数型プログラミングの概要 であり、22ページで著者は適用順および通常順としての用語。興味深いことに、彼の定義では、通常の順序はALGOLの名前による呼び出しのようであるのに対し、適用順序はPascalの値による呼び出しのようなものであると述べています。

彼の説明で「に似ている」という言葉を使用していることが、私を疑わせました。したがって、私の質問:

  • これらの2つの用語は同等ですか、または微妙な違いはありますか?
  • 意味を間違える危険を冒すことなく、どちらか一方を交換して使用できますか?
  • 同じことを指すために異なる用語の存在を正当化する理由について、あなたが知っている理由はありますか?
9
edalorzo

通常の順序の評価と名前による呼び出しの評価はまったく同じものではありません。通常の順序の評価では、最も外側の関数がその引数の前に評価され、それらの引数は必要な場合にのみ評価されます。名前による呼び出しの評価では、引数が最も外側の関数の本体に効果的にコピーされ、その関数が評価されます。どちらの場合も、最も外側の関数は技術的に引数の前に評価されますが、純粋な名前による呼び出しでは、引数は使用されるたびに評価されます(0回、1回、または何度も)。通常の順序では、関数の引数は少なくとも最初に必要になったときにのみ評価されます(通常は0回または1回)。

したがって、通常の順序評価では、引数を最適化(別名call-by-needと呼ばれることもある)としてメモする可能性が残されていますが、call-by-nameはそうではありません。したがって、名前による呼び出しの評価は、通常の順序評価の特殊なケースであると言えます。言い換えると、通常の順序の評価は、引数の前に関数を評価する一般的なアプローチを指し、名前による呼び出しの評価は、通常の順序の評価を実装するための特定の手法を指します。

例として、f(x, y) = sqrt(x*x + y*y)を指定すると、通常の順序評価でf(a+b, c+d)を実装する方法が2つあります。

メモ化:

_t1 = a+b;
t2 = c+d;
return sqrt(t1*t1 + t2*t2);
_

名前で呼び出す:

_return sqrt((a+b)*(a+b) + (c+d)*(c+d));
_

ご覧のように、fへの呼び出しに他の関数呼び出し(つまり、f(random(1,100), ask_user_for_value()))が含まれている場合、2つは非常に異なる動作をします。メモ化されたバージョンは単一の乱数を二乗してユーザーに1回だけ値を要求しますが、名前による呼び出しバージョンは2つの乱数を乗算してユーザーに2回値を要求します。

これらの概念の詳細については、 評価戦略 ウィキペディアのページと https://cs.stackexchange.com/questions/7702/applicative-order-and-normal- order-in-lambda-calculus

7
Randall Cook