Решение упражнения 1.6 из SICP

15 August, 2007 (20:49) | Решения упражнений

Отличное упражнение на понимание того, как происходит выполнение процедур.

Вспомним прошлое упражнение и тот факт, что Scheme при интерпретации использует аппликативный порядок вычислений. Итак, как же будет вычисляться фунция Лизы?

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

При вычислении new-if сначала должны быть вычислены все ее аргументы. С первыми двумя из них проблем нет, а вот при вычислении третьего new-if снова обращается к sqrt-iter, которая затем опять вызовет new-if… и так до бесконечности. Ограничивающего условия, обеспечивающего выход из этого порочного круга, нет. Таким образом программа Лизы, переписанная в таком виде, зациклится.

Почему же такой проблемы не возникает при использовании нормального if вместо new-if? Все просто. Обычный if является особой формой, он вычисляется не так, как стандартные процедуры. Для вычисления его значения не обязательно будут вычислены все операнды (более того, гарантированно будут вычислены только два из трех). Таким образом sqrt-iter будет вычисляться только в случае, когда решение еще не достаточно хорошее, а в противном случае вычисляться не будет, что и гарантирует выход из цикла.

Write a comment