Сообщение на тему язык программирования лисп
Обновлено: 07.07.2024
Язык Лисп был предложен Дж. Маккарти в работе в 1960 году и ориентирован на разработку программ для решения задач не численного характера. Английское название этого языка – LISP является аббревиатурой выражения LISt Processing (обработка списков) и хорошо подчеркивает основную область его применения. Понятие “список” оказалось очень емким. В виде списков удобно представлять алгебраические выражения, графы, элементы конечных групп, множества, правила вывода и многие другие сложные объекты. Списки являются наиболее гибкой формой представления информации в памяти компьютеров. Неудивительно поэтому, что удобный язык, специально предназначенный для обработки списков, быстро завоевал популярность.
После появления Лиспа различными авторами был предложен целый ряд других алгоритмических языков ориентированных на решение задач в области искусственного интеллекта. Однако это не помешало Лиспу остаться наиболее популярным языком для решения таких задач. На протяжении почти сорокалетней истории его существования появился ряд диалектов этого языка: Common LISP, Mac LISP, Inter LISP, Standard LISP и др. Различия между ними не носят принципиального характера и в основном сводятся к несколько отличающемуся набору встроенных функций и некоторой разнице в форме записи программ. Поэтому программист, научившийся работать на одном из них, без труда сможет освоить и любой другой.
Большим достоинством Лиспа является его функциональная направленность, т. е. программирование ведется с помощью функций. Причем функция понимается как правило, сопоставляющее элементам некоторого класса соответствующие элементы другого класса. Сам процесс сопоставления не оказывает никакого влияния на работу программы, важен только его результат – значение функции. Это позволяет относительно легко писать и отлаживать большие программные комплексы. Ясность программ, четкое разграничение их функций, отсутствие каверзных побочных эффектов при их выполнении является обязательными требованиями к программированию таких логически сложных задач, каковыми являются задачи искусственного интеллекта. Дисциплина в программировании становится особенно важной, когда над программой работает не один человек, а целая группа программистов.
Язык программирования Лисп предназначен в первую очередь для обработки символьной информации. Поэтому естественно, что в мире Лиспа числа играют далеко не главную роль. Основные типы данных в Лиспе называются “атом” и “точечная пара”.
Когда программисты обсуждают преимущества тех или других языков программирования, они часто рассуждают о них в прозаических терминах, как об инструментах в наборе различных приспособлений – один больше подходит для системного программирования, другой – для склеивания других программ в целях решения текущей задачи. Так и должно быть. У языков разные сильные стороны, и заявлять, что один язык лучше других языков, не указывая конкретных примеров, — значит, лишь вызывать непродуктивные и резкие споры.
Ведь Бог писал на Лиспе
Когда заполнил листья зелёным.
Фрактальные цветки и рекурсивные корни:
Самый красивый хак из виденных мною.
А когда я изучаю снежинки,
И не нахожу двух одинаковых,
Я знаю, что Бог любит язык
Со своим собственным четырёхбуквенным названием.
Как Лисп дошёл до жизни такой?
Обложка журнала Byte, август 1979
Теория А: аксиоматический язык
Маккарти считал, что будет полезно иметь алгебраические выражения в языке, похожем на Фортран. Поэтому IPL ему не нравился. Но он подумал, что символические списки – неплохой способ моделировать задачи из области ИИ, в особенности те, что включают в себя дедукцию. Это был зародыш желания Маккарти создать язык алгебраической обработки списков, язык, который напоминал бы Фортран, но мог бы и обрабатывать символические списки, как IPL.
Теория Б: машина будущего
Некоторое время казалось, что Лисп-машины будут волной будущего. Появилось несколько компаний, начавших состязаться за коммерциализацию этой технологии. Наиболее успешной из них стала Symbolics, созданная ветеранами MIT AI Lab. В 1980-х Symbolics выпустила линейку компьютеров из серии 3600, популярных в области ИИ и в индустриях, где требовались вычисления высокой мощности. В линейке 3600 были компьютеры с большими экранами, растровая графика, интерфейс, использовавший мышь, мощные программы для графики и анимации. Это были впечатляющие машины, позволявшие писать впечатляющие программы. К примеру, Боб Кали, работавший в области исследования робототехники, написал мне через твиттер, что ему удалось реализовать и визуализировать алгоритм поиска пути на Symbolics 3650 в 1985. Он рассказал, что растровая графика и ООП (доступное на Лисп-машинах благодаря расширению Flavors) были новинками в 1980-х. Symbolics находилась на переднем крае.
Я спросил Пола Макджонса, много сделавшего для сохранения Лиспа в Музее компьютерной истории в Маунтин-Вью, о том, когда люди впервые начали говорить о Лиспе, как о даре существ из высшего измерения. Он сказал, что этому, безусловно, способствовали свойства самого языка, но ещё и близкая связь Лиспа и мощных приложений в области ИИ в 1960-х и 1970-х. Когда Лисп-машины стало возможным приобрести в 1980-х, с мощностью Лиспа познакомилось ещё несколько человек, находившихся вне таких мест, как MIT или Стэнфорд, и легенда продолжила расти. Сегодня Лисп-машины и Symbolics мало кто помнит, но они помогали поддерживать ауру загадочности Лиспа вплоть до 1980-х.
Теория В: обучение программированию
Что тут вообще происходит? Почему у стола нога животного? Почему женщина показывает на стол? В чём значимость чернильницы? Должны ли мы понять, что волшебник раскрыл тайные знания вселенной, и что они состоят из цикла eval/apply и лямбда-исчисления? Видимо, так и есть. Только это изображение должно было многое добавить к сегодняшнему восприятию Лиспа.
И не сказать, что книга плохая. Она чудесная. В ней обсуждаются важные концепции программирования на уровне более высоком, чем во всех других прочитанных мною книгах, концепции, о которых я давно задумывался, но не мог описать. Удивительно, что учебник по введению в программирование так быстро может перейти к описанию фундаментальных недостатков ООП и преимуществах функциональных языков, минимизирующих изменяемое состояние. Удивительно, как это превращается в обсуждение того, как потоковая парадигма, наверно, что-то вроде сегодняшней RxJS, может дать вам лучшее обоих подходов. SICP выделяет самую суть разработки высокоуровневых программ способом, напоминающим исходную работу Маккарти по Лиспу. Первое, что вам хочется сделать, прочтя эту книгу – заставить прочесть её ваших друзей-программистов; если они её найдут, увидят обложку, и не станут читать, то всё, что у них отложится – это то, что некая загадочная штука по имени eval/apply даёт волшебникам особую власть над столами с ногами животных. Меня бы ещё впечатлила их обувь.
Возвращение Лиспа
В год выхода SICP Бьёрн Страуструп опубликовал первое издание книги "Язык программирования C++", принёсшей ООП в массы. Несколько лет спустя рынок Лисп-машин рухнул, и началась зима ИИ. За последовавшие десять с чем-то лет C++ и потом Java стали языками будущего, а Лисп прозябал.
Естественно, невозможно указать, когда точно люди стали снова восхищаться Лиспом. Возможно, это произошло после того, как Пол Грэм, сооснователь Y-Combinator и создатель Hacker News, опубликовал несколько влиятельных эссе, где описывал Лисп, как лучший язык для стартапов. В эссе "Опережая средних" Грэхем утверждал, что макросы Лиспа сделали язык сильнее других языков. Он заявил, что использование Лиспа в своём стартапе Viaweb помогло ему разработать определённые вещи быстрее, чем это смогли сделать конкуренты. Некоторых программистов это убедило. Но большинство не переключилось на Лисп.
Lisp является аббревиатурой для LISt Processing Language — основным списком в структуре языка. Эти семейные языки позволяют специалистам записывать программы, которые работают быстрее, чем на других языках. Язык программирования Лисп и его диалекты такие как Common, Scheme и Clojure, способствуют созданию мощного и гибкого программного обеспечения, необходимого для сложных и быстро развивающихся областей науки и техники.
Существует несколько важных ключевых особенностей, которые отличают языки этого семейства от других языков программирования и делают их идеальными инструментами для приложений искусственного интеллекта и машинного обучения. Lisp имеет серию доменных языков DSL, которые специализируются на определенной области, облегчают формулирование проблем исследования и помогают в установлении стандартов и лучших практик программирования применительно к конкретной области исследований.
История
Лисп является вторым старейшим языком высокого уровня (после FORTRAN), впервые разработанным Джоном Маккарти (Массачусетский технологический институт). Хотя он используется в качестве программного языка во многих областях науки, но после Дартмутской конференции 1956 года, которая считается местом рождение дисциплины искусственного интеллекта(ИИ), он в первую очередь идентифицируется с этой областью науки в течение многих лет.
В ранние годы его неоднородные диалекты разрастались, поскольку находили свое применение на разных платформах. В 1984 году усилия ученых по стандартизации программных языков привели к разработке Common Лисп, который в 1994 году стал стандартом ANSI. Сегодня большинство прикладных направлений пытаются придерживаться этого стандарта.
Еще один ранний диалект - Lisp-Scheme — сохранился до наших дней, является стандартизированным и широко используемым языком для программирования с нуля. Хотя он похож на Лисп, но отличается от него некоторыми элементами, которые позволяют рассматривать его как отдельный язык.
Ключевые моменты программирования
Лисп позволяет программистам писать быстрее. Эмпирическое исследование показывает, что когда специалисты решают те же проблемы в Lisp, C / C ++ и Java, то программы Лисп меньше, и, следовательно, их легче поддерживать, требуется меньше времени для разработки и запуска. Язык программирования Лисп упрощает создание макросов, которые облегчают создание модульных расширений, чтобы помочь специалистам легко разрабатывать плагины для программного обеспечения. Это, в свою очередь, открывает путь для создания отказоустойчивых доменных языков в приложениях любой области исследований или специализации.
Текущее состояние исследований Lisp в области информатики и вычислительной техники находится в точке, когда ожидаемо создания на базе универсального языка, что крайне необходимо, особенно с учетом документированных недостатков основных языков программирования, таких как R и Python. Основные элементы языка имеют несколько других функций, которые отличают его от других:
Базовая концепция
Lisp является самым ранним представителем парадигмы языка функционального программирования с нуля. В отличие от процедурных и объектно-ориентированных языков, теоретическая модель которых является машиной Тьюринга, теоретической моделью расчета Лиспа является исчисление Лямбды, разработанное церковью Алонсо. Это различие может быть понято в по следующим направлениям:
- В процедурных языках код работает с данными.
- В объектно-ориентированных языках объекты инкапсулируют код и данные, взаимодействуя друг с другом.
- В функциональных языках данные передаются через функции, но не имеют отдельного собственного существования.
- В чистых функциональных языках это эфемерно.
Интерактивность и гибкость
Скорость языков Lisp обычно эквивалентна интерпретируемым языкам. Это также является источником старого мифа о том, что если он интерпретируется, то, следовательно, должен быть медленным, однако это не так. Компиляторы для Лисп существуют с 1959 года, и теперь все основные реализации Common Лисп могут быть скомпилированы непосредственно с машинным кодом, который часто совпадает с кодом C. Например, CL—PPCRE библиотека выражений, написанная в Common Лисп, работает быстрее, чем движок регулярного выражения Perl на некоторых тестах в C, а обучение Lisp намного проще.
Программисты, которые используют интерпретируемые языки, такие как Python или Perl, для удобства и гибкости должны прибегать к написанию на C /C ++ для критически важных частей своего кода и имеют для этого уникальные возможности. Это было показано с прямым бенчмаркингом со стороны создателя языка программирования R, Росса Ихаки, который предоставил тесты, демонстрирующие, что необязательное объявление типа Lisp и компилятор машинного кода позволяют использовать их в 380 раз быстрее, чем R, и в 150 раз быстрее Python.
И не только код, созданный компиляторами по умолчанию, эффективен. Common Lisp, в частности, предлагает уникальные возможности для оптимизации тех частей кода, которые действительно должны быть очень быстрыми. Сюда входят так называемые макросы компилятора, которые могут преобразовывать вызовы функций в более эффективный код во время выполнения и обязательный дизассемблер, что позволяет программистам точно настраивать критические по времени функции до тех пор, пока скомпилированный код не будет соответствовать их ожиданиям.
Оценка специальных форм и макросов
Если первым символом в списке, подлежащем оценке, является имя специальной формы или макроса, так как интерпретатор не оценивает аргументы. Однако специальная форма или макрос могут оценивать некоторые из аргументов, как это обрабатывается, варьируется в специальной форме макроса. Например, специальная форма setq оценивает второй аргумент, но не первый. Пример: рассмотрим вторую строку следующего фрагмента кода: (setq a 1) (setq a (+ 2 3)).
Так как специальная форма setq оценивает свой второй аргумент, форма (+ 2 3) оценивается, получая 5. Однако форма не оценена как 5, а назначена. Если setq была функцией или специальной формой, которая оценивала оба аргумента, операция означала бы, что 5 должно быть равно 1, что, очевидно, абсурдная операция!
Некоторые формы и функции
Ниже перечислены лишь некоторые из специальных форм, макросов и lisp-функции. Некоторые специальные формы и макросы Quote являются специальной формой, которая просто передает свой неоценимый аргумент. Например, значение (quote a) символа a. Для удобства считается, что выражение формы anything эквивалентно (quote anything).
Setq - это специальная форма, которая оценивает свой второй аргумент, а затем присваивает значение переменной, названной ее аргументом.
Let является специальной формой, которая создает лексические переменные. Она имеет следующую базовую форму: (let ( <( переменное выражение )>*) < form >*). Формы оцениваются в контексте, в котором каждая из переменных является лексической переменной, связанной с указанным начальным значением. Все выражения вычисляются до того, как какая-либо из переменных привязана, поэтому выражение не может использовать ранее объявленную переменную let.
If является специальной формой, которая выбирает одно из двух выражений для оценки на основе результата какого-либо теста, причем его значение становится значением всего выражения. Это аналогично условному выражению языков C-семейства. Две формы должны быть одиночными s-выражениями, однако progn можно использовать для группировки нескольких форм (аналогично < . >Java), хотя это, конечно, не чисто функциональный стиль.
Форма else может быть опущена, в этом случае, если тест ложный, результат будет nil. Cond - это макрос, который выбирает одну серию выражений из нескольких для оценки. Он имеет следующую базовую форму (cond <( test