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

25 February, 2008 (20:14) | Решения упражнений

Объект z, с которым мы работаем в этом упражнении и для которого мы хотим вычислить модуль (magnitude), – это дважды помеченная пара, представляющая собой комплексное число в декартовой форме. Он состоит из метки complex, за которой следует метка rectangular, а уже затем идет представление числа.

Процедура magnitude задана в разделе 2.4.3 и выглядит следующим образом:

(define (magnitude z) (apply-generic 'magnitude z))

Когда мы вызываем (magnitude z), не определив никаких дополнительных элементов в таблице типов, у apply-generic есть выбор только из двух типов, для которых задана процедура magnitude: rectangular и polar. Эти типы были проинсталлированы в систему ранее и содержали вызовы put для операции magnitude.

Однако в нашем объекте z первой идет метка типа complex, а не rectangular! Поэтому процедура apply-generic выдает Хьюго сообщение об ошибке.

Совет Лизы относительно добавления в пакет для работы с комплексными числами еще нескольких операций put, пополняющих таблицу типов, абсолютно верный. При этом мы фактически разрешаем операции (real-part, imag-part, magnitude, angle) не только для типов rectangular и polar (то есть для объектов с метками типа ‘rectangular и ‘polar), но и для типа complex.

При вызове (magnitude z) по-прежнему вызовется apply-generic c параметрами ‘magnitude и ‘(complex). Однако на этот раз в ячейке таблицы типов, соответствующей операции magnitude и типу complex уже не будет пусто, а будет записана процедура. Причем в этой ячейке будет записана… сама процедура magnitude. Таким образом apply-generic вновь диспетчиризует к magnitude, с одним только важным изменением: она уже сняла внешнюю метку типа complex с объекта z. Теперь magnitude вычисляется для объекта с меткой типа rectangular. Для этого еще раз вызывается apply-generic, которая на этот раз диспетчеризует к процедуре, находящейся в таблице типов в ячейке, соответствующей операции magnitude и типу rectangular, то есть процедуре из пакета декартового представления комплексных чисел, возвращающей квадратный корень из суммы квадратов действительной и мнимой частей комплексного числа, представленного в декартовой форме.

То есть все работает отлично благодаря происходящей двойной диспетчеризации.

Write a comment