Когда программисты обсуждают преимущества тех или других языков программирования, они часто рассуждают о них в прозаических терминах, как об инструментах в наборе различных приспособлений – один больше подходит для системного программирования, другой – для склеивания других программ в целях решения текущей задачи. Так и должно быть. У языков разные сильные стороны, и заявлять, что один язык лучше других языков, не указывая конкретных примеров, — значит, лишь вызывать непродуктивные и резкие споры.
Однако есть один язык, который странным образом вызывает всеобщее уважение: Lisp. Крестоносцы клавиатур, готовые атаковать любого, кто посмеет заявить, что какой-либо язык лучше других, сходятся в том, что Лисп находится на другом уровне. Он выходит за пределы утилитарных критериев, по которым судят другие языки, поскольку средний программист никогда не использовал Лисп для создания чего-либо практического, и, вероятно, никогда не будет этого делать, однако же, уважение к Лиспу настолько глубокое, что ему часто приписывают мифические свойства. Всеми любимые комиксы xkcd изображали таким образом Лисп как минимум дважды: в одном комиксе персонаж достигает Лисп-просветления, которое помогает ему познать фундаментальную структуру Вселенной. В другом старый программист в халате передаёт стопку круглых скобок своему падавану, объясняя, что это – «элегантное оружие для более цивилизованных времён», намекая на присущие Лиспу оккультные возможности Силы.
Ещё один прекрасный пример – пародия Боба Канефского на песню «Бог живёт на Терре». Его пародия написана в середине 90-х и называется «Вечное пламя». Она описывает, как, по-видимому, Бог создал мир при помощи Лиспа. Далее приводим отрывок, а полную версию можно найти на сайте GNU Humor Collection:
Ведь Бог писал на Лиспе
Когда заполнил листья зелёным.
Фрактальные цветки и рекурсивные корни:
Самый красивый хак из виденных мною.
А когда я изучаю снежинки,
И не нахожу двух одинаковых,
Я знаю, что Бог любит язык
Со своим собственным четырёхбуквенным названием.
Говорю только за себя, но мне кажется, что культурный мем «Лисп – это тайное волшебство», это самое странное и интересное явление. Лисп был задуман в башне из слоновой кости в качестве инструмента для исследований искусственного интеллекта, поэтому он всегда будет немного незнакомым и загадочным для простых программистов. Однако сейчас программисты подначивают друг друга «попробуй Лисп перед тем, как умереть», как будто это какое-то психоделическое средство, расширяющее сознание. Они делают это несмотря на то, что Лисп – второй по возрасту из самых старых языков программирования, которые ещё используют, уступая лишь Фортрану, и то, всего на год. Представьте, что вам поручила бы рекламу какого-то нового языка программирования компания или команда, которая его разработала. Разве не было бы классно суметь убедить всех, что у вашего нового языка есть божественные силы? Но как этого можно было бы достичь? Как язык программирования прославился в роли источника тайного знания?
Как Лисп дошёл до жизни такой?
Обложка журнала Byte, август 1979
Теория А: аксиоматический язык
Джон Маккарти, создатель Лиспа, изначально не стремился к тому, чтобы Лисп был элегантной сутью вычислительных принципов. Но, после одной-двух удачных идей и нескольких улучшений, Лисп превратился именно в это. Пол Грэм – о нём мы расскажем позже – писал, что, создав Лисп, Маккарти «сделал для программирования то же, что Евклид для геометрии». Возможно, люди ищут в Лиспе глубокий смысл, потому что Маккарти создал его из настолько фундаментальных частей, что тяжело сказать, изобрёл он его или открыл.
Маккарти начал размышлять о создании языка во время Дартмутского летнего исследовательского проекта по искусственному интеллекту 1956 года. Этот семинар стал непрерывной многонедельной академической конференцией, самой первой в области ИИ. Кстати, именно Маккарти, тогда будучи адъюнкт-профессором по математике в Дартмуре, придумал термин «искусственный интеллект», предлагая провести эту встречу. В конференции участвовало порядка десяти человек. Среди них были Аллен Ньюэл и Герберт Саймон, два исследователя, связанных с RAND Corporation и Университетом Карнеги-Меллона, только что закончившие разработку языка IPL.
Ньюэл и Саймон пытались создать систему, способную выдавать доказательства в логике высказываний. Они поняли, что это будет тяжело сделать, оставаясь на уровне собственных инструкций компьютера, поэтому решили создать язык – или, как они его называли, «псевдо-код» – который поможет им естественнее выразить работу их «машины теоретической логики». Их язык, IPL, «язык обработки информации», был больше похож на высокоуровневый диалект ассемблера, чем на язык программирования в современном смысле. Ньюэл и Саймон, возможно, имея в виду Фортран, отметили, что «другие псевдо-коды», находившиеся тогда в разработке, были «заняты» представлением уравнений в стандартной математической записи. Вместо этого их язык концентрировался на представлении высказываний в виде списков символьных выражений. Программы на IPL использовали последовательности макросов на ассемблере для обработки и вычисления выражений в рамках одного или нескольких из этих списков.
Маккарти считал, что будет полезно иметь алгебраические выражения в языке, похожем на Фортран. Поэтому IPL ему не нравился. Но он подумал, что символические списки – неплохой способ моделировать задачи из области ИИ, в особенности те, что включают в себя дедукцию. Это был зародыш желания Маккарти создать язык алгебраической обработки списков, язык, который напоминал бы Фортран, но мог бы и обрабатывать символические списки, как IPL.
Конечно, сегодня Лисп не напоминает Фортран. За последовавшие несколько лет идеи Маккарти по поводу идеального языка обработки списков развились. Его идеи начали меняться в 1957 году, когда он начал писать процедуры для программы на Фортране, играющей в шахматы. Длительное воздействие Фортрана убедило Маккарти, что в его дизайне было несколько неудачных мест, главное из которых – неуклюжий оператор IF. Маккарти изобрёл альтернативу, условное выражение «true», возвращающее подвыражение A, если заданная проверка прошла успешно, и подвыражение B в другом случае, и выполняющее только то подвыражение, которое было возвращено. Летом 1958 года, когда Маккарти работал над программой, способной на дифференцирование, он понял, что его условное выражение «true» сделало написание рекурсивных функций более простым и естественным. Задача с дифференцированием также подвигла Маккарти на написание функции maplist, принимающей в качестве аргумента другую функцию, и применяющей её ко всем элементам списка. Она была полезной для дифференцирования сумм произвольного количества членов.
Такие вещи на Фортране было не выразить, поэтому осенью 1958 Маккарти задал нескольким студентам задачу по реализации Лиспа. Поскольку теперь Маккарти был адъюнкт-профессором в MIT, все студенты учились в MIT. Переведя идеи в рабочий код, Маккарти со студентами внесли изменения, ещё больше упростившие язык. Самое крупное из них заключалось в синтаксисе Лиспа. Маккарти сначала хотел, чтобы в языке использовались т.н. «М-выражения», слой "синтаксического сахара", делавшего синтаксис Лиспа похожим на Фортран. Хотя М-выражения можно перевести в S-выражения – простой список, заключённый в скобки, которыми славен Лисп – S-выражения реально были низкоуровневым представлением, предназначавшимся для компьютера. Единственной проблемой было то, что Маккарти обозначал М-выражения при помощи квадратных скобок, а на перфораторе IBM 026, использовавшемся в MIT, квадратных скобок не было. Поэтому команда Лиспа ограничилась S-выражениями, и использовала их для представления не только списков данных, но и применения функций. Маккарти со студентами сделали ещё несколько упрощений, включая переход на префиксную запись и модель памяти, в которой у языка был только один тип real.
В 1960-м Маккарти опубликовал знаменитую работу по Лиспу «Рекурсивные функции символических выражений и их машинное вычисление» [Recursive Functions of Symbolic Expressions and Their Computation by Machine]. К тому времени язык был сокращён до такой степени, что Маккарти понял, что создал «элегантную математическую систему», а не просто ещё один язык программирования. Позже он писал, что многие упрощения в Лиспе превратили его в «способ описания вычисляемых функций, гораздо более точный, нежели машины Тьюринга или общие рекурсивные определения, используемые в теории рекурсивных функций». В своей работе он представил Лисп, как рабочий язык программирования, и как формализм для изучения поведения рекурсивных функций.
Маккарти объяснял Лисп читателям, выстраивая его из небольшого набора правил. Позже Пол Грэм прошёл по следам Маккарти, используя более простой в чтении язык, в своём эссе "Корни Лиспа". Грэм может объяснить Лисп при помощи лишь семи примитивных операторов, двух различных записей для функций и шести функций высокого уровня, определяемых через примитивные операторы. Способность определить Лисп при помощи такой небольшой последовательности простых правил, безусловно, добавляет ему загадочности. Грэм назвал работу Маккарти попыткой «аксиоматизировать вычисления». Я думаю, что это отличный способ размышлять о привлекательности Лиспа. В других языках явно присутствуют искусственные конструкции, описываемые такими зарезервированными словами, как while, typedef, или public static void, кажется, что описание Лиспа ограничено самой логикой вычислений. Это качество и изначальная связь Лиспа с такой эзотерической областью, как «теория рекурсивных функций», должны объяснять сегодняшний престиж языка.
Теория Б: машина будущего
Через два десятилетия после создания, Лисп превратился, согласно знаменитому "словарю компьютерщиков", в «родной язык» исследований в области ИИ. На ранних этапах Лисп распространялся быстро, вероятно, из-за того, что его систематический синтаксис делал задачу его реализации на новых машинах относительно прямолинейной. Позже исследователи продолжали его использовать из-за того, как хорошо он справлялся с символическими выражениями, что было важно в эпоху, когда большая часть ИИ была символической. Лисп использовали в таких плодовитых ИИ-проектах, как программа понимания естественного языка SHRDLU, система компьютерной алгебры Macsyma, и логической системы ACL2.
К середине 1970-х исследователям ИИ начало не хватать компьютерной мощности. К примеру, у PDP-10 – всеми любимой машины для работы с ИИ – было 18-битное адресное пространство, которого всё чаще не хватало для ИИ-программ на Лиспе. Многие ИИ-программы к тому же должны были быть интерактивными, а создание крупной интерактивной программы, хорошо работающей на системе с разделением времени, было трудной задачей. Решение, которое первым предложил Питер Дойч из MIT, состояло в разработке специального компьютера для Лиспа. Такие машины должны были дать каждому пользователю выделенный процессор, оптимизированный под Лисп. На них также должна была работать среда разработки, написанная на Лиспе для хардкорных Лисп-программистов. Лисп-машины, придуманные в неудобный момент в конце эры мини-компьютеров, но до начала расцвета микрокомпьютерной революции, были высокопроизводительными персональными компьютерами для элиты программистов.
Некоторое время казалось, что Лисп-машины будут волной будущего. Появилось несколько компаний, начавших состязаться за коммерциализацию этой технологии. Наиболее успешной из них стала Symbolics, созданная ветеранами MIT AI Lab. В 1980-х Symbolics выпустила линейку компьютеров из серии 3600, популярных в области ИИ и в индустриях, где требовались вычисления высокой мощности. В линейке 3600 были компьютеры с большими экранами, растровая графика, интерфейс, использовавший мышь, мощные программы для графики и анимации. Это были впечатляющие машины, позволявшие писать впечатляющие программы. К примеру, Боб Кали, работавший в области исследования робототехники, написал мне через твиттер, что ему удалось реализовать и визуализировать алгоритм поиска пути на Symbolics 3650 в 1985. Он рассказал, что растровая графика и ООП (доступное на Лисп-машинах благодаря расширению Flavors) были новинками в 1980-х. Symbolics находилась на переднем крае.
Но в результате компьютеры Symbolics были безумно дорогими. Symbolics 3600 стоил $110 000 в 1983. Большинство людей могло только дивиться мощности Лисп-машин и магии операторов, писавших на Лисп, издалека. Но они дивились. Журнал Byte несколько раз описывал Лисп и Лисп-машины в период с 1979 по конец 1980-х. В августовском номере от 1979 года, посвящённом Лиспу, главные редактор восторгался новыми машинами, разрабатываемыми в MIT, «с горой памяти» и «передовой операционной системой». Он считал их такими многообещающими, что предыдущие два года, в которые появились Apple II, Commodore PET и TRS-80, казались скучными. Пять лет спустя, в 1985, автор в журнале Byte описывал процесс написания программ на Лиспе для «сложных и чрезвычайно мощных Symbolics 3670», и призывал читателей учить Лисп, заявляя, что он был как «языком, необходимым для большинства исследователей ИИ», так и кандидатом на будущий язык общего назначения.
Я спросил Пола Макджонса, много сделавшего для сохранения Лиспа в Музее компьютерной истории в Маунтин-Вью, о том, когда люди впервые начали говорить о Лиспе, как о даре существ из высшего измерения. Он сказал, что этому, безусловно, способствовали свойства самого языка, но ещё и близкая связь Лиспа и мощных приложений в области ИИ в 1960-х и 1970-х. Когда Лисп-машины стало возможным приобрести в 1980-х, с мощностью Лиспа познакомилось ещё несколько человек, находившихся вне таких мест, как MIT или Стэнфорд, и легенда продолжила расти. Сегодня Лисп-машины и Symbolics мало кто помнит, но они помогали поддерживать ауру загадочности Лиспа вплоть до 1980-х.
Теория В: обучение программированию
В 1985 профессоры из MIT, Гарольд Абельсон и Джеральд Сасман, а также жена Сасмана, Джулии, опубликовали учебник «Структура и интерпретация компьютерных программ» [Structure and Interpretation of Computer Programs]. В учебнике читателей обучали программированию на языке Scheme, диалекте Лиспа. Его использовали в MIT для введения в программирование два десятилетия. Мне кажется, что это учебник, SICP, добавил мистицизма Лиспу. SICP взял Лисп и показал, как его можно использовать для иллюстрации глубоких, почти философских концепций искусства программирования. Эти концепции были достаточно общими для того, чтобы использовать любой ЯП, но авторы SICP выбрали Лисп. В итоге репутация Лиспа была дополнена дурной славой этой странной и гениальной книги, интриговавшей многие поколения программистов (и ставшей очень странным мемом). Лисп всегда был «элегантным формализмом Маккарти»; теперь он стал ещё и языком, «обучающим вас скрытым секретам программирования»).
Стоит немного рассказать о том, насколько странная это книга – поскольку мне кажется, что её странность и странность Лисп сегодня слились в одно. Странность начинается с обложки. На ней изображён волшебник или алхимик, приближающийся к столу, и готовый начать какое-то колдовство. В одной руке у него кронциркуль или компас, в другой – глобус с надписями «eval» и «apply». Женщина напротив него показывает на стол; на фоне висит в воздухе греческая буква лямбда, излучающая свет.
Что тут вообще происходит? Почему у стола нога животного? Почему женщина показывает на стол? В чём значимость чернильницы? Должны ли мы понять, что волшебник раскрыл тайные знания вселенной, и что они состоят из цикла eval/apply и лямбда-исчисления? Видимо, так и есть. Только это изображение должно было многое добавить к сегодняшнему восприятию Лиспа.
Но и текст самой книги часто оказывается таким же странным. SICP не похожа на большинство других книг по информатике. Авторы в предисловии поясняют, что книга не просто о программировании на Лисп – она повествует о «трёх фокусах, или явлениях: человеческом разуме, наборе компьютерных программ и компьютере». Позже они описывают, что убеждены в том, что программирование нужно рассматривать не как дисциплину информатики, а как новую запись «процедурной эпистемиологии». Программы – это новый способ структурирования мыслей, которые лишь иногда вводят в компьютер. В первой главе даётся краткий экскурс по Лиспу, но большая часть книги повествует о более абстрактных концепциях. В ней обсуждаются различные парадигмы программирования, природа времени и идентичности в ОО-системах, а в одном месте – то, какие проблемы с синхронизацией могут возникнуть из-за фундаментальных ограничений передачи сообщений, играющих роль скорости света в теории относительности. Это довольно заумные вещи.
И не сказать, что книга плохая. Она чудесная. В ней обсуждаются важные концепции программирования на уровне более высоком, чем во всех других прочитанных мною книгах, концепции, о которых я давно задумывался, но не мог описать. Удивительно, что учебник по введению в программирование так быстро может перейти к описанию фундаментальных недостатков ООП и преимуществах функциональных языков, минимизирующих изменяемое состояние. Удивительно, как это превращается в обсуждение того, как потоковая парадигма, наверно, что-то вроде сегодняшней RxJS, может дать вам лучшее обоих подходов. SICP выдяляет самую суть разработки высокоуровневых программ способом, напоминающим исходную работу Маккарти по Лиспу. Первое, что вам хочется сделать, прочтя эту книгу – заставить прочесть её ваших друзей-программистов; если они её найдут, увидят обложку, и не станут читать, то всё, что у них отложится – это то, что некая загадочная штука по имени eval/apply даёт волшебникам особую власть над столами с ногами животных. Меня бы ещё впечатлила их обувь.
Но, возможно, наиболее важный вклад SICP состоял в подъёме Лиспа с уровня забавной диковинки до педагогической необходимости. Задолго до SICP люди советовали друг другу изучить Лисп, чтобы повысить свой уровень как программиста. Номер журнала Byte от 1979 года тому свидетельство. Тот же редактор, восхищавшийся новыми Лисп-машинами в MIT, объяснил, что стоит учить этот язык, поскольку он «представляет другую точку зрения на задачи». Однако в SICP Лисп был представлен не просто как контраст к другим языкам. Его использовали в качестве вводного языка, намекая, что это лучший язык для изучения базовых понятий программирования. Когда сегодняшние программисты советуют друг другу попробовать Лисп до того, как они умрут, они, вероятно, делают это из-за SICP. Ведь Brainfuck тоже, вероятно, предлагает «другую точку зрения на задачи». Но люди вместо этого изучают Лисп, зная, что уже лет двадцать точка зрения Лиспа была настолько полезной, что студентов в MIT учили Лиспу до всех остальных языков.
Возвращение Лиспа
В год выхода SICP Бьёрн Страуструп опубликовал первое издание книги "Язык программирования C++", принёсшей ООП в массы. Несколько лет спустя рынок Лисп-машин рухнул, и началась зима ИИ. За последовавшие десять с чем-то лет C++ и потом Java стали языками будущего, а Лисп прозябал.
Естественно, невозможно указать, когда точно люди стали снова восхищаться Лиспом. Возможно, это произошло после того, как Пол Грэм, сооснователь Y-Combinator и создатель Hacker News, опубликовал несколько влиятельных эссе, где описывал Лисп, как лучший язык для стартапов. В эссе "Опережая средних" Грэхем утверждал, что макросы Лиспа сделали язык сильнее других языков. Он заявил, что использование Лиспа в своём стартапе Viaweb помогло ему разработать определённые вещи быстрее, чем это смогли сделать конкуренты. Некоторых программистов это убедило. Но большинство не переключилось на Лисп.
Вместо этого всё больше особенностей Лиспа стало попадать во всеми любимые языки. В Python появилась генерация списков. В C# — Linq. В Ruby… ну, Ruby – это и есть Лисп. Как отмечал Грэм ещё в 2001, «язык по умолчанию, встроенный во многие появившиеся позже популярные языки, постепенно развивался в сторону Лиспа». И хотя другие языки постепенно приближаются к Лиспу, сам Лисп как-то поддерживает свою особую репутацию загадочного языка, который мало кто понимает, но все должны изучить. В 1980, в год 20-летия Лиспа, Маккарти писал, что Лисп выжил так долго, поскольку занял «примерный локальный оптимум своего рода в пространстве ЯП». Но это недооценивает реальное влияние Лиспа. Он выживает уже пятьдесят лет потому, что программисты десятилетие за десятилетием нехотя признавали, что это лучший инструмент для своей задачи. Он выжил, даже несмотря на то, что большинство программистов его не используют. Благодаря его происхождению и использованию в исследованиях ИИ, и, возможно, также наследию SICP, Лисп продолжает восхищать людей. И пока мы не сможем представить Бога, сотворившего мир при помощи какого-то более нового языка, Лисп никуда не денется.
Автор: SLY_G