Вопрос

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

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

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

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

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

Пр1.6.новый-если:

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

Разница с «if-операторами»:Операторы if оцениваются один за другим из предиката -> следствия -> альтернативы,

однако «new-if» должен оценивать все параметры, то есть аргументы, в МОМЕНТ, который он вызывает (что означает, что «else-предложение» оценивается в начале!!),

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top