- •Оглавление
- •Предисловие
- •Предисловие к русскому изданию
- •Глава 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. Анализ
- •Комментарии
- •Алфавитный указатель
Предисловие
Цель данной книги – быстро и основательно научить вас языку Common Lisp. Книга состоит из двух частей: в первой части на множестве приме ров объясняются основные концепции программирования на Common Lisp, вторая часть – это современное описание стандарта ANSI Common Lisp, содержащее каждый оператор языка.
Аудитория
Книга «ANSI Common Lisp» предназначена как для студентов, изучаю щих этот язык, так и для профессиональных программистов. Ее чтение не требует предварительного знания Лиспа. Опыт написания программ на других языках был бы, безусловно, полезен, но не обязателен. Пове ствование начинается с основных понятий, что позволяет уделить осо бое внимание моментам, которые обычно приводят в замешательство человека, впервые знакомящегося с Лиспом.
Эта книга может использоваться в качестве учебного пособия по Лиспу или как часть курсов, посвященных искусственному интеллекту или теории языков программирования. Профессиональные разработчики, желающие изучить Лисп, оценят простой, практический подход. Те, кто уже знаком с языком, найдут в книге множество полезных примеров и оценят ее как удобный справочник по стандарту ANSI Common Lisp.
Как пользоваться книгой
Лучший способ выучить Лисп – использовать его. Кроме того, намного интереснее изучать язык в процессе написания программ. Книга устрое на так, чтобы читатель смог начать делать это как можно раньше. После небольшого введения в главе 2 объясняется все, что понадобится для создания первых Лисп-программ. В главах 3–9 рассматриваются клю чевые элементы программирования на Лиспе. Особое внимание уделя ется таким понятиям, как роль указателей в Лиспе, использование ре курсии и значимость функций как полноценных объектов языка.
Следующие материалы предназначены для читателей, которые хотят бо лее основательно разобраться с техникой программирования на Лиспе. Главы 10–14 охватывают макросы, CLOS (объектная система Common
14 |
Предисловие |
Lisp), операции со списками, оптимизацию, а также более сложные те мы, такие как пакеты и макросы чтения. Главы 15–17 подводят итог предыдущих глав на трех примерах реальных приложений: программа для создания логических интерфейсов, HTML-генератор и встроенный объектно-ориентированный язык программирования.
Последняя часть книги состоит из четырех приложений, которые будут полезны всем читателям. Приложения A–D включают руководство по отладке, исходные коды для 58 операторов языка, описание основных отличий ANSI Common Lisp от предыдущих версий языка° и справоч ник по каждому оператору в ANSI Common Lisp.
Книга завершается комментариями, содержащими пояснения, ссыл ки, дополнительный код и прочие отступления. Наличие комментария помечается в основном тексте маленьким кружочком: °.
Код
Несмотря на то что книга посвящена ANSI Common Lisp, по ней можно изучать любую разновидность Common Lisp. Примеры, демонстрирую щие новые возможности, обычно сопровождаются комментариями, по ясняющими, как они могут быть адаптированы к более ранним реали зациям.
Весь код из книги, ссылки на свободный софт, исторические докумен ты, часто задаваемые вопросы и множество других ресурсов доступны по адресу:
http://www.eecs.harvard.edu/onlisp/
Анонимный доступ к коду можно получить по ftp:
ftp://ftp.eecs.harvard.edu:/pub/onlisp/
Вопросы и комментарии присылайте на pg@eecs.harvard.edu.
«On Lisp»
В этой книге я постарался показать уникальные особенности, которые выделяют Лисп из множества языков программирования, а также пре доставляемые им новые возможности. Например, макросы – они позво ляют разработчику писать программы, которые будут писать другие программы. Лисп – единственный язык, который позволяет с легко стью осуществлять это, потому что только он предлагает необходимые для этого абстракции. Читателям, которым интересно узнать больше о макросах и других интересных возможностях языка, я предлагаю по знакомиться с книгой «On Lisp»1, которая является продолжением дан ного издания.
1Paul Graham «On Lisp», Prentice Hall, 1993. – Прим. перев.
Предисловие |
15 |
Благодарности
Из всех друзей, участвовавших в работе над книгой, наибольшую бла годарность я выражаю Роберту Моррису, который на протяжении всего времени помогал совершенствовать это издание. Некоторые примеры, включая Henley (cтр. 149) и сопоставление с образцом (стр. 254), взяты из написанного им кода.
Я был счастлив работать с первоклассной командой технических рецен зентов: Сконом Бриттаном (Skona Brittain), Джоном Фодераро (John Fo deraro), Ником Левином (Nick Levine), Питером Норвигом (Peter Norvig) и Дэйвом Турецки (Dave Touretzky). Вряд ли найдется хотя бы одна страница, к улучшению которой они не приложили руку. Джон Фоде раро даже переписал часть кода к разделу 5.7.
Нашлись люди, которые согласились прочитать рукопись целиком или частично, включая Кена Андерсона (Ken Anderson), Тома Читама (Tom Cheatham), Ричарда Фейтмана (Richard Fateman), Стива Хайна (Steve Hain), Барри Марголина (Barry Margolin), Уолдо Пачеко (Waldo Pache co), Вилера Румла (Wheeler Ruml) и Стюарта Рассела (Stuart Russel). Кен Андерсон и Вилер Румл сделали множество полезных замечаний.
Яблагодарен профессору Читаму и Гарварду в целом за предоставление необходимых для написания книги возможностей. Также благодарю сотрудников лаборатории Айкен: Тони Хэртмана (Tony Hartman), Дей ва Мазиерса (Dave Mazieres), Януша Джуду (Janusz Juda), Гарри Бохне ра (Harry Bochner) и Джоанну Клис (Joanna Klys).
Ярад, что у меня снова появилась возможность поработать с сотрудни ками Prentice Hall: Аланом Аптом (Alan Apt), Моной Помпили (Mona Pompili), Ширли МакГир (Shirley McGuire) и Ширли Майклс (Shirley Michaels). Обложка книги выполнена превосходным мастером Джино Ли (Gino Lee) из Bow & Arrow Press, Кэмбридж.
Эта книга была набрана с помощью LATEX, языка, созданного Лесли Лэм портом (Leslie Lamport) поверх TEX’а Дональда Кнута (Donald Knuth), с использованием дополнительных макросов авторства Л.А. Карра (L.A. Carr), Вана Якобсона (Van Jacobson) и Гая Стила (Guy Steele). Чер тежи были выполнены с помощью программы Idraw, созданной Джо ном Влиссидсом (John Vlissids) и Скоттом Стантоном (Skott Stanton) . Предпросмотр всей книги был сделан с помощью программы Ghost view, написанной Тимом Тейзеном (Tim Theisen) на основе интерпрета тора Ghostscript, созданного Л. Питером Дойчем (L. Peter Deutch).
Я должен поблагодарить и многих других людей: Генри Бейкера (Henry Baker), Кима Барретта (Kim Barrett), Ингрид Бассет (Ingrid Basset), Тревора Блеквелла (Trevor Blackwell), Пола Беккера (Paul Becker), Гар ри Бисби (Gary Bisbee), Франка Душмана (Frank Dueschmann), Фран сиса Дикли (Frances Dickey), Рича и Скотта Дрейвса (Rich and Scott Draves), Билла Дабак (Bill Dubuque), Дэна Фридмана (Dan Friedman),
16 |
Предисловие |
Дженни Грэм (Jenny Graham), Эллис Хартли (Alice Hartley), Дэвида Хендлера (David Hendler), Майка Хьюлетта (Mike Hewlett), Гленна Хол ловота (Glenn Hollowat), Брэда Карпа (Brad Karp), Соню Кини (Sonya Keene), Росса Найтс (Ross Knights), Митсуми Комуро (Mutsumi Komu ro), Стефи Кутзиа (Steffi Kutzia), Дэвида Кузника (David Kuznick), Мэ ди Лорд (Madi Lord), Джулию Маллози (Julie Mallozzi), Пола МакНами (Paul McNamee), Дэйва Муна (Dave Moon), Говарда Миллингса (Howard Mullings), Марка Ницберга (Mark Nitzberg), Ненси Пармет (Nancy Par met) и ее семью, Роберта Пенни (Robert Penny), Майка Плуча (Mike Plusch), Шерил Сэкс (Cheryl Sacks), Хейзэма Сейеда (Hazem Sayed), Шеннона Спайреса (Shannon Spires), Лоу Штейнберга (Lou Steinberg), Пола Стоддарда (Paul Stoddard), Джона Стоуна (John Stone), Гая Стила (Guy Steele), Стива Страссмана (Steve Strassmann), Джима Вейча (Jim Veitch), Дэйва Уоткинса (Dave Watkins), Айдела и Джулианну Вебер (Idelle and Julian Weber), Вейкерсов (the Weickers), Дэйва Йоста (Dave Yost) и Алана Юлли (Alan Yuille).
Но больше всего я благодарен моим родителям и Джекки.
Дональд Кнут назвал свою известную серию книг «Искусство програм мирования». В прочитанной им Тьюринговской лекции он объяснил, что это название было выбрано не случайно, так как в программирова ние его привела как раз «возможность писать красивые программы».
Так же как и архитектура, программирование сочетает в себе искусст во и науку. Программа создается на основе математических принципов, так же как здание держится согласно законам физики. Но задача архи тектора не просто построить здание, которое не разрушится. Почти все гда он стремится создать нечто прекрасное.
Как и Дональд Кнут, многие программисты чувствуют, что такова ис тинная цель программирования. Так считают почти все Лисп-хакеры. Саму суть лисп-хакерства можно выразить двумя фразами. Програм мирование должно доставлять радость. Программы должны быть кра сивыми. Таковы идеи, которые я постарался пронести через всю книгу.
Пол Грэм