Язык богов: за что хакеры любят Lisp и как с его помощью достичь просветления
Вряд ли найдётся язык программирования, который хвалили бы чаще, чем Lisp. Разбираемся, почему же никто не спешит его учить.
Иллюстрация: Polina Vari для Skillbox Media
Отец ООП Алан Кэй называл его «величайшим языком программирования из когда-либо созданных», а информатик и лауреат Пулитцеровской премии Дуглас Хофштадтер — «одним из наиболее важных и удивительных компьютерных языков». Сооснователь Open Source Initiative Эрик Реймонд говорил, что его изучение подарит глубокое просветление и «сделает вас лучшим программистом».
Всё это они говорили не о Java, C++ и даже не о C. Любимцем первых разработчиков и тру-хакеров был и остаётся Lisp.
Язык искусственного интеллекта
Математик Джон Маккарти создал Lisp в конце 1950-х. Считается, что он же придумал термин «искусственный интеллект» (далее ИИ) и заложил основы функционального программирования. Тогда Маккарти участвовал в исследовательском проекте и, чтобы реализовать совершенно новые на тот момент концепции, разработал язык программирования. В 1960 году он опубликовал статью «Рекурсивные функции символических выражений и их вычисление машиной» (Recursive Functions of Symbolic Expressions and Their Computation by Machine), в которой и представил Lisp научному сообществу.
В Lisp всё завязано на списках. Каждый оператор — это список элементов, а каждый элемент может быть также списком или «атомом». Атом — это минимальная единица данных, число или символ. Пионеры Lisp считали, что язык отражает устройство человеческого мозга и на нём можно закодировать любой интеллектуальный процесс.
Пол Грэм, сооснователь Y Combinator, создатель портала Hacker News (который написан на Arc — диалекте Lisp) и евангелист Lisp, сравнил Маккарти с Евклидом и назвал язык «научным открытием»:
«В 1960 году Джон Маккарти опубликовал замечательную статью, в которой сделал для программирования то же, что Евклид для геометрии. <…> Lisp — это не столько изобретение, сколько научное открытие».
Учитывая, что задачи, связанные с ИИ, всегда были ресурсоёмкими, а мощности компьютеров в 1980-е сильно уступали нынешним, разработчики Lisp старались выжать из языка максимум производительности. Так появились изощрённые компиляторы, которые были ничуть не хуже компиляторов С. Постепенно вокруг Lisp образовался мистический ореол, и на то было две причины.
Причина первая. К середине 1970-х исследователям ИИ стало не хватать компьютерных мощностей, и инженер Питер Дойч из MIT предложил разработать компьютер специально для программ на Lisp. В 1980-е компания Symbolics выпустила серию Lisp-машин, архитектура которых была оптимизирована под этот язык. Так Lisp стал ассоциироваться с мощными программами для ИИ.
В те же годы производители Lisp-машин и лаборатории, изучавшие ИИ, предлагали свои версии языка. Так у Lisp появилось множество диалектов — и в сообществе наметился раскол. Чтобы его избежать, в 1981 году группа хакеров начала работу над единым стандартом языка — Common Lisp. Он вобрал в себя лучшие фичи всех существовавших диалектов.
Причина вторая. В 1985 году профессора MIT Харольд Абельсон и Джеральд Сассман опубликовали учебник «Структура и интерпретация компьютерных программ» — среди хакеров он больше известен как Wizard Book («Книга волшебника»). По нему студентов MIT более двадцати лет обучали программированию на Scheme, диалекте Lisp. Именно благодаря «Книге волшебника» Lisp стали воспринимать как язык, через который можно познать глубокие философские концепции программирования.
Популярность Lisp упала в конце 1980-х. Тогда исследования в области ИИ отошли на второй план, а более дешёвые и мощные компьютеры наводнили рынок и вытеснили Lisp-машины.
Вторая волна популярности языка началась после выхода эссе Пола Грэма, в котором он назвал Lisp «лучшим языком для стартапов». В 1995 году Пол с другом основал компанию Viaweb и выпустил одноимённый конструктор онлайн-магазинов, написанный на легендарном языке.
«Мы подумали, что если будем писать на Lisp, то сможем расширять функциональность продукта быстрее конкурентов и добавлять фичи, которые им недоступны. А так как Lisp — очень высокоуровневый язык, то мы обойдёмся маленькой командой разработчиков и хорошо сэкономим».
Пол Грэм,
сооснователь Y Combinator, создатель Hacker News
Кого-то слова Грэма убедили, но таких энтузиастов были единицы. Согласно статистике GitHub, Emacs Lisp занимает 25-е, а Common Lisp — 49-е место по популярности среди пользователей сайта. Тем не менее лучшие его черты появились в других языках: например, Python взял генератор списков, а C# получил язык интегрированных запросов LINQ.
Lisp — второй после Fortran из «выживших» старейших языков программирования. В индексе TIOBE за декабрь 2021 года Lisp занимает 31-е место, опережая Lua, Scala и TypeScript.
Почему хакеры полюбили Lisp
Lisp довольно быстро стал любимым языком хакеров. В первой версии «Файла жаргона», легендарного словаря хакерского сленга, даже не было отдельной статьи о Lisp — ведь каждый хакер программировал на нём. Потом она всё же появилась:
«LISP: (LISt Processing language, по другой версии Lots of Irritating Superfluous Parentheses — „множество раздражающих ненужных кавычек“) — родной язык искусственного интеллекта, основанный на списках переменной длины, деревьях, интерпретации кода как данных и наоборот. Разработан Джоном Маккарти в MIT в конце 1950-х. Старше любого из ныне используемых высокоуровневых языков, кроме Fortran, но современные варианты Lisp сильно отличаются от оригинального. Основной высокоуровневый язык программирования у хакеров до начала 1980-х».
Сооснователь Open Source Initiative Эрик Реймонд считает, что даже сегодня Lisp выглядит лучше, чем большинство языков программирования:
«В те времена (в 1970-е. — Ред.) Lisp был мощнее и гибче любого языка. На самом деле даже сегодня его дизайн лучше, чем у большинства молодых конкурентов. Lisp подарил хакерам творческую и интеллектуальную свободу и поэтому остаётся любимым языком хакеров».
По словам Пола Грэма, Lisp на момент появления содержал ряд новых идей:
- Условные конструкции. Сегодня даже новички знают про if/else. Но придумал их Маккарти в Lisp. Благодаря ему они попали в Algol, а оттуда разбежались по другим языкам.
- Рекурсия. Как математическая концепция рекурсия существовала задолго до Lisp, но он стал первым языком, который её поддерживал.
- Новая концепция переменных. В Lisp все переменные — указатели. Когда разработчик присваивает одной переменной другую, копируется указатель, а не значение копируемой переменной.
- Сборка мусора. Именно в Lisp впервые появился сборщик мусора — один из основных элементов Java, C#, Python и других языков с автоматическим управлением памятью. Благодаря ему программисты манипулируют списками и сложными структурами данных, не беспокоясь о висячих ссылках и утечках памяти.
- Язык всегда доступен целиком. Нет разделения на время чтения, компиляции и исполнения кода. Можно компилировать и запускать код во время чтения, читать или запускать во время компиляции или читать и компилировать во время выполнения.
Но главная сила Lisp — макросы:
«Только лучшие и самые умные программисты следуют пути Lisp, и только умнейшие из лисперов становятся мастерами макросов!.. Макросы — это величайшее преимущество Lisp и любого языка программирования».
Дуг Хойт,
программист
Макрос можно использовать, чтобы превратить Lisp в другие языки программирования и обратно. Человек, который научится писать макросы, обнаружит, что все другие языки — лишь оболочки Lisp.
Как правило, у любого языка программирования есть стандартная библиотека: модули, классы, объекты, константы, глобальные переменные, функции и так далее. Их можно вызвать из любой программы, написанной на этом языке. Если в библиотеке нет нужной функции, разработчик пишет её сам или добавляет новый класс. А в Lisp с помощью макросов расширяют синтаксис.
Пол Грэм назвал макросы программами, которые пишут программы. А Питер Сибел считает Common Lisp «программируемым языком программирования» — это суть и главное преимущество языка. Когда вы пишете на Common Lisp, то не думаете: «Хорошо бы в нём была такая фича», а просто добавляете её. Вы не тратите время, пытаясь выразить идею в тесных рамках синтаксиса.
«Lisp — это прародитель всех языков. Его можно превратить в любой язык: от интерпретируемого скриптового до эффективного и статично компилируемого. Common Lisp настолько гибок, что на любой стадии разработки можно корректировать и менять код как угодно, но в итоге всё равно получается рабочий, чистый и эффективный дизайн. Такое невозможно ни в одном другом языке».
Паскаль Констанца,
программист на Common Lisp
Слава Ахмечет, основатель RethinkDB, программист и блогер, вообще рассказал, что испытал то самое просветление, о котором говорит Эрик Реймонд:
«Просветление пришло. Сначала я ничего не понимал, а потом мгновенно достиг нирваны. Всё прояснилось. Я много раз слышал слова Эрика Реймонда: „Lisp стоит изучать ради глубокого просветления…“, но не понимал их. И наконец эта фраза обрела смысл! <…> Я достиг почти божественного состояния ума, мои взгляды на информатику перевернулись. В ту же секунду я стал членом культа Lisp».
Польза Lisp очевидна не всем
Окей, если Lisp такой крутой, почему на нём так мало пишут? Дело в том, что польза от изучения языка неочевидна для начинающих разработчиков. Если вы хотите заниматься веб-разработкой, то учите JavaScript, а чтобы писать драйвера, осваиваете С/С++. Но в случае с Common Lisp не получится сразу объяснить, зачем он нужен:
«Очевидной выгоды от изучения Common Lisp, как в случае с C, Java и C++, нет. Основная польза для программиста — в опыте, который он даёт».
Пол Грэм,
сооснователь Y Combinator, создатель Hacker News
Мэтью Баттерик, американский типограф, юрист, писатель и программист, считает, что у Lisp множество преимуществ, но его поклонники не могут изложить их доступно и лаконично:
«Если Lisp и его диалекты настолько хороши, то должно быть краткое описание их преимуществ. Нужно показать всю мощь Lisp за один час, а не за сто. Если фанаты Lisp не делают этого, то неудивительно, что Lisp со своими диалектами занимает нижние строчки рейтингов».
Сам Баттерик приводит наглядные примеры. Например, «Hello, World!» в Racket, одном из популярных диалектов Lisp, так и пишется: «Hello, World!». Даже непрограммист увидит разницу между одной фразой и этим:
В большинстве языков программирования есть выражения, которые вычисляются и производят значение, и инструкции — то есть команды и действия. Например, в Python x = 42 — это инструкция присваивания, а x + 42 — выражение. Следующий код в Python не будет иметь никакого смысла:
А в Lisp такой код даст вполне конкретный результат. Ведь условный оператор if — это тоже выражение. Программист может использовать его в вычислениях как угодно — нужно только немного «расширить сознание».
«В Lisp вы не страдаете от синтаксических ограничений, которых полно в других языках. Это упрощает вашу работу и расширяет возможности: можно комбинировать части языка самыми необычными способами».
Мэтью Баттерик,
американский типограф, юрист, писатель и программист
«Если наибольший кайф программисту доставляет код, который просто и ясно выражает намерения, то программирование на Common Lisp, скорее всего, — самое кайфовое занятие за компьютером. На Lisp можно сделать куда больше вещей — и намного быстрее, чем на любом другом языке.
Пол Грэм,
сооснователь Y Combinator, создатель Hacker News
Что написано на Lisp
В 1996 году студия Naughty Dog выпустила игру Crash Bandicoot, которая взорвала игровой рынок. Все были в восторге от ярких визуальных решений и анимации. Crash Bandicoot стала одной из самых популярных игр на Sony PlayStation. Затем Naughty Dog выпустила Jak and Daxter: the Precursor Legacy, которая получила восторженные отзывы критиков и рейтинг 90 из 100 на Metacritic.
С помощью Lisp и Allegro CL разработчики довольно быстро создали инструменты для дизайна плавных движений и насыщенных текстур. Они спроектировали более 500 разных объектов с уникальным геймплеем и визуальными характеристиками:
«Lisp стал лучшим решением для нас. Мы делали новаторскую игру, поэтому пришлось возиться со сложным поведением персонажей и действиями в реальном времени. Языки вроде С слишком неуклюжи для такого проекта, а Lisp идеален».
Энди Гэвин,
сооснователь и программист Naughty Dog
Марк Тарвер, программист на Lisp с почти 30-летним стажем, так объяснил разницу между С и Lisp:
«Писать на C — всё равно что с пинцетом и клеем собирать мозаику из чечевицы. А Lisp — это пневматическое оружие, сильное и точное. Он открывает целые миры, недоступные другим разработчикам».
Вот список проектов, в которых используются диалекты Lisp:
- GNU Emacs — написан Ричардом Столлманом на Emacs Lisp. Некоторые фанаты даже в шутку называют его операционной системой.
- Grammarly — онлайн-сервис для проверки качества англоязычных текстов.
- Piano — пакет программ на Common Lisp, который используют Boeing и Airbus.
- ПО Лондонского метрополитена — оно разработано на Common Lisp.
- AutoCAD — в системе используется внутренний язык AutoLISP.
- Apache Storm — система обработки больших данных в реальном времени, написана на Clojure (диалекте Lisp) и Java.
Перспективы Lisp
Несмотря на благородную седину, Lisp жив и даже продолжает развиваться в диалектах. По сути, это уже давно не просто язык программирования, а целое семейство языков с оригинальным подходом к разработке программного обеспечения. Lisp насчитывает более 20 диалектов, а наиболее известные из них до сих используются в коммерческой и научной разработке:
- Common Lisp — основной диалект, вышедший в 1984 году и принятый в качестве стандарта ANSI в 1995 году. Поддерживает функциональное программирование, макросы, замыкания и прочие фичи, накопленные с 1959 года другими диалектами.
- Scheme — один из старейших диалектов, созданный в 1970-х исследователями MIT. Особенность языка — гибкий и минималистичный дизайн. В Scheme не предусмотрено средств ООП, но разработчик может реализовать их и другие инструменты самостоятельно.
- Clojure — компилируемый язык, созданный в 2007 году и работающий на платформах JVM и CLR. Поддерживает параллельное программирование, макросы и функции как объекты первого класса. Легко интегрируется с Java.
- Racket — потомок Sheme, увидевший свет в 1994 году. Изначально создавался как учебный язык, но со временем вырос в среду языково-ориентированного программирования — то есть стал инструментом для создания языков.
- Emacs Lisp — диалект, на котором почти целиком написан GNU Emacs. Создан автором проекта GNU и основателем Free Software Foundation Ричардом Столлманом и программистом Гаем Стилом в 1985 году.
- Arc — один из последних диалектов Lisp, разработанный Полом Грэмом в 2008 году. На Arc написан новостной портал Hacker News и некоторые другие части Y Combinator.
Согласно индексу TIOBE, самым распространённым диалектом остаётся Common Lisp (31-е место), а за ним во второй полусотне тянутся Clojure, Racket и Scheme. Даже с учётом всех диалектов Lisp всё ещё остаётся языком «андеграунда». Тем не менее Кент Питман, один из ветеранов Lisp и технический контрибьютор X3J13, считает, что у языка есть все шансы вернуть былую популярность:
«Главная проблема Lisp в том, что он слишком рано достиг коммерческого успеха. В середине 1980-х мир ещё не столкнулся с вычислительными проблемами, которые мог бы успешно решать Lisp. Это были времена MacWrite, MacPaint и Lotus 1-2-3, и было без разницы, что использовать — Lisp или C. Но мир изменился, и проблемы стали гораздо сложнее. Думаю, сегодня Lisp может предложить миру намного больше, чем раньше».