Ответ 1
new-if
- это функция. Когда вызывается функция, что первое, что Scheme делает с помощью списка аргументов? Он оценивает все аргументы.
Я только начинаю работать через 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
, ускользает от меня. Любая помощь очень ценится.
new-if
- это функция. Когда вызывается функция, что первое, что Scheme делает с помощью списка аргументов? Он оценивает все аргументы.
new-if
- это процедура, а схема использует оценку аппликативного порядка (1.1.5), поэтому даже до того, как выполняется new-if
, она должна сначала оценить все аргументы, которые являются guess
и (sqrt-iter (improve guess x) x)
. Вы можете видеть, что последний аргумент - это рекурсия, которая вызывает новую процедуру new-if
, так происходит бесконечный цикл.
Обычный if
не должен сначала оценивать свои аргументы, просто идти по пути, это разница между if
и new-if
.:)
Прежде всего, вы должны понять разницу между оценкой прикладного заказа и обычным порядком. Lisp использует аппликативный порядок, но условные выражения оцениваются не как обычные функции (sicp chapter 1.1.6):
(if <predicate> <consequent> <alternative>)
Чтобы оценить выражение if, интерпретатор начинает с вычисления части
<predicate>
выражения. Если значение<predicate>
соответствует истинному значению, интерпретатор затем оценивает значение<consequent>
и возвращает его значение. В противном случае он оценивает значение<alternative>
и возвращает его значение.