Lisp язык программирования для чего

Lisp (исторически LISP)-это семейство языков программирования с долгой историей и отличительной. Полностью заключенной в скобки префиксной нотацией.[3] Первоначально указанный в 1958 году. Lisp является вторым по возрасту языком программирования высокого уровня, широко используемым сегодня. Только Фортран старше на год.[4][5] Лисп изменился с первых дней. И многие диалекты существовали на протяжении всей его истории. Сегодня наиболее известными общецелевыми диалектами лиспа являются рэкет, Общий лисп, Схема и клоджур.

Первоначально Лисп был создан как практическая математическая нотация для компьютерных программпод влиянием (хотя и не изначально полученной из

[6]) нотации лямбда-исчисления Алонзо Черча. Он быстро стал излюбленным языком программирования для исследований искусственного интеллекта (ИИ). Будучи одним из самых ранних языков программирования. Lisp стал пионером многих идей в области информатики, включая древовидные структуры данных, автоматическое управление хранилищем, динамическую типизацию, условныевыражения , функции высшего порядка, рекурсию, самодостаточный компилятор и цикл read–eval–print.]

Название LISP происходит от [9]Связанные списки являются одной из основных структур данных Lisp, а исходный код Lisp состоит из списков. Таким образом. Лисп-программы могут манипулировать исходным кодом как структурой данных, порождая

макросистемы. Которые позволяют программистам создавать новый синтаксис или новые доменные языки, встроенные в Лисп.

Взаимозаменяемость кода и данных придает Лиспу его мгновенно узнаваемый синтаксис. Весь программный код записывается в виде s-выраженийили списков в скобках. Вызов функции или синтаксическая форма записываются в виде списка. В котором сначала указывается имя функции или оператора. А затем следуют аргументы; например, функция

f, принимающая три аргумента. Будет называться как (f arg1 arg2 arg3).

Джон Маккарти разработал лисп в 1958 году. Когда учился в Массачусетском технологическом институте (MIT). Маккарти опубликовал его дизайн в статье в журнале Communications of the ACM в 1960 году. Озаглавленной [10] Он показал, что с помощью нескольких простых операторов и обозначения анонимных функций. Заимствованных у Черча. Можно построить полный по Тьюрингу язык алгоритмов.

Язык обработки информации был первым языком искусственного интеллекта. Начиная с 1955 или 1956 года. И уже включал в себя многие понятия. Такие как обработка списков и рекурсия. Которые стали использоваться в Lisp.

Оригинальная нотация Маккарти использовала заключенные в скобки М-выраженияS-выражения. Например, М-выражение car[cons[A,B]]эквивалентно S-выражению (car (cons A B)). Как только Лисп был реализован. Программисты быстро решили использовать S-выражения. А от M-выражений отказались. М-выражения снова всплыли на поверхность после недолговечных попыток MLisp[11] Горация Энеа и CGOL Воана Пратта.

Lisp был впервые реализован Стивом Расселом на компьютере IBM 704 с использованием перфокарт.[12] Рассел прочитал статью Маккарти и понял (к удивлению Маккарти). Что функция Lisp

eval может быть реализована в машинном коде. В результате получился работающий интерпретатор Лиспа. Который можно было использовать для запуска лисп-программ или, точнее,

Примитивными операциями декомпозиции списков стали два макроса языка ассемблера для IBM 704: car(Содержание адресной части номера регистра) и cdr(Содержание декрементной части номера регистра)[14], где «регистр» относится к регистрам центрального процессора компьютера. Диалекты Lisp по-прежнему используют carand cdr( и ) для операций. Возвращающих первый элемент в списке и остальную часть списка соответственно.

Первый полный компилятор Lisp. Написанный на Лиспе. Был реализован в 1962 году Тимом Хартом и Майком Левином из Массачусетского технологического института.

[15] Этот компилятор представил модель инкрементной компиляции Lisp. В которой компилируемые и интерпретируемые функции могут свободно смешиваться. Язык, используемый в записке Харта и Левина. Гораздо ближе к современному стилю Lisp. Чем более ранний код Маккарти.

Первые процедуры сбора мусора были разработаны аспирантом Массачусетского технологического института Дэниелом Эдвардсом[16].]

