- •Оглавление
- •Предисловие
- •Предисловие к русскому изданию
- •Глава 1. Введение
- •1.1. Новые инструменты
- •1.2. Новые приемы
- •1.3. Новый подход
- •Глава 2. Добро пожаловать в Лисп
- •2.1. Форма
- •2.2. Вычисление
- •2.3. Данные
- •2.4. Операции со списками
- •2.5. Истинность
- •2.6. Функции
- •2.7. Рекурсия
- •2.8. Чтение Лиспа
- •2.9. Ввод и вывод
- •2.10. Переменные
- •2.11. Присваивание
- •2.12. Функциональное программирование
- •2.13. Итерация
- •2.14. Функции как объекты
- •2.15. Типы
- •2.16. Заглядывая вперед
- •Итоги главы
- •Упражнения
- •Глава 3. Списки
- •3.1. Ячейки
- •3.2. Равенство
- •3.3. Почему в Лиспе нет указателей
- •3.4. Построение списков
- •3.5. Пример: сжатие
- •3.6. Доступ
- •3.7. Отображающие функции
- •3.8. Деревья
- •3.9. Чтобы понять рекурсию, нужно понять рекурсию
- •3.10. Множества
- •3.11. Последовательности
- •3.12. Стопка
- •3.13. Точечные пары
- •3.14. Ассоциативные списки
- •3.15. Пример: поиск кратчайшего пути
- •3.16. Мусор
- •Итоги главы
- •Упражнения
- •Глава 4. Специализированные структуры данных
- •4.1. Массивы
- •4.2. Пример: бинарный поиск
- •4.3. Строки и знаки
- •4.4. Последовательности
- •4.5. Пример: разбор дат
- •4.6. Структуры
- •4.7. Пример: двоичные деревья поиска
- •4.8. Хеш-таблицы
- •Итоги главы
- •Упражнения
- •Глава 5. Управление
- •5.1. Блоки
- •5.2. Контекст
- •5.3. Условные выражения
- •5.4. Итерации
- •5.5. Множественные значения
- •5.6. Прерывание выполнения
- •5.7. Пример: арифметика над датами
- •Итоги главы
- •Упражнения
- •Глава 6. Функции
- •6.1. Глобальные функции
- •6.2. Локальные функции
- •6.3. Списки параметров
- •6.4. Пример: утилиты
- •6.5. Замыкания
- •6.6. Пример: строители функций
- •6.7. Динамический диапазон
- •6.8. Компиляция
- •6.9. Использование рекурсии
- •Итоги главы
- •Упражнения
- •Глава 7. Ввод и вывод
- •7.1. Потоки
- •7.2. Ввод
- •7.3. Вывод
- •7.4. Пример: замена строк
- •7.5. Макрознаки
- •Итоги главы
- •Упражнения
- •Глава 8. Символы
- •8.1. Имена символов
- •8.2. Списки свойств
- •8.3. А символы-то не маленькие
- •8.4. Создание символов
- •8.5. Использование нескольких пакетов
- •8.6. Ключевые слова
- •8.7. Символы и переменные
- •8.8. Пример: генерация случайного текста
- •Итоги главы
- •Упражнения
- •Глава 9. Числа
- •9.1. Типы
- •9.2. Преобразование и извлечение
- •9.3. Сравнение
- •9.4. Арифметика
- •9.5. Возведение в степень
- •9.6. Тригонометрические функции
- •9.7. Представление
- •9.8. Пример: трассировка лучей
- •Итоги главы
- •Упражнения
- •Глава 10. Макросы
- •10.1. Eval
- •10.2. Макросы
- •10.3. Обратная кавычка
- •10.4. Пример: быстрая сортировка
- •10.5. Проектирование макросов
- •10.6. Обобщенные ссылки
- •10.7. Пример: макросы-утилиты
- •10.8. На Лиспе
- •Итоги главы
- •Упражнения
- •Глава 11. CLOS
- •11.1. Объектно-ориентированное программирование
- •11.2. Классы и экземпляры
- •11.3. Свойства слотов
- •11.4. Суперклассы
- •11.5. Предшествование
- •11.6. Обобщенные функции
- •11.7. Вспомогательные методы
- •11.8. Комбинация методов
- •11.9. Инкапсуляция
- •11.10. Две модели
- •Итоги главы
- •Упражнения
- •Глава 12. Структура
- •12.1. Разделяемая структура
- •12.2. Модификация
- •12.3. Пример: очереди
- •12.4. Деструктивные функции
- •12.5. Пример: двоичные деревья поиска
- •12.6. Пример: двусвязные списки
- •12.7. Циклическая структура
- •12.8. Неизменяемая структура
- •Итоги главы
- •Упражнения
- •Глава 13. Скорость
- •13.1. Правило бутылочного горлышка
- •13.2. Компиляция
- •13.3. Декларации типов
- •13.4. Обходимся без мусора
- •13.5. Пример: заранее выделенные наборы
- •13.6. Быстрые операторы
- •13.7. Две фазы разработки
- •Итоги главы
- •Упражнения
- •Глава 14. Более сложные вопросы
- •14.1. Спецификаторы типов
- •14.2. Бинарные потоки
- •14.3. Макросы чтения
- •14.4. Пакеты
- •14.5. Loop
- •14.6. Особые условия
- •Глава 15. Пример: логический вывод
- •15.1. Цель
- •15.2. Сопоставление
- •15.3. Отвечая на запросы
- •15.4. Анализ
- •Глава 16. Пример: генерация HTML
- •16.1. HTML
- •16.2. Утилиты HTML
- •16.3. Утилита для итерации
- •16.4. Генерация страниц
- •Глава 17. Пример: объекты
- •17.1. Наследование
- •17.2. Множественное наследование
- •17.3. Определение объектов
- •17.4. Функциональный синтаксис
- •17.5. Определение методов
- •17.6. Экземпляры
- •17.7. Новая реализация
- •17.8. Анализ
- •Комментарии
- •Алфавитный указатель
Итоги главы |
109 |
(defun num->date (n)
(multiple-value-bind (y left) (num-year n) (multiple-value-bind (m d) (num-month left y)
(values d m y))))
(defun num-year |
(n) |
||
(if (< n 0) |
|
|
|
(do* ((y (- |
yzero 1) (- y 1)) |
||
|
(d (- |
(year-days y)) (- d (year-days y)))) |
|
|
((<= |
d |
n) (values y (- n d)))) |
(do* ((y yzero (+ y 1)) |
|||
|
(prev |
0 d) |
|
|
(d (year-days y) (+ d (year-days y)))) |
||
|
((> d n) (values y (- n prev)))))) |
||
(defun num-month (n y) |
|||
(if (leap? y) |
|
|
|
(cond |
((= |
n |
59) (values 2 29)) |
|
((> |
n |
59) (nmon (- n 1))) |
|
(t |
|
(nmon n))) |
(nmon |
n))) |
|
|
(defun nmon |
(n) |
|
|
(let ((m (position n month :test #’<))) |
|||
(values |
m (+ 1 (- n (svref month (- m 1))))))) |
||
(defun date+ (d |
m |
y n) |
|
(num->date (+ |
(date->num d m y) n))) |
Рис. 5.2. Операции с датами: преобразование целых чисел в даты
Итоги главы
1.В Common Lisp есть три основных конструкции для блоков: progn, block с возможностью немедленного выхода (return) и tagbody, внутри которой работает goto. Многие встроенные операторы используют неявные блоки.
2.Создание нового лексического контекста эквивалентно вызову функ ции.
3.В Common Lisp есть набор условных операторов, приспособленных для различных ситуаций. Все они могут быть определены с помо щью if.
4.В Common Lisp есть также разнообразные итерационные операторы.
5.Выражения могут возвращать несколько значений.
6.Вычисления могут быть прерваны, а также могут быть защищены от последствий таких прерываний.
110 |
Глава 5. Управление |
Упражнения
1.Запишите следующие выражения без использования let или let*, а также без вычисления одного и того же выражения дважды:
(a)(let ((x (car y))) (cons x x))
(b)(let* ((w (car x))
(y (+ w z))) (cons w y))
2.Перепишите функцию mystery (стр. 46) с использованием cond.
3.Определите функцию, возвращающую квадрат своего аргумента, лишь когда аргумент – положительное число, меньшее или равное пяти.
4.Перепишите month-num (рис. 5.1), используя case вместо svref.
5.Определите функцию (рекурсивную и итеративную версии) от объ екта x и вектора v, возвращающую список объектов, следующих не посредственно перед x в v:
>(precedes #\a "abracadabra") (#\c #\d #\r)
6.Определите функцию (итеративно и рекурсивно), принимающую объ ект и список и возвращающую новый список, в котором заданный элемент находится между каждой парой элементов исходного списка:
>(intersperse ’- ’(a b c d))
(A - B - C - D)
7.Определите функцию, принимающую список чисел и возвращаю щую истину, если разница между каждой последующей их парой равна 1. Используйте:
(a)рекурсию
(b)do
(c)mapc и return
8.Определите одиночную рекурсивную функцию, которая возвращает два значения – максимальный и минимальный элементы вектора.
9.Программа на рис. 3.12 продолжает поиск после нахождения перво го подходящего пути в очереди. Для больших сетей это может стать проблемой.
(a)Используя catch и throw, измените программу таким образом, чтобы она возвращала первый найденный путь сразу же после того, как он найден.
(b)Перепишите программу, чтобы она делала то же самое без ис пользования catch и throw.