it-swarm.com.ru

Как объяснить упражнение 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, ускользает от меня. Любая помощь очень ценится.

56
Alex Basson

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

72
Greg Hewgill

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

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

32
Junjie Zhang

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

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

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

22
alex vasi

Ex1.6. новый, если:

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

Отличие от "if-операторов": операторы if оценивают одно за другим из предиката -> последующий -> альтернативный,

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

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

0
user8276400