В 1980-е и 1990-е годы были предприняты большие усилия по объединению работы над новыми диалектами Лиспа (в основном преемниками Maclisp, такими как ZetaLisp и NIL (Новая реализация Лиспа) в единый язык. Новый язык, Common Lisp, был в некоторой степени совместим с диалектами. Которые он заменил (книга Common Lisp the Language отмечает совместимость различных конструкций). В 1994 году ANSI опубликовала стандарт Common Lisp

Временная шкала

Подключение к искусственному интеллекту

С самого начала Lisp был тесно связан с исследовательским сообществом искусственного интеллекта. Особенно в системах PDP-10[17]. Lisp был использован в качестве реализации языка программирования Micro Planner, который использовался в знаменитой системе искусственного интеллекта SHRDLU. В 1970-х годах. Когда исследования ИИ породили коммерческие ответвления. Производительность существующих систем Lisp стала растущей проблемой.[требуется цитирование]

Генеалогия и варианты

За свою шестидесятилетнюю историю Шепелявость породила множество вариаций основной темы языка S-выражений. Более того, каждый данный диалект может иметь несколько реализаций—например. Существует более десятка реализаций Common Lisp.

Различия между диалектами могут быть весьма заметны—например. Common Lisp использует ключевое слово defunдля названия функции. А Scheme define— [18]. Однако в рамках стандартизированного диалекта соответствующие реализации поддерживают один и тот же базовый язык. Но с разными расширениями и библиотеками.

Исторически значимые диалекты

  • LISP 1[19] – Первая реализация.
  • LISP 1.5[16] – Первая широко распространенная версия. Разработанная Маккарти и другими в MIT. Названный так потому. Что он содержал несколько улучшений на оригинальном интерпретаторе LISP 2.
  • Stanford LISP 1.6[20] – Это был преемник LISP 1.5 . Разработанный в Stanford AI Labи широко распространенный в системах PDP-10 под управлением операционной системы TOPS-10. Маклисп и ИнтерЛисп сделали его устаревшим.
  • MACLISP[21] – разработанный для MIT Project MAC, MACLISP является прямым потомком LISP 1.5. Он работал на системах PDP-10 и Multics. Позже МАКЛИСП стал называться Маклиспом. И его часто называют Маклиспом. Macintosh, ни к McCarthy.
  • Interlisp[22] – разработан в BBN Technologies для систем PDP-10 под управлением операционной системы TENEX, позже принят как InterLisp-D. Небольшая версия под названием 8-разрядной семейной компьютерной линии Atari на базе 6502. Довольно долгое время Maclisp и InterLisp были сильными конкурентами.
  • Franz Lisp – первоначально проект Калифорнийского университета в Беркли; позже разработанный компанией Franz Inc. Это название является юмористической деформацией имени ФеренцЛистAllegro Common Lisp, диалекту Common Lisp . Продаваемому компанией Franz Inc. в последние годы.
  • XLISP, на котором базировался AutoLISP.
  • Широко использовались и портировались стандартный Lisp и портативный стандартный Lisp, особенно с системой компьютерной алгебры REDUCE.
  • ZetaLisp, также называемый Lisp Machine Lisp – используется на машинах Lisp, прямых потомках Maclisp. ЗетаЛисп оказал большое влияние на общий шепелявый язык.
  • LeLisp-французский лиспский диалект. Один из первых построителей интерфейса (называемый SOS Interface[23]) был написан на LeLisp.
  • Схема (1975).[24]
  • Common Lisp (1984), как описано Common Lisp the Language – консолидация нескольких расходящихся попыток (ZetaLisp, Spice Lisp, NILи S-1 Lisp) создать диалекты-преемникиMaclisp [25], с существенными влияниями также от диалекта Схемы. Эта версия Common Lisp была доступна для широкого круга платформ и была принята многими как стандарт де-факто[26] до публикации ANSI Common Lisp (ANSI X3.226-1994). Среди наиболее распространенных субдиалектов Common Lisp-Steel Bank Common Lisp (SBCL). CMU Common Lisp (CMU-CL). Clozure OpenMCL (не путать с Clojure!). GNU CLisp и более поздние версии Franz Lisp; все они придерживаются более позднего стандарта ANSI CL (см.
  • Дилан был в своей первой версии смесью схемы с общей системой объектов Lisp.
  • EuLisp – попытка разработать новый эффективный и очищенный Лисп.
  • ISLISP – попытка разработать новый эффективный и очищенный Лисп. Стандартизирован как ISO/IEC 13816:1997[27] и позже пересмотрен как ISO/IEC 13816:2007:[28]Информационные технологии – Языки программирования. Их среды и системные программные интерфейсы – Язык программирования ISLISP.
  • Схема IEEE – стандарт IEEE, 1178-1990 (R1995)
  • ANSI Common Lispстандарт Американского Национального института стандартов (ANSI) для Common Lisp, созданный подкомитетом X3J13, зафрахтованным[29] для того. Чтобы начать с Common Lisp: The Language as a base Document и работать через процесс общественного консенсуса для поиска решений общих проблем переносимости программ и совместимости реализаций Common Lisp. Хотя формально ANSI является стандартом. Внедрение, продажа. Использование и влияние ANSI Common Lisp наблюдалось и продолжает наблюдаться во всем мире.
  • ACL2 или ACL2-это и язык программирования. Который может моделировать компьютерные системы. И инструмент. Помогающий доказать свойства этих моделей.
  • Clojure, недавний диалект Lisp. Который компилируется в виртуальную машину Java и имеет особый акцент на параллелизме.
  • Game Oriented Assembly Lisp (или GOAL) — это язык программирования видеоигр. Разработанный Энди Гэвином и командой Jak and Daxter в Naughty Dog. Она была написана с использованием Allegro Common Lisp и использовалась при разработке всей серии игр Jak и Daxter.

с 2000 года по настоящее

После некоторого спада в 1990-х годах интерес к шепелявости вновь возрос после 2000 года. Большая часть новой деятельности была сосредоточена вокруг реализаций Common Lisp, Scheme, Emacs Lisp, Clojureи Racket, а также включает в себя разработку новых переносимых библиотек и приложений.

Многие новые программисты Lisp были вдохновлены такими писателями. Как Пол Грэм и Эрик С. Рэймонд, чтобы преследовать язык. Который другие считали устаревшим. Новые программисты на лиспе часто описывают язык как открывающий глаза опыт и утверждают. Что он значительно более продуктивен. Чем в других языках.[30] Этот рост осведомленности можно сравнить с зимой ИИ[31]

По состоянию на 2010было одиннадцать активно поддерживаемых реализаций Common Lisp.[32] Scieneer Common Lisp-это новая коммерческая реализация. Разветвленная от CMUCL с первым выпуском в 2002 году.

С открытым исходным кодом сообщество создало новые вспомогательная инфраструктура: CLiki — Вики. Который собирает общий Лисп. Связанных с информацией, в общий Лисп каталоге перечислены ресурсы. #Lisp-это популярный IRC-канал и позволяет обмену и комментирование фрагментов кода (при поддержке lisppaste, также IRC-бот написан на Лиспе), Планета Лисп собирает содержимое из различных Лисп-обзоры блогов, на LispForum пользователей Лиспа обсудить темы, Lispjobs — это сервис для объявления вакансии и еженедельно служба новостей, еженедельные Лисп Новости. Common-lisp.net это хостинг-сайт для проектов Common Lisp с открытым исходным кодом. Quicklisp-это менеджер библиотек для Common Lisp.

Пятьдесят лет Lisp (1958-2008) было отпраздновано в LISP50@OOPSLA.[33] В Бостоне, Ванкувере и Гамбурге регулярно проводятся встречи местных пользователей. Другие мероприятия включают Европейское Общее совещание по лиспу. Европейский симпозиум по лиспу и Международную конференцию по лиспу.

Сообщество Scheme активно поддерживает более двадцати реализаций. В 2000-е годы (десятилетие) было разработано несколько значительных новых реализаций (Chicken, Gambit. Gauche, Ikarus. Larceny, Ypsilon). В сообществе Scheme был широко принят пересмотренный 5-й отчет о стандарте схемы алгоритмического языка[34]. В процессе реализации Scheme Requests было создано множество квази-стандартных библиотек и расширений для Scheme. Сообщества пользователей отдельных реализаций схем продолжают расти. Новый процесс стандартизации языка был начат в 2003 году и привел к R6Стандарт схемы RS в 2007 году. Академическое использование Схемы для обучения информатике. По-видимому. Несколько сократилось. Некоторые университеты больше не используют Scheme в своих вводных курсах по информатике;[35][36] Массачусетский технологический институт теперь использует Python вместо Scheme для своей программы бакалавриата по информатике и массового открытого онлайн-курса MITx.[37][38]

Существует несколько новых диалектов лиспа: Arc, Hy, Nu, Liskellи LFE (Lisp Flavored Erlang). Парсер для Джулии реализован на фемтолиспе. Диалекте Схемы (Джулия вдохновлена Схемой, которая. В свою очередь. Является диалектом лиспа).

В октябре 2019 года Пол Грэм выпустил спецификацию для Bel,

Основные диалекты

Common Lisp и Scheme представляют собой два основных потока развития Lisp. Эти языки воплощают существенно различные варианты дизайна.

Common Lisp является преемником Maclisp. Основными влияниями были Lisp Machine Lisp, Maclisp, NIL, S-1 Lisp, Spice Lispи Scheme.[39] Он обладает многими особенностями Lisp Machine Lisp (большой диалект Lisp. Используемый для программирования Lisp-машин), но был разработан таким образом. Чтобы быть эффективно реализованным на любом персональном компьютере или рабочей станции. Common Lisp является языком программирования общего назначения и. Таким образом. Имеет большой языковой стандарт. Включающий множество встроенных типов данных, функций. Макросов и других языковых элементов. А также объектную систему (Common Lisp Object System). Common Lisp также заимствовал некоторые особенности из схемы. Такие как лексическая область и лексические замыкания. Реализации Common Lisp доступны для таргетинга на различные платформы. Такие как LLVM, Java virtual machine, x86-64, PowerPC. Alpha, ARM. Motorola 68000 и MIPS, а также операционные системы. Такие как Windows. MacOS, Linux. Solaris, FreeBSD. NetBSD, OpenBSD. Dragonfly BSD и Heroku.[43]

Scheme-это статически ограниченный и правильно хвост-рекурсивный диалект языка программирования Lisp. Изобретенный Гаем Л. Стилом-младшим и Джеральдом Джеем Сассманом. Он был разработан. Чтобы иметь исключительно ясную и простую семантику и несколько различных способов формирования выражений. Разработанная примерно на десять лет раньше. Чем Common Lisp, Scheme представляет собой более минималистичный дизайн. Он имеет гораздо меньший набор стандартных функций. Но с определенными функциями реализации (такими как оптимизация хвостового вызова и полные продолжения) не указан в Common Lisp. Большое разнообразие парадигм программирования. Включая императивные. Функциональные и стили передачи сообщений. Находят удобное выражение в Схеме. Схема продолжает развиваться с серией стандартов (Пересмотренный отчет n о схеме алгоритмического языка) и серией запросов схемы на реализацию.

Clojure-это недавний диалект Lisp . Предназначенный в основном для виртуальной машины Java, а также для среды выполнения Common Language Runtime (CLR), виртуальной машины Python , виртуальной машины Ruby YARVи компиляции в JavaScript. Он предназначен для прагматического языка общего назначения. Clojure черпает значительное влияние из Haskell и делает очень сильный акцент на неизменяемости.[44] Clojure предоставляет доступ к фреймворкам и библиотекам Java с дополнительными подсказками типов и выводом типов, так что вызовы Java могут избежать отражения и включить быстрые примитивные операции. Clojure не предназначен для обратной совместимости с другими диалектами Lisp.[45]

Кроме того, диалекты Lisp используются в качестве языков сценариев во многих приложениях. Наиболее известными из которых являются Emacs Lisp в редакторе Emacs, AutoLISP и позже Visual Lisp в AutoCAD, Nyquist в Audacityи Scheme в LilyPond. Потенциально небольшой размер полезного интерпретатора схем делает его особенно популярным для встроенных сценариев. Примеры включают SIOD и TinyScheme, оба из которых были успешно встроены в процессор обработки изображений GIMP под общим именем Менеджер окон Sawfish.[47]

Стандартизированные диалекты

Lisp имеет официально стандартизированные диалекты: R6RS Scheme, R7RS Scheme, IEEE Scheme,[48]ANSI Common Lisp и ISO ISLISP.

Язык инновации

Lisp был первым языком. Где структура программного кода представлена точно и непосредственно в стандартной структуре данных—качество. Гораздо позже получившее название гомоиконичностьТаким образом. Функциями Lisp можно манипулировать. Изменять или даже создавать в программе Lisp без манипуляций более низкого уровня. Это, как правило. Считается одним из главных преимуществ языка с точки зрения его выразительной силы. И делает язык пригодным для синтаксических макросов и метациркулярной оценки.

Условное выражение. Использующее синтаксис if–then–else, было изобретено Маккарти в контексте Фортрана. Он предложил включить его в ALGOL, но он не был включен в спецификацию Algol 58. Для лиспа Маккарти использовал более общую структуру cond.[49]Алгол 60 взял if-then–else и популяризировал ее.

Lisp глубоко повлиял на Алана Кея, руководителя исследовательской группы. Разработавшей Smalltalk в Xerox PARC; и в свою очередь Lisp был под влиянием Smalltalk. С более поздними диалектами. Принявшими объектно-ориентированные функции программирования (классы наследования. Инкапсуляция экземпляров. Передача сообщений и т. Д.) В 1970-х годах. Объектная система Flavors ввела концепцию множественного наследования и миксина. Объектная система Common Lisp обеспечивает множественное наследование. Мультиметоды с множественной диспетчеризациейи первоклассные универсальные функции, обеспечивая гибкую и мощную форму динамической диспетчеризации. Он служил в качестве шаблона для многих последующих Лисп (в том числе схемы) объектов системы. Которые нередко претворяются в жизнь через протокол метаобъекта, а светоотражающие metacircular проектирования , в котором объект системы определяется с точки зрения себя: Лисп был только вторым языком после таких языков. Как Smalltalk (и до сих пор является одним из очень немногих языках). Чтобы обладать такой мета-объектной системы. Много лет спустя Алан Кей предположил. Что в результате слияния этих функций только Smalltalk и Lisp можно рассматривать как правильно задуманные объектно-ориентированные системы программирования.[50]

Лисп ввел концепцию автоматической сборки мусора, при которой система ходит по куче в поисках неиспользуемой памяти. Прогресс в современных сложных алгоритмах сбора мусора. Таких как поколенческая сборка мусора. Был стимулирован его использованием в Лиспе[51].]

Эдсгер У Дейкстра в своей лекции о премии Тьюринга 1972 года сказал,

Кроме того, LISP был носителем для значительного числа в некотором смысле наших самых сложных компьютерных приложений. LISP в шутку был описан как “самый умный способ неправильного использования компьютера”. Я считаю это описание большим комплиментом. Потому что оно передает весь аромат освобождения: оно помогло многим нашим наиболее одаренным собратьям-людям думать о ранее невозможных мыслях[52]

Во многом из-за своих потребностей в ресурсах по отношению к раннему вычислительному оборудованию (включая ранние микропроцессоры) Lisp не стал таким популярным за пределами сообщества ИИ. Как Fortran и язык C. Происходящий от АЛГОЛА. Из-за своей пригодности для сложных и динамичных приложений Lisp пользуется некоторым возрождением популярного интереса в 2010-х годах [53].]

