- BrainTools - https://www.braintools.ru -

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

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

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

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

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

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

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

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

FORTRAN создавался для численных расчетов (буквально, “Formula Translation”) и отлично справлялся с вычислениями по формулам. Но задачи искусственного интеллекта [1] требовали работы с символьной информацией. Например – разбора предложений, доказательства теорем, оперирования логическими правилами вида “если А, то Б”. Теоретически любые структуры можно закодировать числами, но на практике описывать сложные вложенные правила в рамках строго числовой абстракции 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 (пометка и очистка), чтобы автоматически освобождать память [2] от недостижимых списков. До этого программисты управляли памятью вручную. 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 [3] остался историческим артефактом по другой причине – это первый зарегистрированный домен в зоне .com (аж 15 марта 1985 года).

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

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

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

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

Но символьное мышление [5] никуда не делось. Современные агентные системы – это в значительной мере управление символами, правилами, контекстом. 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

Источник [6]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/31664

URLs in this post:

[1] интеллекта: http://www.braintools.ru/article/7605

[2] память: http://www.braintools.ru/article/4140

[3] symbolics.com: http://symbolics.com

[4] обучению: http://www.braintools.ru/article/5125

[5] мышление: http://www.braintools.ru/thinking

[6] Источник: https://habr.com/ru/articles/1046996/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1046996

www.BrainTools.ru

Rambler's Top100