- •Оглавление
- •Предисловие
- •Предисловие к русскому изданию
- •Глава 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. Анализ
- •Комментарии
- •Алфавитный указатель
128 |
Глава 6. Функции |
Итеративная версия менее понятна, зато намного более эффективна. Как часто на практике имеют место такие различия? Очень редко, и именно поэтому в различных книгах приводится один и тот же пример. Тем не менее таких ситуаций следует остерегаться.
Итоги главы
1.Именованная функция хранится как symbol-function соответствую щего символа. Макрос defun скрывает подобные детали. Кроме того, он позволяет сопровождать функции документацией, а также на страивать поведение setf.
2.Имеется возможность определять локальные функции; этот процесс напоминает определение локальных переменных.
3.Функции могут иметь необязательные и остаточные аргументы, а также аргументы по ключу.
4.Утилиты дополняют язык. Они представляют собой пример про граммирования снизу-вверх в маленьком масштабе.
5.Лексические переменные существуют до тех пор, пока на них ссыла ется какой-либо объект. Замыкания – это функции, ссылающиеся на свободные переменные. Вы можете самостоятельно определять функции, возвращающие замыкания.
6.Dylan предоставляет функции для построения других функций. С ис пользованием замыканий мы легко можем реализовать их в Common Lisp.
7.Специальные переменные имеют динамический диапазон.
8.Функции могут компилироваться индивидуально или (чаще) в со ставе файла.
9.Рекурсивный алгоритм решает задачу разделением ее на конечное число похожих подзадач меньшего размера.
Упражнения
1.Определите версию tokens (стр. 81), которая использует ключи :test
и:start, по умолчанию равные #’constituent и 0 соответственно.
2.Определите версию bin-search (стр. 75), использующую ключи :key, :test, :start и :end, имеющие обычные для них значения по умолча нию.
3.Определите функцию, принимающую любое количество аргументов
ивозвращающую их количество.
4.Измените функцию most (стр. 118) так, чтобы она возвращала два зна чения – два элемента, имеющие наибольший вес.
5.Определите remove-if (без аргументов по ключу) с помощью filter (стр. 117).
Упражнения |
129 |
6.Определите функцию, принимающую одно число и возвращающую наибольшее число из всех ранее полученных ею.
7.Определите функцию, принимающую одно число и возвращающую его же, если оно больше числа, переданного этой функции на преды дущем вызове. Во время первого вызова эта функция должна возвра щать nil.
8.Предположим, что функция expensive имеет один аргумент – целое число между 0 и 100 включительно. Она производит сложные и до рогостоящие вычисления. Определите функцию frugal, возвращаю щую тот же ответ, что и expensive, но вызывающую expensive, лишь когда ей передается аргумент, который не встречался ранее.
9.Определите функцию наподобие apply, но где все числа, которые мо гут быть напечатаны при ее выполнении, выводятся в восьмеричном формате (base 8).