Синтаксис и семантика

Примечание: Примеры этой статьи написаны на Common Lisp (хотя большинство из них также допустимы в Схеме).

Символические выражения (S-выражения)

Lisp-это язык. Ориентированный на выражения. В отличие от большинства других языков. Здесь не проводится различия между ; весь код и данные записываются в виде выражений. Когда выражение вычисляется, оно выдает значение (в Common Lisp, возможно. Несколько значений). Которое затем может быть встроено в другие выражения. Каждое значение может быть любым типом данных.

В статье 1958 года Маккарти ввел два типа синтаксиса: Символические выражения (S-выражения, sexps). Которые отражают внутреннее представление кода и данных; и Мета-выражения (M-выражения), которые выражают функции S-выражений. М-выражения никогда не пользовались популярностью. И почти все современные шепелявые используют S-выражения для манипулирования как кодом. Так и данными.

Использование скобок является наиболее очевидным отличием Lisp от других семейств языков программирования. В результате студенты уже давно дают Шепелявым прозвищам такие . Как Потерянные В Глупых скобкахили Множество Раздражающих Лишних скобок.] Однако синтаксис S-выражения также отвечает за большую часть мощности Lisp: синтаксис чрезвычайно регулярен. Что облегчает манипуляции компьютером. Однако синтаксис Lisp не ограничивается традиционными скобками. Он может быть расширен и включать альтернативные обозначения. Например, XMLisp-это общее расширение Lisp, которое использует протокол metaobject для интеграции S-выражений с расширяемым языком разметки (XML).

