76

私はちょうど SICP の作業を始めたところです (これはクラス用ではありません)。演習 1.6 で数日間苦労してきましたが、まったく理解できないようです。ifこれは、Alyssaが に関して次のcondように再定義したものです。

(define (new-if predicate then-clause else-clause)
    (cond (predicate then-clause)
          (else else-clause))

彼女はそれをいくつかの単純なケースでうまくテストし、それを使って平方根プログラムを書き直しました (これは でうまくいきましたif):

(define (sqrt-iter guess x)
    (new-if (good-enough? guess x)
            guess
            (sqrt-iter (improve guess x)
                       x)))

次に、「アリッサがこれを使用して平方根を計算しようとするとどうなりますか?説明してください。」という質問が表示されます。good-enough?[必要に応じて、他の手順 ( 、など)を再現improveさせていただきます。お知らせください。]

これで、何が起こるかわかりました。値を返すことはありません。つまり、プログラムは無限に再帰します。なぜこれが起こるのか説明できません。ifとの間に存在する微妙な違いが何であれ、new-if私を逃れています。ありとあらゆる助けが大歓迎です。

4

6 に答える 6

101

new-if関数です。関数が呼び出されたとき、Scheme が引数リストに対して最初に行うことは何ですか? すべての引数を評価します。

于 2009-07-23T11:55:44.370 に答える
55

new-ifはプロシージャであり、Schemeは適用順序評価(1.1.5)を使用するため、new-if実際に実行される前であっても、最初にすべての引数であるとを評価する必要がguessあり(sqrt-iter (improve guess x) x)ます。後者の引数は、新しいプロシージャを呼び出す再帰であることがわかりnew-ifます。これが、無限ループが発生する方法です。

通常は、最初に引数を評価する必要はありません。途中で、これがとifの違いです。:)ifnew-if

于 2011-12-12T12:36:38.313 に答える
28

まず、適用順序評価と通常順序の違いを理解する必要があります。Lisp は適用可能な順序を使用しますが、条件式は通常の関数とは異なり評価されます ( sicp 章 1.1.6 ):

(if <predicate> <consequent> <alternative>)

if 式を評価するために、インタープリターは<predicate>式の一部を評価することから始めます。<predicate>が true 値に評価される場合、インタープリターは を評価し<consequent>、その値を返します。それ以外の場合は、 を評価して<alternative>その値を返します。

于 2009-07-23T13:04:57.923 に答える