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

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

Рассмотрим, что нам нужно сделать при добавлении нового типа или новой операции в систему с обобщенными операциями при разных стратегиях представления операций и типов.

1. Обобщенные операции с явной диспетчеризацией.При добавлении типа нам нужно будет:

  • добавить специфичные операции типа по числу операций в системе;
  • изменить все обобщенные операции, добавив в каждую условия проверки метки нового типа и вызова соответствующей операции нового типа.

При добавлении новой операции нам нужно будет:

  • добавить для каждого типа специфичную реализацию этой операции;
  • добавить обобщенную операцию в систему.

2. Стиль, управляемый данными.

При добавлении типа нам нужно будет:

  • добавить пакет со всеми операциями реализованными для этого типа;
  • добавить все реализации операций в таблицу типов с тегом этого типа.

Обобщенные операции при этом менять не нужно!

При добавлении новой операции нам нужно будет:

  • изменить все пакеты типов, добавив для каждого типа специфичную реализацию этой операции и добавить эту реализацию в таблицу типов;
  • добавить обобщенную операцию в систему.

3. Передача сообщений.

При добавлении типа нам нужно будет:

  • добавить тип в виде конструктора с процедурой диспетчеризации, содержащей условия для каждой операции в системе;

Обобщенные операции при этом менять не нужно!

При добавлении новой операции нам нужно будет:

  • изменить все конструкторы, добавив в каждый из них условие диспетчеризации для новой операции и ее реализацию для каждого типа;
  • добавить обобщенную операцию в систему.

Какая же стратегия лучше при частом добавлении новых типов, а какая – при частом добавлении новых операций? В случае добавление нового типа меньше всего телодвижений приходится делать при передаче сообщений. В случае же добавления новой операции все не так однозначно. По большому счету, ни один из подходов не имеет большого преимущества перед другими.

Я был бы рад обсудить это упражнение. Мне кажется, что я тут мог упустить нечто важное. Комментарии приветствуются.

Comments

Comment from Андрей
Date: March 18, 2008, 5:08 pm

ИМХО вопрос должен стоять не в количестве телодвижений – они во всех случаях примерно одинаковые. Писать чуть меньше кода или чуть больше – это не так важно как то, где этот код писать/вставлять. Тогда очевидно, что при добавлении нового типа удобнее варианты с управлением данными и передачей сообщений, т.к. все изменения локализованы в пакетах/конструкторах типов. Когда добавляются новые операции удобнее пользоваться явной диспетчеризацией, т.к. тогда все изменения коснуться только новой операции и специфика для каждого типа может быть упрятана в нее.

Мне кажется задача намекает на инкапсуляцию. Вообще весь раздел 2.4 очень сильно перекликается с ООП. Скажем, примеры с таблицами процедур разбитыми по типам и операциям – это фактически прямой путь к реализации перегружаемых методов/операторов из C++/JAVA/подобные. Более того, они в реальности практически так и реализованы. Передача сообщений – очень близка к ООП а-ля Smalltalk. Вообще конечно забавно как меняется представление о других языках при прочтении сикп и необходимости существования специальных синтаксических конструкций для реализации тех или иных парадигм.

Comment from Dima
Date: September 2, 2008, 2:20 am

В “Стиль, управляемый данными”, при добавлении новой операции не обязательно изменять пакеты типов. Можно сделать новый пакет с одной операцией для всех типов. Тогда менять вообще ничего не надо.

Write a comment