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


9

私は「コンピュータプログラムの構造と解釈」という本を研究しており、セクション1.1.5手続き適用の代替モデルでは、筆者は通常の順序適用順序の概念を説明しています。

今すぐ、私はコースを取っていコーセラが呼ばれるスカラ座での関数プログラミングの原則をと(本が先に引用してずっと彼もちろんベース)教授マーティン・オーダーズキーが説明の名の下に同じ概念コール名ずつcall-値渡し

彼のコースでは、教授Odersky著は、私は私の図書館の本に相談して置換モデルは、ラムダ計算に基づいていると言う関数型プログラミングもののラムダ計算に入門をし、22ページに、著者はApplicativeのため、通常の注文として用語を定義し。興味深いことに、彼の定義では、通常の順序はAlgolの名前による呼び出しと同様に、適用順序はPascalの値による呼び出しと同様であると述べています。

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

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

1
このウィキペディアの記事では、通常の順序とは対照的に、「名前による呼び出し戦略は、適用されていない関数の本体内では評価されない」と述べています。ただし、具体的な引用はありません。
chrisaycock 2013

4
参考までに、Martin OderskyがScalaのリードデザイナーであることを知っていますよね?
KChaloux 2013

回答:


7

通常の順序の評価と名前による呼び出しの評価はまったく同じものではありません。通常の順序の評価では、最も外側の関数がその引数の前に評価され、それらの引数は必要な場合にのみ評価されます。名前による呼び出しの評価では、引数が最も外側の関数の本体に効果的にコピーされ、その関数が評価されます。どちらの場合も、最も外側の関数は技術的に引数の前に評価されますが、純粋な名前による呼び出しでは、引数は使用されるたびに評価されます(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回値を要求します。

これらの概念の詳細については、評価戦略の Wikipediaページ、および/cs/7702/applicative-order-and-normal-order-in-lambda-calculusを読むことをお勧めします


ありがとう、@ edalorzo。価値があると思われる場合は、それを受け入れることを検討してください。:)
Randall Cook
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.