Х. Абельсон, Дж. Дж. Сассман, Дж. Сассман - Структура и интерпретация компьютерных программ (1108516), страница 5
Текст из файла (страница 5)
Мы хотели бы поблагодаритьодаренных преподавателей — в особенности Джима Миллера, Билла Сиберта и МайкаАйзенберга, — которые разработали курсы повышения квалификации с использованиемэтих видеоматериалов и преподавали по ним в различных университетах и корпорацияхпо всему миру.Множество работников образования проделали значительную работу по переводупервого издания. Мишель Бриан, Пьер Шамар и Андре Пик сделали французское издание, Сюзанна Дэниелс-Хэрольд выполнила немецкий перевод, а Фумио Мотоёси —японский. Мы не знаем авторов китайского издания, однако считаем для себя честьюбыть выбранными в качестве объекта «неавторизованного» перевода.Трудно перечислить всех людей, внесших технический вклад в разработку системпрограммирования на языке Scheme, которые мы используем в учебных целях. Кроме Гая Стила, в список важнейших волшебников входят Крис Хансон, Джо Боубир,Джим Миллер, Гильермо Росас и Стефен Адамс.
Кроме них, существенное время исилы вложили Ричард Столлман, Алан Боуден, Кент Питман, Джон Тафт, Нил Мэйл,Джон Лэмпинг, Гуин Оснос, Трейси Ларраби, Джордж Карретт, Сома Чаудхури, БиллКиаркиаро, Стивен Кирш, Лей Клотц, Уэйн Носс, Тодд Кэсс, Патрик О’Доннелл, Кевин Теобальд, Дэниел Вайзе, Кеннет Синклер, Энтони Кортеманш, Генри М. Ву, ЭндрюБерлин и Рут Шью.Помимо авторов реализации MIT, мы хотели бы поблагодарить множество людей,работавших над стандартом Scheme IEEE, в том числе Уильяма Клингера и Джонатана Риса, которые редактировали R4 RS, а также Криса Хэйнса, Дэвида Бартли, КрисаХансона и Джима Миллера, которые подготовили стандарт IEEE.Долгое время Дэн Фридман был лидером сообщества языка Scheme.
Работа сообщества в более широком плане переходит границы вопросов разработки языка и включаетзначительные инновации в образовании, такие как курс для старшей школы, основанный на EdScheme компании Schemer’s Inc. и замечательные книги Майка Айзенберга,Брайана Харви и Мэтью Райта.Мы ценим труд тех, кто принял участие в превращении этой работы в настоящуюкнигу, особенно Терри Элинга, Ларри Коэна и Пола Бетджа из издательства MIT Press.Элла Мэйзел нашла замечательный рисунок для обложки. Что касается второго издания,то мы особенно благодарны Бернарду и Элле Мэйзел за помощь с оформлением книги, атакже Дэвиду Джонсу, великому волшебнику TEXа. Мы также в долгу перед читателя-20Благодарностими, сделавшими проницательные замечания по новому проекту: Джекобу Кацнельсону,Харди Мейеру, Джиму Миллеру и в особенности Брайану Харви, который был для этойкниги тем же, кем Джули была для его книги Просто Scheme.Наконец, мы хотели бы выразить признательность организациям, которые поддерживали нашу работу в течение этих лет.
Мы благодарны компании Хьюлетт-Паккард заподдержку, которая стала возможной благодаря Айре Гольдстейну и Джоэлю Бирнбауму, а также агентству DARPA за поддержку, которая стала возможной благодаря БобуКану.∗∗ Со своей стороны хотелось бы поблагодарить Константина Добкина, Андрея Комеча, Сергея Коропа, Алексея Овчинникова, Алекса Отта, Вадима Радионова, Марию Рубинштейн и особенно Бориса Смилгу. — прим.перев.Благодарностиpgh21ГЛАВА 1ПОСТРОЕНИЕАБСТРАКЦИЙ С ПОМОЩЬЮПРОЦЕДУРДействия, в которых ум проявляет своиспособности в отношении своих простыхидей, суть главным образом следующиетри: 1) Соединение нескольких простыхидей в одну сложную; так образовалисьвсе сложные идеи, 2) Сведение вместедвух идей, все равно, простых илисложных, и сопоставление их друг сдругом так, чтобы обозревать их сразу,но не соединять в одну; так умприобретает все свои идеи отношений,3) Обособление идей от всех другихидей, сопутствующих им в реальнойдействительности; это действиеназывается «абстрагированием», и приего помощи образованы все общие идеи вуме.Джон Локк.«Опыт о человеческом разуме» (1690)(Перевод А.Н.
Савина)Мы собираемся изучать понятие вычислительного процесса (computational process).Вычислительные процессы — это абстрактные существа, которые живут в компьютерах.Развиваясь, процессы манипулируют абстракциями другого типа, которые называютсяданными (data). Эволюция процесса направляется набором правил, называемым программой (program). В сущности, мы заколдовываем духов компьютера с помощью своихчар.Вычислительные процессы и вправду вполне соответствуют представлениям колдуна о ду́хах. Их нельзя увидеть или потрогать.
Они вообще сделаны не из вещества. Вто же время они совершенно реальны. Они могут выполнять умственную работу, могутотвечать на вопросы. Они способны воздействовать на внешний мир, оплачивая счета вбанке или управляя рукой робота на заводе. Программы, которыми мы пользуемся длязаклинания процессов, похожи на чары колдуна.
Они тщательно составляются из символических выражений на сложных и немногим известных языках программирования(programming languages), описывающих задачи, которые мы хотим поручить процессам.На исправно работающем компьютере вычислительный процесс выполняет программы точно и безошибочно. Таким образом, подобно ученику чародея, программисты-но-23вички должны научиться понимать и предсказывать последствия своих заклинаний. Даже мелкие ошибки (их обычно называют блохами (bugs) или глюками (glitches)), могутпривести к сложным и непредсказуемым последствиям.К счастью, обучение программированию не так опасно, как обучение колдовству,поскольку духи, с которыми мы имеем дело, надежно связаны.
В то же время программирование в реальном мире требует осторожности, профессионализма и мудрости.Например, мелкая ошибка в программе автоматизированного проектирования может привести к катастрофе самолета, прорыву плотины или самоуничтожению промышленногоробота.Специалисты по программному обеспечению умеют организовывать программы так,чтобы быть потом обоснованно уверенными: получившиеся процессы будут выполнять тезадачи, для которых они предназначены. Они могут изобразить поведение системы заранее. Они знают, как построить программу так, чтобы непредвиденные проблемы не привели к катастрофическим последствиям, а когда эти проблемы возникают, программистыумеютотлаживать (debug) свои программы. Хорошо спроектированные вычислительные системы, подобно хорошо спроектированным автомобилям или ядерным реакторам,построены модульно, так что их части могут создаваться, заменяться и отлаживаться поотдельности.Программирование на ЛиспеДля описания процессов нам нужен подходящий язык, и с этой целью мы используемязык программирования Лисп.
Точно так же, как обычные наши мысли чаще всего выражаются на естественном языке (например, английском, французском или японском), аописания количественных явлений выражаются языком математики, наши процедурныемысли будут выражаться на Лиспе. Лисп был изобретен в конце 1950-х как формализмдля рассуждений об определенном типе логических выражений, называемых уравнениярекурсии (recursion equations), как о модели вычислений. Язык был придуман Джоном Маккарти и основывается на его статье «Рекурсивные функции над символьнымивыражениями и их вычисление с помощью машины» (McCarthy 1960).Несмотря на то, что Лисп возник как математический формализм, это практическийязык программирования.
Интерпретатор (interpreter) Лиспа представляет собой машину, которая выполняет процессы, описанные на языке Лисп. Первый интерпретаторЛиспа написал сам Маккарти с помощью коллег и студентов из Группы по Искусственному Интеллекту Исследовательской лаборатории по Электронике MIT и Вычислительного центра MIT1 . Лисп, чье название происходит от сокращения английских слов LIStProcessing (обработка списков), был создан с целью обеспечить возможность символьнойобработки для решения таких программистских задач, как символьное дифференцирование и интегрирование алгебраических выражений.
С этой целью он содержал новыеобъекты данных, известные под названием атомов и списков, что резко отличало его отдругих языков того времени.Лисп не был результатом срежиссированного проекта. Он развивался неформально,экспериментальным путем, с учетом запросов пользователей и прагматических соображений реализации. Неформальная эволюция Лиспа продолжалась долгие годы, и сооб1 Руководство программиста по Лиспу 1 появилось в 1960 году, а Руководство программиста по Лиспу 1.5 (McCarthy 1965) в 1965 году.
Ранняя история Лиспа описана в McCarthy 1978.24Глава 1. Построение абстракций с помощью процедурщество пользователей Лиспа традиционно отвергало попытки провозгласить какое-либо«официальное» описание языка. Вместе с гибкостью и изяществом первоначального замысла такая эволюция позволила Лиспу, который сейчас по возрасту второй из широкоиспользуемых языков (старше только Фортран), непрерывно адаптироваться и вбирать всебя наиболее современные идеи о проектировании программ. Таким образом, сегодняЛисп представляет собой семью диалектов, которые, хотя и разделяют большую частьизначальных свойств, могут существенным образом друг от друга отличаться.
Тот диалект, которым мы пользуемся в этой книге, называется Scheme (Схема)2 .Из-за своего экспериментального характера и внимания к символьной обработке первое время Лисп был весьма неэффективен при решении вычислительных задач, по крайней мере по сравнению с Фортраном. Однако за прошедшие годы были разработаныкомпиляторы Лиспа, которые переводят программы в машинный код, способный производить численные вычисления с разумной эффективностью.
А для специализированныхприложений Лисп удавалось использовать весьма эффективно3. Хотя Лисп и не преодолел пока свою старую репутацию безнадежно медленного языка, в наше время ониспользуется во многих приложениях, где эффективность не является главной заботой.Например, Лисп стал любимым языком для оболочек операционных систем, а также в качестве языка расширения для редакторов и систем автоматизированного проектирования.Но коль скоро Лисп не похож на типичные языки, почему же мы тогда используем егокак основу для нашего разговора о программировании? Потому что этот язык обладаетуникальными свойствами, которые делают его замечательным средством для изученияважнейших конструкций программирования и структур данных, а также для соотнесенияих с деталями языка, которые их поддерживают.
Самое существенное из этих свойств —то, что лисповские описания процессов, называемые процедурами (procedures), сами посебе могут представляться и обрабатываться как данные Лиспа. Важность этого в том,что существуют мощные методы проектирования программ, которые опираются на возможность сгладить традиционное различение «пассивных» данных и «активных» процессов. Как мы обнаружим, способность Лиспа рассматривать процедуры в качестве данныхделает его одним из самых удобных языков для исследования этих методов.