|
||||||||||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[58] Передача сообщений Основная идея программирования, управляемого данными, состоит в том, чтобы работать с обобщенными операциями в программах при помощи явных манипуляций с таблицами операций и типов, вроде таблицы на рисунке 2.22. В стиле программирования, который мы применяли в разделе 2.4.2, диспетчеризация по типу организуется внутри каждой операции, и каждая операция должна сама заботиться о своей диспетчеризации. Это, в сущности, разбивает таблицу операций и типов на строки, и каждая обобщенная операция представляет собой строку таблицы. Альтернативой такой стратегии реализации будет разбить таблицу по столбцам и вместо «умных операций», которые диспетчируют по типам данных, работать с «умными объектами данных», которые диспетчируют по именам операций. Мы можем этого добиться, если устроим все так, что объект данных, например комплексное число в декартовом представлении, будет представляться в виде процедуры, которая в качестве входа воспринимает имя операции и осуществляет соответствующее ей действие. При такой организации можно написать make-from-real-imag в виде (define (make-from-real-imag x y) (define (dispatch op) (cond ((eq? op real-part) x) ((eq? op imag-part) y) ((eq? op magnitude) (sqrt (+ (square x) (square y)))) ((eq? op angle) (atan y x)) (else (error "Неизвестная оп. - MAKE-FROM-REAL-IMAG" op)))) dispatch) Соответствующая процедура apply-generic, которая применяет обобщенную операцию к аргументу, просто скармливает имя операции объекту данных и заставляет его делать всю работу:48 (define (apply-generic op arg) (arg op)) Обратите внимание, что значение, возвращаемое из make-from-real-imag, является процедурой - это внутренняя процедура dispatch. Она вызывается, когда apply-generic требует выполнить обобщенную операцию. Такой стиль программирования называется передача сообщений (message passing). Имя происходит из представления, что объект данных - это сущность, которая получает имя затребованной операции как «сообщение». Мы уже встречались с примером передачи сообщений в разделе 2.1.3, где мы видели, как cons, car и cdr можно определить безо всяких объектов данных, с одними только процедурами. Теперь мы видим, что передача сообщений не математический трюк, а полезный метод организации систем с обобщенными операциями. В оставшейся части этой главы мы будем продолжать пользоваться программированием, управляемым данными, а не передачей сообщений, и рассмотрим обобщенные арифметические операции. Мы вернемся к передаче 48У такой организации есть ограничение: она допускает обобщенные процедуры только от одного аргумента. сообщений в главе 3, и увидим, что она может служить мощным инструментом для структурирования моделирующих программ. Упражнение 2.75. Реализуйте в стиле передачи сообщений конструктор make-from-mag-ang. Он должен быть аналогичен приведенной выше процедуре make-from-real-imag. Упражнение 2.76. Когда большая система с обобщенными операциями развивается, могут потребоваться новые типы объектов данных или новые операции. Для каждой из трех стратегий - обобщенные операции с явной диспетчеризацией, стиль, управляемый данными, и передача сообщений, - опишите, какие изменения нужно произвести в системе, чтобы добавить новый тип или новую операцию. Какая организация лучше подходит для системы, в которую часто добавляются новые типы? Какая для системы, где часто появляются новые операции? 2.5 Системы с обобщенными операциями В предыдущем разделе мы увидели, как проектировать системы, где объекты данных могут быть представлены более чем одним способом. Основная идея состоит в том, чтобы связать код, который определяет операции над данными, и многочисленные реализации данных, при помощи обобщенных процедур интерфейса. Теперь мы увидим, что ту же самую идею можно использовать не только для того, чтобы определять обобщенные операции для нескольких реализаций одного типа, но и для того, чтобы определять операции, обобщенные относительно нескольких различных типов аргументов. Мы уже встречались с несколькими различными пакетами арифметических операций: элементарная арифметика (+, -, *, /), встроенная в наш язык, арифметика рациональных чисел (add-rat, sub-rat, mul-rat, div-rat) из раздела 2.1.1 и арифметика комплексных чисел, которую мы реализовали в разделе 2.4.3. Теперь мы, используя методы программирования, управляемого данными, создадим пакет арифметических операций, который включает все уже построенные нами арифметические пакеты. На рисунке 2.23 показана структура системы, которую мы собираемся построить. Обратите внимание на барьеры абстракции. С точки зрения человека, работающего с «числами», есть только одна процедура add, которая работает, какие бы числа ей ни дали. Add является частью обобщенного интерфейса, который позволяет программам, пользующимся числами, одинаковым образом обращаться к раздельным пакетам обыкновенной, рациональной и комплексной арифметики. Всякий конкретный арифметический пакет (например, комплексная арифметика) сам по себе доступен через обобщенные процедуры (например, add-complex), которые связывают пакеты, предназначенные для различных реализаций (таких, как декартовы и полярные числа). Более того, структура системы аддитивна, так что можно проектировать отдельные арифметические пакеты независимо и сочетать их, получая обобщенную арифметическую систему. Глава 2. Построение абстракций с помощью данных Программы, использующие числа add sub mul div Пакет обобщенной арифметики
Списковая структура и элементарная арифметика машины Рис. 2.23: Обобщенная арифметическая истема. 2.5.1 Обобщенные арифметические операции Задача проектирования обобщенных арифметических операций аналогична задаче проектирования обобщенных операций с комплексными числами. К примеру, нам бы хотелось иметь обобщенную процедуру сложения add, которая действовала бы как обычное элементарное сложение + по отношению к обычным числам, как add-rat по отношению к рациональным числам и как add-complex по отношению к комплексным. Реализовать add и прочие обобщенные арифметические операции мы можем, следуя той же стратегии, которую мы использовали в разделе 2.4.3 для обобщенных селекторов комплексных чисел. К каждому числу мы прикрепим метку типа и заставим обобщенную процедуру передавать управление в нужный пакет в соответствии с типами своих аргументов. Обобщенные арифметические процедуры определяются следующим образом: (define(add x y)(apply-generic add x y)) (define(sub x y)(apply-generic sub x y)) (define(mul x y)(apply-generic mul x y)) (define(div x y)(apply-generic div x y)) Начнем с установки пакета для работы с обычными числами, то есть элементарными числами нашего языка. Мы пометим их символом scheme-number. Арифметические операции этого пакета - это элементарные арифметические процедуры (так что нет никакой нужды определять дополнительные процедуры для обработки непомеченных чисел). Поскольку каждая из них принимает по два аргумента, в таблицу они заносятся с ключом-списком (scheme-number scheme-number) : (define (install-scheme-number-package) (define (tag x) (attach-tag scheme-number x)) (put add (scheme-number scheme-number) (lambda (x y) (tag (+ x y)))) (put sub (scheme-number scheme-number) |
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||||||||||