通常順と適用順の評価の違い


9

私が学んでいる言語はSchemeであり、これを行う演習に取り組んでいます:

(define (p) (p) )

(define (test x y) (if (= x 0)
                               0
                               y))

次に、質問は式(test 0(p))を評価し、通常の下で観察されるであろう動作(順序および適用順序の評価)についてコメントを求めます。

これらは私の考えです:

通常の順序では、プログラムは次に進む前に部分式を評価します。

したがって、次のように( test 0 (p) )なります。

(test 0 p)
( if (= x 0) 0 p))

出力を返す 0

適用順序の唯一の違いは、プログラムが次のように実行されることです。

( test 0 (p) ) になる:

(test 0 (p))
( if (= x 0) 0 (p)))

出力を返す 0

したがって、(p)必要がないため、評価されることはありません。

これは正しいです?私はプログラミングの経験がほとんどないので知らせてください。


1
質問は、Scheme言語自体を超えて、ここでの扱いを正当化するのに十分一般的であると感じました。
バブー2015年

回答:


19

その質問に答えるためにどのような研究をしましたか?私はそれをグーグルでそのままプラグインし、2番目の回答として取得しました(最初の回答は良いかもしれませんが、チェックしませんでした)トピックに関する聖書のセクションへの参照:Hal Abelson、Jerry Sussman、およびJulie Sussmanの構造コンピュータプログラムの解釈(MIT Press、1984; ISBN 0-262-01077-1)、別名ウィザードブック。参照先は、「通常の順序と適用される順序」のセクションです。

それは述べています:

Schemeは適用順序言語です。つまり、Schemeプロシージャへのすべての引数は、プロシージャが適用されるときに評価されます。対照的に、通常の順序の言語では、実際の引数の値が必要になるまで、プロシージャの引数の評価が遅れます。

後者は遅延評価と呼ばれていると付け加えます。

だからあなたはあなたの定義を間違っており、他のもののために一つを取る:

  • 適用順序は、プロシージャが適用されるとき、つまり直前に、部分式を評価します。

  • 通常の順序では、部分式は評価なしでそのまま渡され、対応する仮パラメーター自体が実際に評価される場合にのみ評価が続行されます。(環境問題に関してはさらにひねりがあります...しかし、現時点ではそれを忘れた方がよいでしょう)。

さらに、次の2つを含む呼び出しメカニズムを適切に理解していません。

  • 評価ルールに応じて、呼び出しへの実際の引数の適切な処理を含む、パラメーターを渡すメカニズム。

  • 関数の本体(ヘッダーなし)による関数呼び出しの「置換」。

以下の場合、応用的順評価( test 0 (p) )、あなたは、最初の引数のsubxpressionsを評価することになっています。これらは0 および(p)です。

  • のようなリテラル値の評価は、0その値をもたらします。

  • ただし、2番目の引数は、と呼ばれるパラメータなしのプロシージャへのプロシージャコールpです。パラメータがないので、評価の順番を気にする必要はありません。次に、評価を進めるために、呼び出しを引数のリストに続くプロシージャの本体に置き換え、その本体を評価する必要があります。p宣言(define (p) (p) )で定義されているように、手続きの本体は(p)なので、評価しようとしていたものの評価が残ります。つまり、評価プロセスはループに巻き込まれ、終了しません。

...そしてtest、その引数の評価が終了しないため、実際に関数の呼び出しを終了することはできません。プログラムは終了しません。

有罪の引数が呼び出しで使用されない場合でも、この非終了のリスクは、代わりに通常の順序評価を使用する理由の1つです。これは実装が少し難しいかもしれませんが、終了プロパティが優れている場合があります。

下では、通常の順序評価は、引数のサブ表現を触れないでください。あなたがやっていることは呼び出しを置き換えるある( test 0 (p) )関数の本体でtest、すなわち(if (= x 0) 0 y)(正式な)引数の名前、xおよびはy、対応する実引数に置き換えられます0(p)、(環境まで、または名前変更の問題が重要であることが、複雑になりますここでの説明、そしてオリジナルのLispとScheme言語の主な違いです)。

したがって、あなたはの評価を置き換える( test 0 (p) )の評価によって(if (= 0 0) 0 (p))

今、この関数はif通常、常にその最初の引数を評価する原始関数であるが、最初に評価されるかどうかに応じて、唯一の有用な1評価、通常のために、その最後の2つの引数を評価し、偽または(実際にNILまたは#fのために 虚偽の、または他のいくつかのSchemeの場合はtrueの値-私の記憶が失敗しない場合)。はtrueと評価(= 0 0)されるため、条件付きの量を評価することで、まだ評価されていない2番目の引数を評価します。00

深呼吸。


私はOPを通り第1章で定義と混同していると思う。この
SMA
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.