|
|
От: | Кодёнок | |
| Дата: | 29.07.05 13:52 | ||
| Оценка: | |||
Оглавление
Предисловие . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Предисловие ко второму изданию . . . . . . . . . . . . . . . . . . . . . vii
Предисловие к первому изданию . . . . . . . . . . . . . . . . . . . . . . ix
Благодарности . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
1 Построение абстракций с помощью процедур 1
1.1 Элементы программирования . . . . . . . . . . . . . . . . . . . . . 4
1.1.1 Выражения . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.2 Имена и окружение . . . . . . . . . . . . . . . . . . . . . . 6
1.1.3 Вычисление комбинаций . . . . . . . . . . . . . . . . . . . 7
1.1.4 Составные процедуры . . . . . . . . . . . . . . . . . . . . . 10
1.1.5 Подстановочная модель применения процедуры . . . . . . 11
1.1.6 Условные выражения и предикаты . . . . . . . . . . . . . . 14
1.1.7 Пример: вычисление квадратного корня методом Ньютона 18
1.1.8 Процедуры как абстракции типа «черный ящик» . . . . . 22
1.2 Процедуры и порождаемые ими процессы . . . . . . . . . . . . . . 26
1.2.1 Линейные рекурсия и итерация . . . . . . . . . . . . . . . 27
1.2.2 Древовидная рекурсия . . . . . . . . . . . . . . . . . . . . 31
1.2.3 Порядки роста . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.2.4 Возведение в степень . . . . . . . . . . . . . . . . . . . . . 38
1.2.5 Нахождение наибольшего общего делителя . . . . . . . . 41
1.2.6 Пример: проверка на простоту . . . . . . . . . . . . . . . . 42
1.3 Формулирование абстракций с помощью процедур высших по-
рядков . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.3.1 Процедуры в качестве аргументов . . . . . . . . . . . . . . 48
1.3.2 Построение процедур с помощью lambda . . . . . . . . . 53
1.3.3 Процедуры как обобщенные методы . . . . . . . . . . . . . 56
1.3.4 Процедуры как возвращаемые значения . . . . . . . . . . . 61
2 Построение абстракций с помощью данных 69
2.1 Введение в абстракцию данных . . . . . . . . . . . . . . . . . . . 72
2.1.1 Пример: арифметические операции над рациональными
числами . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
2.1.2 Барьеры абстракции . . . . . . . . . . . . . . . . . . . . . . 76
2.1.3 Что значит слово «данные»? . . . . . . . . . . . . . . . . . 78
2.1.4 Расширенный пример: интервальная арифметика . . . . . 81
2.2 Иерархические данные и свойство замыкания . . . . . . . . . . . 84
2.2.1 Представление последовательностей . . . . . . . . . . . . . 86
2.2.2 Иерархические структуры . . . . . . . . . . . . . . . . . . . 93
i
2.2.3 Последовательности как стандартные интерфейсы . . . . . 98
2.2.4 Пример: язык описания изображений . . . . . . . . . . . . 109
2.3 Символьные данные . . . . . . . . . . . . . . . . . . . . . . . . . . 124
2.3.1 Кавычки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
2.3.2 Пример: символьное дифференцирование . . . . . . . . . . 127
2.3.3 Пример: представление множеств . . . . . . . . . . . . . . 132
2.3.4 Пример: деревья кодирования по Хаффману . . . . . . . . 140
2.4 Множественные представления для абстрактных данных . . . . . 147
2.4.1 Представления комплексных чисел . . . . . . . . . . . . . 149
2.4.2 Помеченные данные . . . . . . . . . . . . . . . . . . . . . . 152
2.4.3 Программирование, управляемое данными, и аддитивность 156
2.5 Системы с обобщенными операциями . . . . . . . . . . . . . . . . 163
2.5.1 Обобщенные арифметические операции . . . . . . . . . . . 164
2.5.2 Сочетание данных различных типов . . . . . . . . . . . . . 168
2.5.3 Пример: символьная алгебра . . . . . . . . . . . . . . . . . 175
3 Модульность, объекты и состояние 189
3.1 Присваивание и внутреннее состояние объектов . . . . . . . . . . 190
3.1.1 Внутренние переменные состояния . . . . . . . . . . . . . 191
3.1.2 Преимущества присваивания . . . . . . . . . . . . . . . . . 196
3.1.3 Издержки, связанные с введением присваивания . . . . . 200
3.2 Модель вычислений с окружениями . . . . . . . . . . . . . . . . . 205
3.2.1 Правила вычисления . . . . . . . . . . . . . . . . . . . . . 206
3.2.2 Применение простых процедур . . . . . . . . . . . . . . . . 209
3.2.3 Кадры как хранилище внутреннего состояния . . . . . . . 212
3.2.4 Внутренние определения . . . . . . . . . . . . . . . . . . . 216
3.3 Моделирование при помощи изменяемых данных . . . . . . . . . 219
3.3.1 Изменяемая списковая структура . . . . . . . . . . . . . . 219
3.3.2 Представление очередей . . . . . . . . . . . . . . . . . . . . 227
3.3.3 Представление таблиц . . . . . . . . . . . . . . . . . . . . . 232
3.3.4 Имитация цифровых схем . . . . . . . . . . . . . . . . . . 237
3.3.5 Распространение ограничений . . . . . . . . . . . . . . . . 248
3.4 Параллелизм: время имеет значение . . . . . . . . . . . . . . . . . 257
3.4.1 Природа времени в параллельных системах . . . . . . . . 258
3.4.2 Механизмы управления параллелизмом . . . . . . . . . . . 262
3.5 Потоки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
3.5.1 Потоки как задержанные списки . . . . . . . . . . . . . . . 275
3.5.2 Бесконечные потоки . . . . . . . . . . . . . . . . . . . . . . 282
3.5.3 Использование парадигмы потоков . . . . . . . . . . . . . 288
3.5.4 Потоки и задержанное вычисление . . . . . . . . . . . . . 299
3.5.5 Модульность функциональных программ и модульность
объектов . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
4 Метаязыковая абстракция 309
4.1 Метациклический интерпретатор . . . . . . . . . . . . . . . . . . . 312
4.1.1 Ядро интерпретатора . . . . . . . . . . . . . . . . . . . . . 313
4.1.2 Представление выражений . . . . . . . . . . . . . . . . . . 317
4.1.3 Структуры данных интерпретатора . . . . . . . . . . . . . 324
4.1.4 Выполнение интерпретатора как программы . . . . . . . . 328
4.1.5 Данные как программы . . . . . . . . . . . . . . . . . . . . 331
ii
iii
4.1.6 Внутренние определения . . . . . . . . . . . . . . . . . . . 333
4.1.7 Отделение синтаксического анализа от выполнения . . . . 338
4.2 Scheme с вариациями: ленивый интерпретатор . . . . . . . . . . . 342
4.2.1 Нормальный порядок вычислений и аппликативный поря-
док вычислений . . . . . . . . . . . . . . . . . . . . . . . . 343
4.2.2 Интерпретатор с ленивым вычислением . . . . . . . . . . . 345
4.2.3 Потоки как ленивые списки . . . . . . . . . . . . . . . . . 351
4.3 Scheme с вариациями — недетерминистское вычисление . . . . . 354
4.3.1 Amb и search . . . . . . . . . . . . . . . . . . . . . . . . . 356
4.3.2 Примеры недетерминистских программ . . . . . . . . . . . 359
4.3.3 Реализация amb-интерпретатора . . . . . . . . . . . . . . . 366
4.4 Логическое программирование . . . . . . . . . . . . . . . . . . . . 376
4.4.1 Дедуктивный поиск информации . . . . . . . . . . . . . . . 379
4.4.2 Как действует система обработки запросов . . . . . . . . . 389
4.4.3 Является ли логическое программирование математиче-
ской логикой? . . . . . . . . . . . . . . . . . . . . . . . . . 396
4.4.4 Реализация запросной системы . . . . . . . . . . . . . . . 401
5 Вычисления на регистровых машинах 421
5.1 Проектирование регистровых машин . . . . . . . . . . . . . . . . 422
5.1.1 Язык для описания регистровых машин . . . . . . . . . . 425
5.1.2 Абстракция в проектировании машин . . . . . . . . . . . . 428
5.1.3 Подпрограммы . . . . . . . . . . . . . . . . . . . . . . . . . 430
5.1.4 Реализация рекурсии с помощью стека . . . . . . . . . . . 434
5.1.5 Обзор системы команд . . . . . . . . . . . . . . . . . . . . 442
5.2 Программа моделирования регистровых машин . . . . . . . . . . 443
5.2.1 Модель машины . . . . . . . . . . . . . . . . . . . . . . . . 444
5.2.2 Ассемблер . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
5.2.3 Порождение исполнительных процедур для команд . . . . 451
5.2.4 Отслеживание производительности машины . . . . . . . . 457
5.3 Выделение памяти и сборка мусора . . . . . . . . . . . . . . . . . 460
5.3.1 Память как векторы . . . . . . . . . . . . . . . . . . . . . . 460
5.3.2 Иллюзия бесконечной памяти . . . . . . . . . . . . . . . . 465
5.4 Вычислитель с явным управлением . . . . . . . . . . . . . . . . . 471
5.4.1 Ядро вычислителя с явным управлением . . . . . . . . . . 472
5.4.2 Вычисление последовательностей и хвостовая рекурсия . 478
5.4.3 Условные выражения, присваивания и определения . . . . 480
5.4.4 Запуск вычислителя . . . . . . . . . . . . . . . . . . . . . . 482
5.5 Компиляция . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
5.5.1 Структура компилятора . . . . . . . . . . . . . . . . . . . . 490
5.5.2 Компиляция выражений . . . . . . . . . . . . . . . . . . . . 495
5.5.3 Компиляция комбинаций . . . . . . . . . . . . . . . . . . . 500
5.5.4 Сочетание последовательностей команд . . . . . . . . . . . 506
5.5.5 Пример скомпилированного кода . . . . . . . . . . . . . . . 509
5.5.6 Лексическая адресация . . . . . . . . . . . . . . . . . . . . 517
5.5.7 Связь скомпилированного кода с вычислителем . . . . . . 520
Литература . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
Предметный указатель . . . . . . . . . . . . . . . . . . . . . . . . . . . 535