11

質問はここにあります。

本の中で、通常の順序評価の説明の 1 つを見つけました。

「別の評価モデルでは、オペランドの値が必要になるまでオペランドを評価しません。代わりに、最初に原始演算子のみを含む式が得られるまでパラメータの代わりにオペランド式を使用し、その後評価を実行します。」

また、「完全に拡大してから縮小する」という別の短い説明も見つけました。

演習では、 の定義は のpようなもの(lambda () (p))で、プリミティブ演算子に展開されず、したがって終了しないと思いました。

ただし、一方で、この質問に対するいくつかの回答をグーグルで調べた後、必要に応じて評価するだけで、実際に(p)は評価されないため、通常の順序評価は終了する必要があるようです。

したがって、「展開」と「評価」には何らかの違いがあるに違いないと思います。ここでインタープリターが行うことは、物事を評価することです。

違いは正確には何ですか、または見逃した点はありますか?

別の質問: "は "(p)に評価される(p)か、"(p)は " に展開され(p)ますか?

4

2 に答える 2

5

通常の評価規則で(p)は、引数なしで関数を呼び出すことによって評価されpます。たとえば (Common Lisp の場合):

> (defun p ()
    5)
  => P
> (p)
  => 5

あなたの質問は、「遅延評価」と呼ばれるものに言及することから始まりました。Common Lisp はデフォルトではこれを行いません。関数のすべての引数を左から右に評価します。スキームは、それらが評価される順序を指定していません。

ただし、物事を評価する前に、展開する必要があります (これは、Lisp では多くのことを意味します)。これにより、Lisp は評価の順序を制御できます。たとえばp、マクロである可能性があります。この場合、通常の評価ルールは必ずしも適用されません。繰り返しますが、Common Lisp では次のようになります。

> (defmacro p ()
    (print "I'm being expanded!") ; print on expansion
    (terpri) ; new line.
    `(progn (print "I'm being evaluated!") ; print on evaluation
            (terpri)
            5))
  => P

これは、読み取り評価印刷ループに入ります。式が読み取られ、展開され、評価され、出力されます。

> (p)
  I'm being expanded!
  I'm being evaluated!
  => 5

展開の評価を停止するには、ラムダに貼り付けましょう。拡張メッセージがまだ出力されていることに気付くでしょう。

> (defvar foo (lambda () (p)))
  I'm being expanded!
  => COMPILED FUNCTION #<LAMBDA>

これを呼び出すと、フォームが評価されます。

> (funcall foo) ; call the function 
  I'm being evaluated!
  => 5

マクロ呼び出しを単独で展開できます。

> (macroexpand-1 '(lambda () (p)))
  I'm being expanded!
  => (lambda () (progn (print "I'm being evaluated!")
                       (terpri)
                       5))

Haskell などの言語には、デフォルトで遅延評価があります。あなたが引用した一節で、SICP は Lisp の怠惰なバージョンを想像させます。このような Lisp が機能し、必要なものだけを評価するには、値に到達するまですべてをやみくもに展開して評価するだけでなく (SICP の置換モデルの説明を参照)、単に展開し、値を具体的に求められた場合にのみ、物事を評価します。Pこれを、ラムダ式の本体でマクロを展開し、値が必要なときに評価を強制した上記の例と比較できFUNCALLます。SICP の後半で、同様の手法を使用して遅延リストを実装します。

私が言ったように、Haskell はこの種のことを自動的に行います。同じことを行う Lisp を想像することは難しくありません (ただし、現在、一般的な Lisp はそうしていません)。本の実際の質問を考えると、私は少し話を逸らしたと思いますが、何が評価され、いつ評価されるか、そしてそれがもたらす違いについて少し理解していただければ幸いです。

于 2013-04-16T14:27:00.067 に答える