Язык, который придумали для ИИ в 1958-м. Clojure.. Clojure. common lisp.. Clojure. common lisp. Lisp.. Clojure. common lisp. Lisp. джон маккарти.. Clojure. common lisp. Lisp. джон маккарти. искусственный интеллект.. Clojure. common lisp. Lisp. джон маккарти. искусственный интеллект. История IT.. Clojure. common lisp. Lisp. джон маккарти. искусственный интеллект. История IT. история программирования.. Clojure. common lisp. Lisp. джон маккарти. искусственный интеллект. История IT. история программирования. Программирование.. Clojure. common lisp. Lisp. джон маккарти. искусственный интеллект. История IT. история программирования. Программирование. Функциональное программирование.

Язык, который придумали для ИИ в 1958-м - 1

Недавно попалось на глаза одно очень интересное видео с динамическими шкалами по популярности разных языков программирования по годам (вроде как, начиная с 1980х). Удивительно, сколько всего и как много придумало человечество. И как быстро меняются тренды, а еще – сколько всего уникального уходит в тень истории. Вот был такой Лисп. Принято считать, что Лисп – это что-то из учебников по истории программирования. Где-то между перфокартами и первыми компиляторами. Условный артефакт. Язык, которым пользовались бородатые профессора, пока не пришел Python и не навел порядок.

Только вот Python тоже унаследовал из Лиспа некоторую часть. Но не все. Самое радикальное так и не забрал.

Откуда взялся Лисп – и почему именно для ИИ

Джон Маккарти был математиком, который всерьез решил, что машины можно научить думать. Не в переносном смысле – технически. И примерно с середины 1950-х он последовательно это доказывал.

Сам термин “artificial intelligence” появился в заявке на Дартмутский летний семинар – в 1955 году. А уже летом 1956-го встреча в Дартмуте фактически закрепила его как название новой научной области. Тогда Маккарти был одним из организаторов. Конечно же, не как маркетинговый слоган – как название дисциплины, под которую он хотел получить финансирование.

Осенью 1958-го Маккарти пришел в MIT. Вместе с Марвином Мински они запустили AI Project – то, что в хронологии MIT обычно датируется 1959-м. MIT AI Lab как отдельная структура выделилась позже, в 1969-м. И практически сразу Маккарти столкнулся с проблемой, которую современный разработчик понял бы мгновенно – нет подходящего инструмента.

FORTRAN создавался для численных расчетов (буквально, “Formula Translation”) и отлично справлялся с вычислениями по формулам. Но задачи искусственного интеллекта требовали работы с символьной информацией. Например – разбора предложений, доказательства теорем, оперирования логическими правилами вида “если А, то Б”. Теоретически любые структуры можно закодировать числами, но на практике описывать сложные вложенные правила в рамках строго числовой абстракции FORTRAN было крайне неудобно.

Для решения этой проблемы инженеры IBM Герберт Гелернтер и Карл Герберих при участии Маккарти разработали FLPL (Fortran List Processing Language) – набор подпрограмм для работы со списками внутри FORTRAN. FLPL помог запустить один из первых ИИ-проектов (геометрический доказыватель теорем), но выявил фундаментальные ограничения исходного языка. В FORTRAN того времени не было ни рекурсии, которая необходима для обработки вложенных списков, ни удобных условных выражений.

Поняв ограничения этого подхода, Маккарти начал проектировать новый язык с нуля. В 1960 году вышла его статья “Рекурсивные функции символьных выражений и их вычисление на машине”, ставшая одной из фундаментальных работ в истории компьютерных наук.

Что Маккарти придумал – и чего он сам не понял

Здесь есть одна примечательная деталь.

Маккарти взял из лямбда-исчисления Алонзо Черча нотацию LAMBDA для обозначения функций. Это стало основой синтаксиса Лиспа. Но сам Маккарти позже признавался, что в момент создания языка не очень-то разбирался в лямбда-исчислении – взял нотацию, потому что она казалась удобной и пошел дальше. Позже Дэвид Парк заметил, что рекурсивную LABEL-нотацию можно выразить через конструкцию на LAMBDA, аналогичную Y-оператору Черча. Но сама LAMBDA в Лиспе Y-комбинатором не является.

Это, кстати, нормальная история для фундаментальных вещей. Автор интуитивно нащупывает правильное решение, а теоретики потом объясняют, почему оно работает.

Главное, что получилось у Маккарти – это идея eval (сокращение от evaluate – “вычислить”). Функция, которая берет программу на Лиспе и выполняет ее. Сегодня это звучит банально. В 1958-м это была концептуальная бомба – программа стала данными, которые можно передавать, трансформировать и запускать.

Человек, который запустил то, что не должно было работать

Маккарти написал eval как математическую нотацию. Он, судя по всему, не планировал реализовывать ее на реальной машине – по крайней мере, не сразу.

Стив Расселл, молодой программист из его группы, прочитал статью и сказал, что может закодировать eval для IBM 704. Маккарти ответил примерно следующее: “Ты путаешь теорию с практикой. Это нотация для чтения, а не для вычислений.”

Расселл все равно это сделал. Руками, в машинном коде IBM 704.

Так в 1960-м появился первый интерпретатор Лиспа. Вот просто потому что один человек решил проверить, работает ли теория.

Работала.

Что Лисп придумал первым – и что потом переизобрели все остальные

Итак.

Сборка мусора. Garbage collection – изобретение Лиспа, буквально. Маккарти разработал алгоритм mark-and-sweep (пометка и очистка), чтобы автоматически освобождать память от недостижимых списков. До этого программисты управляли памятью вручную. Java, Python, Go – все взяли эту идею оттуда.