Опора на выражения дает языку большую гибкость. Поскольку функции Lisp записываются в виде списков. Они могут обрабатываться точно так же. Как и данные. Это позволяет легко писать программы. Которые манипулируют другими программами (метапрограммирование). Многие диалекты Lisp используют эту функцию с помощью макросистем. Что позволяет расширять язык почти без ограничений.

Списки

Список Lisp записывается с элементами . Разделенными пробеламии окруженными круглыми скобками. Например, (1 2 foo)это список. Элементами которого являются три атома 1,2, и foo. Эти значения неявно типизированы: они являются соответственно двумя целыми числами и специфичным для Lisp типом данных, называемым

Пустой список ()также представлен в виде специального атома nil. Это единственная сущность в Лиспе. Которая является одновременно атомом и списком.

Выражения записываются в виде списков. Используя префиксальную нотацию. Первым элементом в списке является имя функции. Имя макроса. Лямбда-выражение или имя Остальная часть списка-аргументы. Например, функция listвозвращает свои аргументы в виде списка. Поэтому выражение

 (список 1 2 (цитата foo)) 

оценивает список (1 2 foo). fooв предыдущем примере является Любые некотируемые выражения рекурсивно вычисляются перед вычислением заключающего выражения. Например,

 (список 1 2 (список 3 4)) 

оценивает список (1 2 (3 4)). Обратите внимание. Что третий аргумент-это список; списки могут быть вложенными.

Операторы

Арифметические операторы обрабатываются аналогично. Выражение

 (+ 1 2 3 4) 

оценивает до 10. Эквивалентом в инфиксной нотации будет 1 + 2 + 3 + 4

В Лиспе нет понятия операторов. Реализованных в языках. Производных от Алголя. Арифметические операторы в Лиспе-это вариадические функции (или n-арные), способные принимать любое число аргументов. Оператор инкремента ‘++’ в стиле C иногда реализуется под именем incfсинтаксиса. Дающего имя

 (вкл. x) 

эквивалентно тому (setq x (+ x 1)), что возвращает новое значение x.

Например, специальный оператор ifпринимает три аргумента. Если первый аргумент не равен нулю. Он вычисляется до второго аргумента; в противном случае он вычисляется до третьего аргумента. Таким образом, выражение

 (если нет (список 1 2 ) (список 3 4 )) 

оценивает до (3 4 "bar"). Конечно, это было бы более полезно. Если бы вместо этого было заменено нетривиальное выражение nil.

Lisp также предоставляет логические операторы and, or и not. Операторы and и or выполняют оценку короткого замыкания и возвращают свой первый аргумент nil и non-nil соответственно.

 (или (и  ноль )  время  ) 

будем оценивать по

Лямбда-выражения и определение функций

Другой специальный оператор, lambda, используется для привязки переменных к значениям. Которые затем вычисляются в выражении. Этот оператор также используется для создания функций: аргументы tolambda-это список аргументов. А также выражение или выражения. Для которых выполняется вычисление функции (возвращаемое значение-это значение последнего вычисляемого выражения). Выражение

 (лямбда (arg) (+ arg 1)) 

вычисляет функцию. Которая при применении принимает один аргумент. Связывает его argи возвращает число на единицу больше этого аргумента. Лямбда-выражения обрабатываются не иначе. Чем именованные функции; они вызываются таким же образом. Поэтому выражение

 ((лямбда (arg) (+ arg 1)) 5) 

оценивает до 6. Здесь мы делаем приложение функции: мы выполняем анонимную функцию, передавая ей значение 5.

Именованные функции создаются путем хранения лямбда-выражения в символе с помощью макроса defun.

 (defun foo (a b c d) (+ a b c d)) 

