Каково объяснение упражнения 1.6 в SICP?


Я только начинаю работать через SICP (самостоятельно; это не для класса), и я боролся с упражнением 1.6 в течение нескольких дней, и я просто не могу понять это. Это тот, где Алисса переопределяет if С точки зрения 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   51   2009-07-23 15:53:13

4 ответа:

new-if - Это функция. Когда вызывается функция, что первое, что делает схема со списком аргументов? Он оценивает все аргументы.

new-if Это процедура, и схема использует оценку прикладного порядка (1.1.5), поэтому даже до new-if фактически выполняется, он должен сначала оценить все аргументы, которые guess и (sqrt-iter (improve guess x) x). Вы можете видеть, что последний аргумент является рекурсией, которая вызывает новый new-if процедура, вот как происходит бесконечный цикл.

обычный if не нужно сначала оценивать его аргументы, просто идите по пути, это разница между if и new-if. :)

прежде всего, вы должны понимаете разницу между аппликативной оценкой порядка и нормальным порядком. Lisp использует прикладной порядок, но условные выражения вычисляются не так, как обычные функции (sicp глава 1.1.6):

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

чтобы вычислить выражение if, интерпретатор начинает с вычисления <predicate> часть выражения. Если <predicate> принимает значение true, то интерпретатор вычисляет <consequent> и возвращает его значение. В противном случае он оценивает <alternative> и возвращает его значение.

Ех1.6. новый-если:

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

разница с ' if-statements’: if-операторы оценивают один за другим из предиката -> consequent -> alternative,

однако "new-if" должен оценить все параметры aka аргументы в момент его вызова(что означает "else-предложение" оценивается в начале!!),

и таким образом это вызывает бесконечный цикл, когда любой из этих параметров называют себя в итерационный цикл