Код как данные. В Лиспе программа и данные записываются одинаково – вложенными списками, S-выражениями. Функцию можно передать как аргумент, вернуть из другой функции, сгенерировать прямо во время выполнения. Это называется гомоиконичностью и именно на этом держатся макросы Лиспа – механизм, который позволяет писать код, генерирующий код.

Рекурсия как основа вычислений. FORTRAN и ранний Кобол работали с итерациями и GOTO. Маккарти показал, что рекурсивные функции – это самодостаточная вычислительная модель.

Условные выражения. if-then-else в том виде, в каком это существует в любом языке – тоже Лисп. Звучит странно, но до 1958-го условные переходы реализовывались как низкоуровневые инструкции, а не как выражения, возвращающие значение.

REPL. Интерактивный read-eval-print-цикл вырос из ранней Лисп-культуры – именно там сложилась привычка работать с живой средой, где пишешь строку и сразу получаешь результат. Сам термин REPL закрепился позже, в документации 1960-х. Jupyter Notebook, Python shell, Node.js repl – все это наследники той же идеи.

Как Лисп стал промышленным стандартом – и что пошло не так

К началу 1960-х Лисп – основной язык ИИ-исследований в MIT, Стэнфорде, Карнеги-Меллоне. К 1980-м на нем работают крупные прикладные системы.

Проблема обнаружилась не в языке. В железе.

Стандартные машины того времени гоняли Лисп медленно – сборка мусора, динамическая типизация, работа со списками требовали ресурсов, которых не хватало. Решение нашли радикальное. Строить специализированные компьютеры под Лисп.

Символы в памяти размечались тегами на уровне архитектуры. Сборка мусора делалась аппаратно. Компании Symbolics и Lisp Machines Inc. (обе – спиноффы MIT AI Lab) выпускали такие машины с конца 1970-х. Texas Instruments тоже вошла в этот рынок.

Цена вопроса – от 150 000 за рабочую станцию. Покупали лаборатории, крупные корпорации, военные.

Во второй половине 1980-х Unix-станции от Sun и других производителей подорвали рынок специализированного железа: стали дешевле и достаточно быстрыми, чтобы использовать Лисп без отдельного процессора. Специализированное железо потеряло экономический смысл.

Symbolics, кстати, пережила это особенно болезненно. Компания подала на банкротство в 1993-м и фактически ушла с рынка в 1990-х. Зато symbolics.com остался историческим артефактом по другой причине – это первый зарегистрированный домен в зоне .com (аж 15 марта 1985 года).

Почему ИИ ушел на Python 

В 1980-х символьный ИИ еще переживал бум – на Лиспе и смежных системах строили экспертные системы. Но после “Зимы искусственного интеллекта” конца 1980-х фокус постепенно сместился к статистическому машинному обучению, а в 2010-х окончательно – к глубоким нейросетям. Лисп оказался в очень неудобном положении.

Увы, новые задачи требовали другого. Перемножать матрицы миллиарды раз – это чуть-чуть не про символы и списки. Это про BLAS, CUDA, числа с плавающей точкой в плотных массивах. Python здесь работает как обертка над C++ и CUDA, и делает это хорошо.

Тут, кстати, важный момент. Собственно, Python, с чего мы и начинали эту историю, унаследовал у Лисп – автоматическую память, функции как значения, интерактивную работу, динамические структуры данных. Но самое радикальное, такого как S-выражения или гомоиконичность – Python не взял. Это другая парадигма, и победила та, под которую оказалось больше денег и вычислительных ресурсов.

Но символьное мышление никуда не делось. Современные агентные системы – это в значительной мере управление символами, правилами, контекстом. LLM генерирует код и вызывает инструменты. Это структурно ближе к тому, что делал Лисп, чем к тому, что делает матричное умножение.

Что живет сегодня

Common Lisp, Scheme и Clojure – три основных живых диалекта.

Common Lisp стандартизирован в 1994-м и с тех пор почти не менялся. Это или минус, или плюс – зависит от задачи. Код, написанный тридцать лет назад, работает сегодня без изменений. Немного языков могут этим похвастаться.

Scheme – академический диалект, намеренно минималистичный. Навсегда связан со знаменитым учебником SICP – “Structure and Interpretation of Computer Programs”, вышедшим в MIT в 1984-м. В самом MIT этот курс давно уже не является основным вводным, но учебник до сих пор читают как классику – и не только в университетах.

Clojure появился в 2007-м и работает на JVM. Из всех диалектов – самый близкий к промышленному применению. Команды на Clojure встречаются в финтехе и в backend-разработке, где важна иммутабельность данных и конкурентность.

Ни один из них не входит в топ-10 по числу репозиториев на GitHub. Это понятно. Но разработчики, которые их знают, обычно говорят об этом как о сдвиге в способе думать о программировании – не как о добавлении еще одного инструмента в набор.

И еще момент. 

Пока это не массовый тренд, а исследовательская гипотеза. Но есть идея в том, что агентные системы, те, которые планируют, рефлексируют и вызывают инструменты – снова делают привлекательными вещи, которые Лисп умел давно. Живое окружение, код как данные, интроспекцию и изменение программы прямо во время выполнения. LLM подключают к живому REPL, агент пишет код и тут же запускает его в той же среде.

Есть конкретные исследовательские работы на эту тему. Хотя и до промышленного масштаба пока далеко, само собой.

Но вот идея, что архитектура шестидесятилетней давности снова оказывается уместной – это, согласитесь, занятно. 

Автор: ArthurEx

Источник