(defun f (a) b...) определяет новую функцию с именем fв глобальной среде. Это концептуально похоже на выражение:

 (setf (fdefinition 'f) #'(lambda (a) (block f b...))) 

гдеsetf-макрос. Используемый для установки значения первого аргумента fdefinition 'fв новый объект функции. fdefinition это глобальное определение функции для названной функции f. #' это аббревиатура functionспециального оператора. Возвращающего объект функции.

Атомы

В исходном LISP было два основных типа данных: атомы и списки. Список-это конечная упорядоченная последовательность элементов. Где каждый элемент-это либо атом. Либо список. А атом-это число или символ. Символ-это, по сути . Уникальный именованный элемент. Записанный в виде буквенно-цифровой строки в исходном кодеи используемый либо как имя переменной. Либо как элемент данных в символьной обработке. Например, список (FOO (BAR 1) 2)содержит три элемента: символ FOO, список (BAR 1)и число 2.

Существенное различие между атомами и списками состояло в том. Что атомы были неизменными и уникальными. Два атома, которые появились в разных местах исходного кода. Но были написаны точно таким же образом. Представляли один и тот же объект. В то время как каждый список был отдельным объектом. Который мог быть изменен независимо от других списков и мог быть отличен от других списков операторами сравнения.

По мере того как в более поздние диалекты лиспа вводилось все больше типов данных и развивались стили программирования. Понятие атома теряло свое значение. Многие диалекты все еще сохраняли атом предиката для унаследованной совместимости, определяя его истинным для любого объекта. Который не является cons.

Минусы и списки

Схема прямоугольника иуказателя для списка (42 69 613)

Список Lisp реализован как односвязный список.[55] Каждая ячейка этого списка называется cons (в схеме-парой) и состоит из двух указателей, называемых car и cdr. Они соответственно эквивалентны полям dataиnext, обсуждаемым в связанном списке статей.

Из многих структур данных. Которые могут быть построены из ячеек cons. Одна из самых основных называется правильным списком. Правильный список-это либо специальный nil(пустой список) символ. Либо минусы. В которых carточки указывают на датум (который может быть другой структурой минусов. Такой как список), а cdrточки-на другой правильный список.

Если данный cons считать главой связанного списка. То его car указывает на первый элемент списка. А cdr-на остальную часть списка. По этой причине функции carand cdrтакже называются firstand restпри обращении к conses. Которые являются частью связанного списка (а не. Скажем, дерева).

Таким образом. Список Lisp не является атомарным объектом. Как это было бы с экземпляром контейнерного класса в C++ или Java. Список-это не что иное. Как совокупность связанных сбережений. Переменная, которая ссылается на данный список. Является просто указателем на первые минусы в списке. Обход списка может быть выполнен путем cdring вниз по списку; то есть. Принимая последовательные cdrs посетить каждый минусы списка; или с помощью любой из нескольких функций более высокого порядка для отображения функции над списком.

Поскольку conses и списки настолько универсальны в системах Lisp. Распространено заблуждение. Что они являются единственными структурами данных Lisp. На самом деле, все. Кроме самых простых лиспов. Имеют другие структуры данных. Такие как векторы (массивы), хэш-таблицы. Структуры и т. Д.

S-выражения представляют списки

S-выражения. Заключенные в скобки. Представляют собой структуры связанных списков. Существует несколько способов представления одного и того же списка в виде S-выражения. Минусы могут быть записаны в виде точечных парных обозначений (a . b), где aнаходится автомобиль и bcdr. Более длинный правильный список может быть записан (a . (b . (c . (d . nil))))в виде точечных пар. Это условно сокращается. Как (a b c d)в нотации списка. Неправильный список[56] может быть записан в комбинации из двух – как (a b c . d)для списка из трех минусов. Последним из которых является cdr d(то есть список (a . (b . (c . d)))в полностью заданной форме).

Процедуры обработки списков

Lisp предоставляет множество встроенных процедур для доступа к спискам и управления ими. Списки могут быть созданы непосредственно с listпомощью процедуры. Которая принимает любое количество аргументов и возвращает список этих аргументов.

 (список 1 2 'a 3) ;Вывод: (1 2 a 3) 
 (список 1 '(2 3) 4) ;Вывод: (1 (2 3) 4) 

Из-за того . Что списки строятся из пар минусов, consпроцедура может быть использована для добавления элемента в переднюю часть списка. Обратите внимание. Что consпроцедура асимметрична в том. Как она обрабатывает аргументы списка. Из-за того. Как создаются списки.

 (минусы 1 '(2 3)) ;Выход: (1 2 3) 
 (минусы '(1 2) '(3 4)) ;Выход: ((1 2) 3 4) 

appendПроцедура добавляет два (или более) списка друг к другу. Поскольку списки Lisp являются связанными списками. Добавление двух списков имеет асимптотическую временную сложность

O(n){\displaystyle O(n)}

 (добавить '(1 2) '(3 4)) ;Выход: (1 2 3 4) 
 (добавить '(1 2 3) '() '(a) '(5 6)) ; Выход: (1 2 3 a 5 6) 

Общая структура

Списки Lisp. Будучи простыми связанными списками. Могут делиться структурой друг с другом. То есть два списка могут иметь один и тот же хвостили конечную последовательность минусов. Например, после выполнения следующего кода Common Lisp:

(setf foo (list 'a 'b 'c)) (setf bar (cons 'x (cdr foo))) 

списки fooи barесть (a b c)и (x b c)соответственно. Однако хвост(b c)-это одна и та же структура в обоих списках. Это не копия; ячейки cons. Указывающие на bи cнаходятся в одних и тех же ячейках памяти для обоих списков.

Совместное использование структуры. А не копирование может дать резкое повышение производительности. Однако этот метод может нежелательно взаимодействовать с функциями. Которые изменяют списки. Передаваемые им в качестве аргументов. Изменение одного списка, например. Путем замены cна a goose, повлияет на другой:

 (setf (third foo) 'гусь) 

Это изменяется foo(a b goose), но тем самым также изменяется bar(x b goose)– возможно. Неожиданный результат. Это может быть источником ошибок, и функции. Которые изменяют свои аргументы. Документируются как разрушительные именно по этой причине.

Приверженцы функционального программирования избегают деструктивных функций. В схеме диалекта. Благоприятствующей функциональному стилю. Названия деструктивных функций обозначаются предостерегающим восклицательным знаком. Или set-car!(читай набор car bang), который заменяет автомобиль из минусов. На диалекте Common Lisp деструктивные функции являются обычным явлением; эквивалент set-car!называется rplacaОднако эта функция редко встречается так как Common Lisp включает в себя специальное средство, setf, чтобы облегчить определение и использование деструктивных функций. Частым стилем в Common Lisp является написание кода функционально (без деструктивных вызовов) при прототипировании. А затем добавление деструктивных вызовов в качестве оптимизации там. Где это безопасно.

Самооценочные формы и цитирование

Lisp вычисляет выражения. Которые вводит пользователь. Символы и списки вычисляются в соответствии с каким – либо другим (обычно более простым) выражением-например. Символ вычисляется в соответствии со значением переменной. Которую он называет; (+ 2 3)вычисляется 5. Однако большинство других форм оценивают сами себя: если войти 5в Лисп. То он возвращается 5.

Любое выражение также может быть помечено. Чтобы предотвратить его вычисление (как это необходимо для символов и списков). Это роль quoteспециального оператора. Или его аббревиатура '(одна кавычка). Например, обычно при вводе символа fooон возвращает значение соответствующей переменной (или ошибку . Если такой переменной нет). Чтобы обратиться к буквальному символу. Введите (quote foo)или, как правило, 'foo.

Как Common Lisp. Так и Scheme также поддерживают оператор backquote (называемый quasiquote в Схеме). Вводимый с `символом (серьезное ударение). Это почти то же самое. Что и обычная кавычка. За исключением того. Что она позволяет вычислять выражения и интерполировать их значения в список кавычек с , помощью операторов unquote и comma-at ,@ splice. Если переменная snueимеет значение(bar baz), то `(foo ,snue)вычисляется значение to (foo (bar baz)), а `(foo ,@snue)вычисляется значение to (foo bar baz). Обратная цитата чаще всего используется при определении макрорасширений.[57][58]

Самооценочные формы и кавычки являются эквивалентом литералов Lisp. Можно изменить значения (изменяемых) литералов в программном коде. Например, если функция возвращает форму в кавычках, а код. Вызывающий функцию. Изменяет форму. Это может изменить поведение функции при последующих вызовах.

(defun should-be-constant () '(one two three)) (let ((stuff (should-be-constant))) (setf (third stuff) 'bizarre)) ; плохо! (должен быть постоянным) ; возвращает (один два причудливых) 

Изменение такой формы в кавычках обычно считается плохим стилем и определяется ANSI Common Lisp как ошибочное (что приводит к

Формализация Лиспа цитирования была отмечена Дугласом ХофштадтеромГеделя, Эшера. Баха) и другими в качестве примера философской идеи самореференции .

Область применения и закрытие

Семейство Lisp разделяется на использование динамической или статической (также известной как лексическая) области . Clojure, Common Lisp и Scheme по умолчанию используют статическую область видимости. В то время как newLISP, Picolisp и встроенные языки Emacs и AutoCAD используют динамическую область видимости. Начиная с версии 24.1, Emacs использует как динамическую. Так и лексическую область видимости.

Структура списка программного кода; эксплуатация макросами и компиляторами

Фундаментальное различие между Lisp и другими языками заключается в том. Что в Lisp текстовое представление программы-это просто читаемое человеком описание тех же внутренних структур данных (связанных списков. Символов, чисел. Символов и т. Д.), Которые используются базовой системой Lisp.

Lisp использует это для реализации очень мощной макросистемы. Как и другие макроязыки . Такие как C, макрос возвращает код. Который затем может быть скомпилирован. Однако, в отличие от макросов C. Макросы являются функциями Lisp и поэтому могут использовать всю мощь Lisp.

Кроме того, поскольку код Lisp имеет ту же структуру. Что и списки. Макросы могут быть построены с помощью любой из функций обработки списков в языке. Короче говоря, все. Что Лисп может сделать со структурой данных. Макросы Лиспа могут сделать с кодом. В отличие от этого. В большинстве других языков вывод синтаксического анализатора является чисто внутренним для реализации языка и не может быть обработан программистом.

Эта функция позволяет легко разрабатывать эффективные языки внутри языков. Например, объектная система Common Lisp может быть чисто реализована как расширение языка с помощью макросов. Это означает. Что если приложение нуждается в другом механизме наследования. Оно может использовать другую объектную систему. Это резко контрастирует с большинством других языков; например. Java не поддерживает множественное наследование. И нет разумного способа добавить его.

В упрощенных реализациях Lisp эта структура списка непосредственно интерпретируется для запуска программы; функция-это буквально часть структуры списка. Которую проходит интерпретатор при ее выполнении. Однако большинство существенных систем Lisp также включают компилятор. Компилятор переводит структуру списка в машинный код или байт-код для выполнения. Этот код может работать так же быстро, как код. Скомпилированный на обычных языках. Таких как C.

Макросы расширяются перед этапом компиляции и. Таким образом. Предлагают некоторые интересные варианты. Если программе нужна предварительно вычисленная таблица. То макрос может создать таблицу во время компиляции. Поэтому компилятору нужно только вывести таблицу и не нужно вызывать код для создания таблицы во время выполнения. Некоторые реализации Lisp даже имеют механизмeval-when, который позволяет коду присутствовать во время компиляции (когда макрос будет нуждаться в нем). Но не присутствовать в излучаемом модуле.[59]

Оценка и цикл read–eval–print

Языки Lisp часто используются с интерактивной командной строкой, которая может быть объединена с интегрированной средой разработки (IDE). Пользователь вводит выражения в командной строке или направляет IDE для передачи их в систему Lisp. Lisp считывает введенные выражения, вычисляет их и выводит результат. По этой причине командная строка Lisp называется циклом read–eval–print (REPL).

Основная операция REPL заключается в следующем. Это упрощенное описание. Которое опускает многие элементы реального лиспа. Такие как кавычки и макросы.

readФункция принимает текстовые S-выражения в качестве входных данных и анализирует их во внутреннюю структуру данных. Например, если вы наберете текст (+ 1 2)в приглашении, readон преобразуется в связанный список с тремя элементами: символом +, цифрой 1 и цифрой 2. Так случилось. Что этот список также является допустимым фрагментом кода Lisp; то есть он может быть оценен. Это происходит потому. Что автомобиль списка называет функцию—операцию сложения.

Обратите внимание. Что а fooбудет читаться как один символ. 123 будет прочитано как число сто двадцать три. "123" будет прочитана как строка

evalФункция вычисляет данные. Возвращая в результате ноль или более других данных Lisp. Вычисление не обязательно означает интерпретацию; некоторые лисп-системы компилируют каждое выражение в машинный код. Однако легко описать оценку как интерпретацию: чтобы вычислить список. Автомобиль которого называет функцию, evalсначала вычисляется каждый из аргументов. Приведенных в его cdr. А затем применяется функция к аргументам. В этом случае функция является сложением. И применение ее к списку аргументов (1 2)дает ответ 3. Это результат оценки.

Символ fooвычисляется как значение символа foo. Данные, такие как строка Список (quote (1 2 3))оценивается в список (1 2 3).

Это работа printфункции для представления выходных данных пользователю. Для такого простого результата 3это тривиально. Выражение, которое вычисляется в часть структуры списка, требует. Чтобы printоно пересекло список и распечатало его как S-выражение.

Для реализации Lisp REPL необходимо только реализовать эти три функции и функцию бесконечного цикла. (Естественно. Реализация evalбудет сложной. Так как она также должна реализовывать все специальные операторы типа ifor lambda.) Это сделано. Основной REPL является одна строка кода: (loop (print (eval (read)))).

Lisp REPL обычно также обеспечивает редактирование входных данных. Историю входных данных. Обработку ошибок и интерфейс к отладчику.

Шепелявость обычно оценивают жадно. В Common Lispаргументы вычисляются в прикладном порядке (Схеме порядок аргументов не определен. Оставляя место для оптимизации компилятором.

Структуры управления

Первоначально в лиспе было очень мало управляющих структур. Но в процессе эволюции языка появилось гораздо больше. (Оригинальный условный оператор Lisp, cond, является предшественником более поздних if-then-elseструктур.)

Программисты на диалекте Схемы часто выражают циклы с помощью хвостовой рекурсии. Общность схемы в академической информатике привела некоторых студентов к убеждению. Что хвостовая рекурсия-это единственный или наиболее распространенный способ написания итераций на Лиспе. Но это неверно. Все часто встречающиеся диалекты Лиспа имеют итерационные конструкции императивного стиля, от doцикла схемы до сложных выражений Common Lisploop. Более того, ключевой вопрос. Который делает этот вопрос объективным. А не субъективным. Заключается в том. Что Схема предъявляет особые требования к обработке хвостовых вызовов, и, таким образом, причина. По которой использование хвостовой рекурсии обычно поощряется для схемы. Заключается в том. Что эта практика явно поддерживается определением языка. Напротив, ANSI Common Lisp не требует[60] оптимизации. Обычно называемой устранением хвостового вызова. Таким образом, тот факт . Что хвостовой рекурсивный стиль как случайная замена использования более традиционных итерационных конструкций (таких какdo, dolistили loop) не рекомендуется[61] в Common Lisp. Является не просто вопросом стилистических предпочтений. Но потенциально вопросом эффективности (поскольку очевидный хвостовой вызов в Common Lisp может не компилироваться как простой переход) и корректность программы (поскольку хвостовая рекурсия может увеличить использование стека в Common Lisp. Рискуя переполнением стека).

Некоторые структуры управления Lisp являются специальными операторами, эквивалентными синтаксическим ключевым словам других языков. Выражения, использующие эти операторы. Имеют тот же внешний вид. Что и вызовы функций. Но отличаются тем. Что аргументы не обязательно вычисляются—или. В случае итерационного выражения. Могут быть вычислены более одного раза.

В отличие от большинства других основных языков программирования. Lisp позволяет реализовывать управляющие структуры с помощью этого языка. Некоторые управляющие структуры реализуются в виде макросов Lisp и могут быть даже расширены программистом. Который хочет знать. Как они работают.

И Common Lisp. И Scheme имеют операторы для нелокального потока управления. Различия в этих операторах являются одними из самых глубоких различий между двумя диалектами. Схема поддерживает повторные продолжения с использованием процедуры. Которая позволяет программе сохранить (а затем восстановить) определенное место в процессе выполнения.call/cc Common Lisp не поддерживает повторные продолжения. Но поддерживает несколько способов обработки escape-продолжений.

Часто один и тот же алгоритм может быть выражен в лиспе либо в императивном. Либо в функциональном стиле. Как отмечалось выше. Схема имеет тенденцию отдавать предпочтение функциональному стилю. Используя хвостовую рекурсию и продолжения для выражения потока управления. Однако императивный стиль все же вполне возможен. Стиль. Предпочитаемый многими программистами Common Lisp. Может показаться более знакомым программистам. Привыкшим к структурированным языкам. Таким как C. В то время как стиль. Предпочитаемый схематиками. Больше напоминает чисто функциональные языки. Такие как Haskell.

Благодаря раннему наследию Лиспа в области обработки списков он обладает широким спектром функций более высокого порядка. Связанных с итерацией последовательностей. Во многих случаях. Когда явный цикл был бы необходим в других языках (напримерfor, цикл в C). В Lisp та же задача может быть выполнена с помощью функции более высокого порядка. (То же самое относится и ко многим функциональным языкам программирования.)

Хорошим примером является функция. Которая в Scheme называется mapи в Common Lisp называется mapcar. Учитывая функцию и один или несколько списков, mapcarприменяет функцию последовательно к элементам списков по порядку. Собирая результаты в новый список:

 (mapcar #'+ '(1 2 3 4 5) '(10 20 30 40 50)) 

Это применяет +функцию к каждой соответствующей паре элементов списка. Давая результат (11 22 33 44 55).

Вот примеры кода Common Lisp.

Основное Здравствуй. Мир!— программа:

(печать ) 

Синтаксис Lisp естественно поддается рекурсии. Математические задачи. Такие как перечисление рекурсивно определенных множеств. Просты для выражения в этой нотации. Например, для оценки факториала числа:

(defun factorial (n) (if (= n 0) 1 (* n (factorial (- n 1))))) 

Альтернативная реализация занимает меньше места в стеке. Чем предыдущая версия. Если базовая система Lisp оптимизирует хвостовую рекурсию:

(defun factorial (n &optional (acc 1)) (if (= n 0) acc (factorial (- n 1) (* acc n)))) 

Сравните приведенные выше примеры с итеративной версией. Которая использует макрос Common Lisploop:

(defun factorial (n) (цикл для i от 1 до n для fac = 1 then (* fac i) finally (return fac))) 

Следующая функция переворачивает список. (Встроенная обратная функция Lisp делает то же самое.)

(defun -reverse (list) (let ((return-value '())) (dolist (e list) (push e return-value)) return-value)) 

Объектные системы

Различные объектные системы и модели были построены поверх. Рядом или в Lisp, включая:

  • Объектная система Common Lisp, CLOS. Является неотъемлемой частью ANSI Common Lisp. КЛО происходил от Новых Ароматов и простонародья. ANSI Common Lisp был первым стандартизированным объектно-ориентированным языком программирования (1994, ANSI X3J13).
  • ObjectLisp[62] или Object Lisp, используемый компанией Lisp Machines Incorporated и ранними версиями Macintosh Common Lisp
  • ЦИКЛЫ (система объектно-ориентированного программирования Lisp) и более поздние CommonLOOPS
  • Ароматизаторы, построенные в Массачусетскомтехнологическом институте . И его потомки Новые Ароматизаторы (разработанные компанией Symbolics).
  • KR (сокращение от Knowledge Representation)- объектная система на основе ограничений. Разработанная для помощи в написании Garnet. Графической библиотеки для Common Lisp.
  • Knowledge Engineering Environment (KEE) использовала объектную систему UNITS и интегрировала ее с механизмом вывода[63] и системой поддержания истинности (ATMS).

См. также

  1. ^
  2. ^ . Исследование Вольфрама. Извлечено 2016-12-10.
  3. ^ Эдвин Д. Рейли (2003). Основные достижения в области информатики и информационных технологий. Издательская группа ISBN 978-1-57356-521-9.
  4. ^ . Архивирован с оригинала на 2001-07-27. Lisp сохранился. Будучи в использовании в течение примерно четверти века. Среди активных языков программирования только Fortran имел более длительный срок службы.
  5. ^ . Архивирован с оригинала 2014-04-03. Проверено 2014-06-04.
  6. ^ Библиотеки Массачусетского технологического института. лпвп:1721,1/6094. Получено 2020-08-01.
  7. ^ Пол Грэм. . Проверено 2013-03-14.
  8. ^ Чизнолл, Дэвид (2011-01-12). Влиятельные языки программирования, Часть 4: Лисп.
  9. ^ Джонс, Робин; Мейнард, Клайв; Стюарт, Ян (6 декабря 2012). Искусство программирования на лиспе. Springer Science & Business Media. p. 2. ISBN 9781447117193.
  10. ^ Джон Маккарти. . Архивирован с оригинала на 2013-10-04годы . Извлечено в 2006-10-13годах .
  11. ^ Дэвид Кэнфилд Смит. (PDF). Извлечено в 2006-10-13годах .
  12. ^ Джон Маккарти (12 февраля 1979). (PDF).
  13. Согласно тому , что сообщил Пол Грэм в Hackers & Painters, стр. 185, Маккарти сказал: оценку … и я сказал ему: хо-хо. Ты путаешь теорию с практикой. Эта оценка предназначена для чтения. А не для вычислений. Но он пошел вперед и сделал это. То есть он скомпилировал eval в моей статье в машинный код IBM 704, исправив ошибку, а затем рекламировал его как интерпретатор Lisp , что. Безусловно, было так. Таким образом. В тот момент Лисп имел по существу ту же форму. Что и сегодня …
  14. ^ Джон Маккарти. . Проверено 2010-03-14.
  15. ^ Тим Харт и Майк Левин. (PDF). Извлечено 2019-03-18.
  16. ^ b McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I. (1985) [1962]. LISP 1.5 Programmer’s Manual (2-е изд.). MIT Press. ISBN 0-262-13011-4.
  17. На 36-битный размер слова PDP-6/PDP-10 повлияла полезность наличия двух 18-битных указателей Lisp в одном слове. Херли (18 октября 1990). . Группа новостей: alt.folklore.computers. Usenet: 84950@tut.cis.ohio-state.eduПроект PDP-6 стартовал в начале 1963 года как 24-битная машина. Он вырос до 36 бит для LISP — цели дизайна.
  18. ^ Common Lisp: (defun f (x) x)
    Scheme: (define f (lambda (x) x))or (define (f x) x)
  19. ^ McCarthy, J.; Brayton, R.; Edwards, D.; Fox, P.; Hods, L.; Luckham, D.; Maling, K.; Park, D.; Russell, S. (март 1960). (PDF). Бостон, Массачусетс: Группа искусственного интеллекта, Вычислительный центр М. И. Т. и исследовательская лаборатория. Архивировано из оригинала (PDF) на 2010-07-17. Дата обращения 11 мая 2010 года.
  20. ^ Куам, Линн Х.; Диффл, Уитфилд. Stanford LISP 1.6 Manual (PDF).
  21. ^ . 3 марта 1979 года. Архивирован с оригинала 2007-12-14 годов.
  22. ^ Тейтельман. Уоррен (1974). Справочник InterLisp (PDF). Архивирован из оригинала (PDF) на 2006-06-02. 2006-08-19 .
  23. ^ Outils de generation d’interfaces : etat de l’art et classification by H. El Mrabet
  24. ^ ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-349.pdf[постоянная мертвая связь]
  25. ^ Стил, Гай Л., младший . Общий лисп языка (2-е изд.). ISBN 0-13-152414-3.
  26. ^ Кантровиц, Марк; Марголин, Барри (20 февраля 1996 г.). — История: Откуда взялась шепелявость?. Часто задаваемые вопросы: Lisp Frequently Asked Questions 2/7.
  27. ^ . Iso.org. 2007-10-01. Проверено 2013-11-15.
  28. ^ . Iso.org. 2013-10-30. Проверено 2013-11-15.
  29. ^ .
  30. ^ . Архивирован с оригинала 2006-10-04 годов. Извлечено в 2006-10-13годах .
  31. ^ . Faqs.org. Архивировано с оригинала 2013-06-03. Проверено 2013-11-15.
  32. ^ Вайнреб, Дэниел. . Архивирован с оригинала 2012-04-21. Извлечено 4 апреля 2012года .
  33. ^ . Lisp50.org… Проверено 2013-11-15.
  34. ^ Документы: Стандарты: R5RS. schemers.org (2012-01-11). Проверено в 2013-07-17 годах.
  35. ^ . cemerick.com… 24 марта 2009 года. Архивирован с оригинала 17 сентября 2010года . Извлечено 10 ноября 2013года .
  36. ^ Бродер, Эван (8 января 2008). . mitadmissions.org. Извлечено 10 ноября 2013года .
  37. ^ . www.eecs.mit.edu. MIT Electrical Engineering & Computer Science. Извлечено 31 декабря 2018года .
  38. ^ . MIT EECS. Массачусетский технологический институт электротехники и компьютерных наук. Извлечено 31 декабря 2018года .
  39. ^ Глава 1.1.2, История. Стандарт ANSI CL
  40. ^ [1] Clasp-это распространенная реализация Lisp. Которая взаимодействует с C++ и использует LLVM для компиляции JIT в машинный код.
  41. ^ [2]
  42. ^ [3] Архив 2018-06-22 на машине Wayback Общие реализации Lisp: Опрос
  43. ^ [4] Сравнение активно разрабатываемых реализаций Common Lisp
  44. ^ Углубленный взгляд на коллекции Clojure, извлеченные в 2012-06-24 годах
  45. ^ . Извлечено 27 августа 2019года . Clojure-это Lisp. Не ограниченный обратной совместимостью
  46. ^ Script-fu В GIMP 2.4, Извлечено 2009-10-29
  47. ^ librep в Sawfish Wikia. Извлечено 2009-10-29
  48. ^ . IEEE 1178-1990 — Стандарт IEEE для языка программирования Scheme. Извлечено 27 августа 2019года .
  49. ^ . Я изобрел условные выражения в связи с набором шахматных процедур легальных ходов. Которые я написал на ФОРТРАНЕ для IBM 704 в M. I. T. в 1957-58 годах … Статья, определяющая условные выражения и предлагающая их использование в Алголе. Была отправлена в Коммуникацию ACM. Но была произвольно понижена до письма редактору. Потому что она была очень короткой.
  50. ^ . 2003-07-23. Тогда я еще не понимал чудовищную идею лиспа о материальном метаязыке. Но был близок к идеям о расширяемых языках … Вторая фаза этого процесса состояла в том. Чтобы, наконец. Понять LISP. А затем использовать это понимание для создания гораздо более приятных, меньших. Более мощных и более поздних связанных подструктур … ООП для меня означает только обмен сообщениями. Локальное сохранение. Защиту и сокрытие состояния-процесса. А также крайнюю позднюю привязку всех вещей. Это можно сделать как на Smalltalk. Так и на LISP. Возможно, есть и другие системы. В которых это возможно. Но я не знаю о них.
  51. ^ Либерман, Генри; Хьюитт, Карл (июнь 1983), «Сборщик мусора в реальном времени на основе времени жизни объектов», Communications of the ACM, 26 (6): 419-429, CiteSeerX 10.1.1.4.8633, doi:10.1145/358141.358147, hdl:1721.1/6335, S2CID 14161480
  52. ^ Эдсгер У. Дейкстра (1972), Скромный программист (EWD 340) (лекция ACM Turing Award).
  53. ^ .
  54. ^ . Извлечено в 2006-10-13годах .
  55. ^ Sebesta, Robert W. (2012). 2.4 Функциональное Программирование: LISPПонятия языков программирования (печать) (10-е изд.). Бостон, Массачусетс, США: Аддисон-Уэсли. ISBN 978-0-13-139531-2.
  56. ^ NB: так называемый Другой вид-это Обычно это представляется с помощью #n=(…) для представления целевой ячейки cons. Которая будет иметь несколько ссылок. А #n# используется для ссылки на эту ячейку cons. Например, (#1=(a b) . #1#) обычно печатается как ((a b) a b) (без включения круговой печати структуры). Но делает повторное использование ячейки cons ясным. #1=(a . #1#) обычно не может быть напечатан. Так как он круглый. Хотя иногда отображается (a…). CDR ячейки cons. Определяемой #1= is сама по себе.
  57. ^ . Cs.washington.edu. 1999-02-22. Проверено 2013-11-15.
  58. ^ Quasiquotation in Lisp Archived 2013-06-03 at the Wayback Machine, Alan Bawden
  59. ^ Время оценки — Common Lisp Extensions. Gnu.org. Проверено в 2013-07-17 годах.
  60. ^ 3.2.2.3 Семантические ограничения в гиперспеке Common Lisp
  61. ^ 4.3. Абстракция управления (Рекурсия против рекурсии) Итерация) в Учебнике по хорошему стилю программирования на Лиспе Кента Питмана и Питера Норвига, август 1993 года.
  62. ^ pg 17 of Bobrow 1986
  63. ^ Veitch, p 108, 1988

Дальнейшее чтение

Внешние ссылки

История
Ассоциации и собрания
Книги и учебные пособия
Интервью
Ресурсы