Jump to content

Лисп (язык программирования)

(Перенаправлено из Lisp 1.5 )
Лисп
Парадигма Мультипарадигма : функциональная , процедурная , рефлексивная , мета.
Разработано Джон Маккарти
Разработчик Стив Рассел , Тимоти П. Харт, Майк Левин
Впервые появился 1960 год ; 64 года назад ( 1960 )
Дисциплина набора текста Динамичный , сильный
Диалекты
Под влиянием
Язык обработки информации (IPL)
Под влиянием

Лисп (исторически LISP , аббревиатура от «обработка списков») — это семейство языков программирования с долгой историей и характерной , полностью заключенной в круглые скобки префиксной нотацией . [ 3 ] Первоначально разработанный в конце 1950-х годов, это второй по возрасту язык программирования высокого уровня, до сих пор широко используемый, после Фортрана . [ 4 ] [ 5 ] Лисп изменился с первых дней своего существования, и множество диалектов на протяжении его истории существовало . Сегодня наиболее известными диалектами Lisp общего назначения являются Common Lisp , Scheme , Racket и Clojure . [ 6 ] [ 7 ] [ 8 ]

Первоначально Лисп был создан как практическая математическая система обозначений для компьютерных программ под влиянием (но изначально не производного от) [ 9 ] обозначение Алонзо Чёрча лямбда-исчисления . Он быстро стал излюбленным языком программирования для исследований искусственного интеллекта (ИИ). [ 10 ] Как один из самых ранних языков программирования, Лисп стал пионером многих идей в информатике , включая древовидные структуры данных , автоматическое управление хранилищем , динамическую типизацию , условные выражения , функции высшего порядка , рекурсию , автономный компилятор . [ 11 ] и цикл чтения-оценки-печати . [ 12 ]

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

Взаимозаменяемость кода и данных придает Lisp мгновенно узнаваемый синтаксис. Весь программный код записывается в виде s-выражений или списков в круглых скобках. Вызов функции или синтаксическая форма записывается в виде списка, в котором сначала имя функции или оператора, а затем аргументы; например, функция f который принимает три аргумента, будет называться как (f arg1 arg2 arg3).

Джон Маккарти начал разработку Lisp в 1958 году, когда работал в Массачусетском технологическом институте (MIT). Маккарти опубликовал свой дизайн в статье в журнале Communications of ACM в апреле 1960 года под названием «Рекурсивные функции символических выражений и их машинное вычисление, часть I». [ 14 ] Он показал, что с помощью нескольких простых операторов и обозначений анонимных функций, заимствованных у Чёрча, можно построить полный по Тьюрингу язык алгоритмов.

Язык обработки информации был первым языком искусственного интеллекта , появившимся в 1955 или 1956 году, и уже включал в себя многие концепции, такие как обработка списков и рекурсия, которые стали использоваться в Лиспе.

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

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

По мнению Маккарти [ 17 ]

Стив Рассел сказал, смотри, почему бы мне не запрограммировать этот eval ... и я ему сказал: хо-хо, ты путаешь теорию с практикой, этот eval предназначен для чтения, а не для вычислений. Но он пошел дальше и сделал это. То есть он скомпилировал eval . из моей статьи в IBM 704 машинный код , исправив ошибки , а затем рекламировал это как интерпретатор Лиспа, что, безусловно, и было Итак, на тот момент Лисп по сути имел ту форму, которую он имеет сегодня...

Результатом стал работающий интерпретатор Лиспа , который можно было использовать для запуска программ на Лиспе или, точнее, «оценки выражений Лиспа».

Два макроса языка ассемблера для IBM 704 стали примитивными операциями для декомпозиции списков: car ( Содержимое адресной части номера регистра) и cdr ( Содержимое декрементной части номера регистра), [ 18 ] где «регистр» относится к регистрам (ЦП) компьютера центрального процессора . Диалекты Lisp до сих пор используют car и cdr ( / k ɑːr / и / ˈ k ʊ d ər / ) для операций, которые возвращают первый элемент в списке и остальную часть списка соответственно.

Первый полноценный компилятор Lisp, написанный на Lisp, был реализован в 1962 году Тимом Хартом и Майком Левином в Массачусетском технологическом институте. Его можно было скомпилировать, просто заставив существующий интерпретатор LISP интерпретировать код компилятора, создавая выходные данные машинного кода, которые можно было выполнить со скоростью 40 секунд. -кратное увеличение скорости по сравнению со скоростью переводчика. [ 19 ] Этот компилятор представил модель инкрементной компиляции Lisp , в которой скомпилированные и интерпретируемые функции могут свободно смешиваться. Язык, использованный в записке Харта и Левина, гораздо ближе к современному стилю Лиспа, чем более ранний код Маккарти.

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

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

Хронология

[ редактировать ]
1958 1960 1965 1970 1975 1980 1985 1990 1995 2000 2005 2010 2015 2020
ЛИСП 1, 1.5, ЛИСП 2 (заброшенный)
 Маклисп
 Интерлисп
 леев
 Лисп-машина Лисп
 Схема Р5РС Р6РС R7RS маленький
 НОЛЬ
 ЗИЛ (язык реализации Zork)
 Франц Лисп
 Общий Лисп стандарт ANSI
 Лисп
 Схема СО
 XLISP
 Т
 На схеме
 Эмакс Лисп
 АвтоЛИСП
 ПикоЛисп
 Гамбит
 EuLisp
 ИСЛИСП
 ОпенЛисп
 Схема PLT  Ракетка
 новыйЛИСП
 GNU Коварство
 Визуальный ЛИСП
 Кложур
 Дуга
 ЛФЭ
 Он
 Хиалисп

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

[ редактировать ]

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

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

[ редактировать ]

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

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

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

[ редактировать ]
Машина Lisp в музее Массачусетского технологического института
4.3BSD от Университета Висконсина , отображающая страницу справочную Franz Lisp.

2000 по настоящее время

[ редактировать ]

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

Многие новые программисты на Лиспе были вдохновлены такими авторами, как Пол Грэм и Эрик С. Рэймонд, на разработку языка, который другие считали устаревшим. Программисты New Lisp часто описывают этот язык как поучительный опыт и утверждают, что он значительно более продуктивен, чем другие языки. [ 36 ] Этот рост осведомленности можно противопоставить « зиме ИИ » и кратковременному успеху Лиспа в середине 1990-х годов. [ 37 ]

По состоянию на 2010 год , существовало одиннадцать активно поддерживаемых реализаций Common Lisp. [ 38 ]

Сообщество открытого исходного кода создало новую инфраструктуру поддержки: CLiki — это вики, которая собирает информацию, связанную с Common Lisp, в каталоге Common Lisp перечислены ресурсы, #lisp — популярный IRC-канал, позволяющий делиться и комментировать фрагменты кода (при поддержке lispaste , IRC -бот, написанный на Lisp), Planet Lisp [ 39 ] собирает содержимое различных блогов, посвященных Lisp, на LispForum. [ 40 ] пользователи обсуждают темы Lisp, Lispjobs [ 41 ] — это сервис для объявления предложений о работе, а также существует еженедельная служба новостей Weekly Lisp News . Common-lisp.net — это хостинг для проектов Common Lisp с открытым исходным кодом. Квиклисп [ 42 ] является менеджером библиотеки Common Lisp.

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

Сообщество Scheme активно поддерживает более двадцати реализаций . Несколько важных новых реализаций (Chicken, Gambit, Gauche, Ikarus, Larceny, Ypsilon) были разработаны в 2000-х (десятилетии). Пересмотренный 5 Отчет об алгоритмической языковой схеме [ 44 ] Стандарт Scheme получил широкое признание в сообществе Scheme. было В ходе процесса запросов на реализацию схемы создано множество квазистандартных библиотек и расширений для схемы. Сообщества пользователей отдельных реализаций Scheme продолжают расти. Новый процесс стандартизации языка был начат в 2003 году и привел к появлению R 6 Стандарт RS Scheme в 2007 году. Академическое использование Scheme для преподавания информатики, похоже, несколько сократилось. Некоторые университеты больше не используют Scheme на вводных курсах по информатике; [ 45 ] [ 46 ] MIT теперь использует Python вместо Scheme в своей программе бакалавриата по информатике и в массовом открытом онлайн-курсе MITx. [ 47 ] [ 48 ]

Появилось несколько новых диалектов Lisp: Arc , Hy , Nu , Liskell и LFE (Lisp Flavored Erlang). Парсер Julia реализован на Femtolisp, диалекте Scheme (Julia вдохновлена ​​Scheme, который, в свою очередь, является диалектом Lisp).

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

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

[ редактировать ]

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

Common Lisp является преемником Maclisp . Основное влияние оказали Lisp Machine Lisp , Maclisp, NIL , S-1 Lisp , Spice Lisp и Scheme. [ 49 ] Он обладает многими функциями Lisp Machine Lisp (большого диалекта Lisp, используемого для программирования Lisp Machines ), но был разработан для эффективной реализации на любом персональном компьютере или рабочей станции. Common Lisp — это язык программирования общего назначения, поэтому он имеет большой языковой стандарт, включающий множество встроенных типов данных, функций, макросов и других элементов языка, а также объектную систему ( Common Lisp Object System ). Common Lisp также позаимствовал некоторые функции из Scheme, такие как лексическая область видимости и лексические замыкания . Доступны общие реализации Lisp для различных платформ, таких как LLVM , [ 50 ] виртуальная машина Java , [ 51 ] x86-64, PowerPC, Alpha, ARM, Motorola 68000 и MIPS, [ 52 ] и операционные системы, такие как Windows, macOS, Linux, Solaris, FreeBSD, NetBSD, OpenBSD, Dragonfly BSD и Heroku. [ 53 ]

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

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

Кроме того, диалекты Lisp используются в качестве языков сценариев во многих приложениях, наиболее известными из которых являются Emacs Lisp в редакторе Emacs , AutoLISP и более поздний Visual Lisp в AutoCAD , Nyquist в Audacity и Scheme в LilyPond . Потенциально небольшой размер полезного интерпретатора Scheme делает его особенно популярным для встроенных сценариев. Примеры включают SIOD и TinyScheme , оба из которых были успешно встроены в процессор изображений GIMP под общим названием «Script-fu». [ 56 ] LIBREP, интерпретатор Лиспа, разработанный Джоном Харпером, первоначально основанный на языке Emacs Lisp , был встроен в Sawfish оконный менеджер . [ 57 ]

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

[ редактировать ]

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

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

[ редактировать ]

Пол Грэм выделяет девять важных аспектов Лиспа, которые отличают его от существующих языков, таких как Фортран : [ 59 ]

Лисп был первым языком, в котором структура программного кода точно и непосредственно представлена ​​в стандартной структуре данных — качество, гораздо позже получившее название « гомоиконичность ». Таким образом, функциями Lisp можно манипулировать, изменять или даже создавать внутри программы Lisp без манипуляций на более низком уровне. Обычно это считается одним из основных преимуществ языка с точки зрения его выразительной силы и делает язык подходящим для синтаксических макросов и метациклических вычислений .

Условное выражение, использующее синтаксис if-then-else, было изобретено Маккарти для шахматной программы, написанной на Фортране . Он предложил включить его в АЛГОЛ , но он не стал частью спецификации Алгола 58 . Для Лиспа Маккарти использовал более общую структуру cond . [ 60 ] Алгол 60 взял на вооружение «если-то-иначе» и популяризировал его.

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

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

Эдсгер В. Дейкстра в своей лекции на Премии Тьюринга 1972 года сказал:

Имея в своей основе несколько очень простых принципов, он [LISP] продемонстрировал замечательную стабильность. Кроме того, LISP стал основой для значительного числа наших самых сложных компьютерных приложений. LISP в шутку называют «самым разумным способом неправильного использования компьютера». Я думаю, что это описание — великий комплимент, поскольку оно передает всю суть освобождения: оно помогло ряду наших самых одаренных собратьев задуматься о ранее невозможных мыслях. [ 63 ]

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

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

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

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

[ редактировать ]

Лисп — язык, ориентированный на выражения . не делается различий В отличие от большинства других языков, между «выражениями» и «утверждениями» ; [ сомнительно обсудить ] весь код и данные записываются в виде выражений. Когда выражение оценивается , оно создает значение (возможно, несколько значений), которое затем можно внедрить в другие выражения. Каждое значение может быть любым типом данных.

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

Использование круглых скобок — самое очевидное отличие Лиспа от других семейств языков программирования. В результате студенты уже давно дали Лиспу прозвища, такие как « Потерянные в глупых скобках » или «Множество раздражающих лишних скобок» . [ 65 ] Однако синтаксис S-выражений также отвечает за большую часть возможностей Лиспа: синтаксис прост и последователен, что облегчает манипуляции с компьютером. Однако синтаксис Лиспа не ограничивается традиционной записью в круглых скобках. Его можно расширить, включив в него альтернативные обозначения. Например, XMLisp — это расширение Common Lisp, которое использует протокол метаобъектов для интеграции S-выражений с расширяемым языком разметки ( XML ).

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

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

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

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

 (list 1 2 (quote foo))

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

 (list 1 2 (list 3 4))

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

Операторы

[ редактировать ]

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

 (+ 1 2 3 4)

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

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

 (incf x)

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

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

 (if nil
     (list 1 2 "foo")
     (list 3 4 "bar"))

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

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

 (or (and "zero" nil "never") "James" 'task 'time)

будет оцениваться как «Джеймс».

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

[ редактировать ]

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

 (lambda (arg) (+ arg 1))

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

 ((lambda (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.

Существенная разница между атомами и списками заключалась в том, что атомы были неизменяемыми и уникальными. Два атома, появившиеся в разных местах исходного кода, но написанные совершенно одинаково, представляли один и тот же объект. [ нужна ссылка ] тогда как каждый список представлял собой отдельный объект, который можно было изменять независимо от других списков и отличать от других списков операторами сравнения.

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

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

[ редактировать ]
Диаграмма в виде прямоугольника и указателя для списка (42 69 613)

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

Из множества структур данных, которые можно построить из ячеек cons, одна из самых простых называется правильным списком . Правильный список — это либо специальный nil (пустой список) или символ «минус», в котором car указывает на данные (которые могут быть другой структурой cons, например списком), а cdr указывает на другой правильный список.

Если данный cons считается главой связанного списка, то его car указывает на первый элемент списка, а его cdr указывает на остальную часть списка. По этой причине car и cdr функции еще называют first и rest когда речь идет о консах, которые являются частью связанного списка (а не, скажем, дерева).

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

Поскольку константы и списки настолько универсальны в системах Lisp, распространено заблуждение, что они являются единственными структурами данных Lisp. Фактически, все Лиспы, кроме самых упрощенных, имеют другие структуры данных, такие как векторы ( массивы ), хеш-таблицы , структуры и т. д.

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

[ редактировать ]

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

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

[ редактировать ]

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

 (list 1 2 'a 3)
 ;Output: (1 2 a 3)
 (list 1 '(2 3) 4)
 ;Output: (1 (2 3) 4)

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

 (cons 1 '(2 3))
 ;Output: (1 2 3)
 (cons '(1 2) '(3 4))
 ;Output: ((1 2) 3 4)

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

 (append '(1 2) '(3 4))
 ;Output: (1 2 3 4)
 (append '(1 2 3) '() '(a) '(5 6))
 ;Output: (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) имеет одинаковую структуру в обоих списках. Это не копия; ячейки минусов, указывающие на b и c находятся в одних и тех же ячейках памяти для обоих списков.

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

 (setf (third foo) 'goose)

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

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

Формы самооценки и цитирование

[ редактировать ]

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

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

И Common Lisp, и Scheme также поддерживают оператор обратной кавычки (называемый в Scheme квазицитой ), вводимый с помощью ` характер ( серьезный акцент ). Это почти то же самое, что и простая кавычка, за исключением того, что она позволяет оценивать выражения и интерполировать их значения в список кавычек с запятой. , снять кавычки и запятую ,@ операторы сращивания . Если переменная snue имеет значение (bar baz) затем `(foo ,snue) оценивается как (foo (bar baz)), пока `(foo ,@snue) оценивается как (foo bar baz). Обратная кавычка чаще всего используется при определении расширений макросов. [ 68 ] [ 69 ]

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

(defun should-be-constant ()
  '(one two three))

(let ((stuff (should-be-constant)))
  (setf (third stuff) 'bizarre))   ; bad!

(should-be-constant)   ; returns (one two bizarre)

Изменение формы в кавычках, как это, обычно считается плохим стилем и определяется ANSI Common Lisp как ошибочное (приводящее к «неопределённому» поведению в скомпилированных файлах, поскольку компилятор файлов может объединить похожие константы, поместить их в память, защищенную от записи, и и т. д.).

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

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

[ редактировать ]

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

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

[ редактировать ]

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

Лисп использует это для реализации очень мощной системы макросов. Как и другие макроязыки, например тот, который определяется препроцессором C (препроцессор макросов для языков программирования C , Objective-C и C++ ), макрос возвращает код, который затем можно скомпилировать. Однако, в отличие от макросов препроцессора C, макросы являются функциями Lisp и поэтому могут использовать всю мощь Lisp.

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

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

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

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

Оценка и цикл чтения-оценки-печати

[ редактировать ]

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

Основная работа REPL заключается в следующем. Это упрощенное описание, в котором опущены многие элементы настоящего Лиспа, такие как кавычки и макросы.

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

А foo будет читаться как один символ. 123 будет читаться как число сто двадцать три. "123" будет читаться как строка «123».

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

Символ foo оценивается как значение символа foo. Такие данные, как строка «123», оцениваются как одна и та же строка. Список (quote (1 2 3)) возвращает список (1 2 3).

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

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

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

Lisp обычно оценивается с нетерпением . В Common Lisp аргументы оцениваются в аппликативном порядке («самый левый внутренний»), тогда как в Scheme порядок аргументов не определен, что оставляет место для оптимизации компилятором.

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

[ редактировать ]

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

Программисты, использующие диалект Scheme, часто выражают циклы, используя хвостовую рекурсию . Общность Scheme в академической информатике привела некоторых студентов к мысли, что хвостовая рекурсия — единственный или наиболее распространенный способ написания итераций в Lisp, но это неверно. Все часто встречающиеся диалекты Лиспа имеют конструкции итерации в императивном стиле, начиная с Scheme. do цикл к Common Lisp комплексу loop выражения. Более того, ключевой вопрос, который делает это объективным, а не субъективным вопросом, заключается в том, что Scheme предъявляет особые требования к обработке хвостовых вызовов , и, таким образом, причина, по которой использование хвостовой рекурсии обычно поощряется для Scheme, заключается в том, что эта практика явно поддерживается определение языка. Напротив, ANSI Common Lisp не требует [ 71 ] оптимизация, обычно называемая устранением хвостовых вызовов. Таким образом, тот факт, что стиль хвостовой рекурсии как случайная замена использованию более традиционных итерационных конструкций (таких как do, dolist или loop) обескуражен [ 72 ] в Common Lisp — это не просто вопрос стилистических предпочтений, но потенциально вопрос эффективности (поскольку очевидный хвостовой вызов в Common Lisp может не компилироваться как простой переход ) и корректности программы (поскольку хвостовая рекурсия может увеличить использование стека в Common Lisp, рискуя переполнение стека ).

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

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

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

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

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

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

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

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

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

Базовая программа « Привет, Мир! »:

(print "Hello, World!")

Синтаксис Лиспа естественным образом поддается рекурсии. Математические проблемы, такие как перечисление рекурсивно определенных множеств, легко выразить в этих обозначениях. числа Например, чтобы вычислить факториал :

(defun factorial (n)
    (if (zerop n) 1
        (* n (factorial (1- n)))))

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

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

Сравните приведенные выше примеры с итеративной версией, использующей Common Lisp . loop макрос:

(defun factorial (n)
    (loop for i from 1 to n
        for fac = 1 then (* fac i)
        finally (return fac)))

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

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

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

[ редактировать ]

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

Операционные системы

[ редактировать ]

Некоторые операционные системы , включая системы на основе языка , основаны на Lisp (используют функции Lisp, соглашения, методы, структуры данных и т. д.) или написаны на Lisp. [ 75 ] включая:

Genera , переименованная в Open Genera, [ 76 ] от Символики ; Medley, написанная на Interlisp, первоначально семействе графических операционных систем, работавших на Xerox более поздних Star рабочих станциях ; [ 77 ] [ 78 ] Сваха; [ 79 ] Промежуточный; [ 80 ] [ 81 ] КрисаЛисп, [ 82 ] от разработчиков TAOS компании Tao Systems. [ 83 ] , а также Штукатурка

См. также

[ редактировать ]
  1. ^ "Введение" . Руководство Юлии . Прочтите Документы. Архивировано из оригинала 8 апреля 2016 г. Проверено 10 декабря 2016 г.
  2. ^ «Вопросы и ответы по языку Wolfram» . Вольфрам Исследования . Проверено 10 декабря 2016 г.
  3. ^ Эдвин Д. Рейли (2003). Вехи развития информатики и информационных технологий . Издательская группа Гринвуд. стр. 156–157. ISBN  978-1-57356-521-9 .
  4. ^ «СИКП: Предисловие» . Архивировано из оригинала 27 июля 2001 г. Lisp выжил, его используют уже около четверти века. Среди активных языков программирования только Фортран прожил более долгую жизнь.
  5. ^ «Выводы» . Архивировано из оригинала 3 апреля 2014 г. Проверено 4 июня 2014 г.
  6. ^ Стил, Гай Л. (1990). Common Lisp: язык (2-е изд.). Бедфорд, Массачусетс: Digital Press. ISBN  1-55558-041-6 . OCLC   20631879 .
  7. ^ Феллейзен, Матиас; Финдлер, Роберт; Флэтт, Мэтью; Кришнамурти, Шрирам; Верзеллий, Илий; Маккарти, Джей; Тобин-Хохштадт, Сэм (2015). « Манифест рэкета» ( PDF) .
  8. ^ «Clojure — Отличия от других Лиспов» . Clojure.org . Проверено 27 октября 2022 г.
  9. ^ Стил, Гай Льюис; Сассман, Джеральд Джей (май 1978 г.). «Искусство переводчика, или Комплекс модульности (Части нулевая, первая и вторая), Часть нулевая, ч. 4» . Библиотеки Массачусетского технологического института. hdl : 1721.1/6094 . Проверено 1 августа 2020 г.
  10. ^ Хофштадтер, Дуглас Р. (1999) [1979], Гёдель, Эшер, Бах: Вечная золотая коса (издание к двадцатой годовщине) , Basic Books, стр. 292, ISBN  0-465-02656-7 . Одним из наиболее важных и увлекательных компьютерных языков является LISP (расшифровывается как «Обработка списков»), который был изобретен Джоном Маккарти примерно в то же время, когда был изобретен Алгол Впоследствии LISP пользовался большой популярностью среди специалистов по искусственному интеллекту.
  11. ^ Пол Грэм. «Месть ботанов» . Проверено 14 марта 2013 г.
  12. ^ Чисналл, Дэвид (12 января 2011 г.). Влиятельные языки программирования, часть 4: Лисп .
  13. ^ Джонс, Робин; Мейнард, Клайв; Стюарт, Ян (6 декабря 2012 г.). Искусство программирования на Лиспе . Springer Science & Business Media. п. 2. ISBN  9781447117193 .
  14. ^ Маккарти, Джон. «Рекурсивные функции символьных выражений и их машинное вычисление, часть I» . Архивировано из оригинала 4 октября 2013 г. Проверено 13 октября 2006 г.
  15. ^ Смит, Дэвид Кэнфилд. Руководство пользователя MLISP (PDF) . Проверено 13 октября 2006 г.
  16. ^ Маккарти, Джон (12 февраля 1979 г.). «История Лиспа: Лаборатория искусственного интеллекта» (PDF) .
  17. ^ Стоян, Герберт (6 августа 1984 г.). Ранняя история LISP (1956–1959) . LFP '84: Материалы симпозиума ACM 1984 года по LISP и функциональному программированию. Ассоциация вычислительной техники . п. 307. дои : 10.1145/800055.802047 .
  18. ^ Маккарти, Джон. «Предыстория LISP — лето 1956 г. — лето 1958 г.» . Проверено 14 марта 2010 г.
  19. ^ Харт, Тим; Левин, Майк. «AI Memo 39-Новый компилятор» (PDF) . Архивировано из оригинала (PDF) 13 декабря 2020 г. Проверено 18 марта 2019 г.
  20. ^ Маккарти, Джон; Абрахамс, Пол В.; Эдвардс, Дэниел Дж.; Харт, Тимоти П.; Левин, Майкл И. (1985) [1962]. Руководство программиста LISP 1.5 (PDF) . 15-е издание (2-е изд.). п. Предисловие.
  21. ^ На 36-битный размер слова PDP-6 / PDP-10 повлияла полезность наличия двух 18-битных указателей Lisp в одном слове. Питер Дж. Херли (18 октября 1990 г.). «История ТОПС или жизнь в быстрых АС» . Группа новостей : alt.folklore.computers . Usenet:   [электронная почта защищена] . Проект PDP-6 стартовал в начале 1963 года как 24-битная машина. Для LISP он вырос до 36 бит, что было целью разработки.
  22. ^ Стил, Гай Л.; Габриэль, Ричард П. (январь 1996 г.), Бергин, Томас Дж.; Гибсон, Ричард Г. (ред.), «Эволюция Лиспа» , История языков программирования ---II , Нью-Йорк, штат Нью-Йорк, США: ACM, стр. 233–330, doi : 10.1145/234286.1057818 , ISBN  978-0-201-89502-5 , получено 25 июля 2022 г.
  23. ^ Общий Лисп: (defun f (x) x)
    Схема: (define f (lambda (x) x)) или (define (f x) x)
  24. ^ Маккарти, Дж .; Брайтон, Р.; Эдвардс, Д.; Фокс, П .; Ходс, Л. ; Лакхэм, Д .; Малинг, К.; Парк, Д. ; Рассел, С. (март 1960 г.). Руководство программиста LISP I (PDF) . Бостон: Группа искусственного интеллекта, Вычислительный центр и исследовательская лаборатория Массачусетского технологического института. Архивировано из оригинала (PDF) 17 июля 2010 г. По состоянию на 11 мая 2010 г.
  25. ^ Маккарти, Джон; Абрахамс, Пол В.; Эдвардс, Дэниел Дж.; Харт, Тимоти П.; Левин, Майкл И. (1985) [1962]. Руководство программиста LISP 1.5 (PDF) (2-е изд.). МТИ Пресс . ISBN  0-262-13011-4 .
  26. ^ Куам, Линн Х.; Диффл, Уитфилд. Руководство по Стэнфордскому LISP 1.6 (PDF) .
  27. ^ «Справочное руководство по Maclisp» . 3 марта 1979 г. Архивировано из оригинала 14 декабря 2007 г.
  28. ^ Тейтельман, Уоррен (1974). Справочное руководство InterLisp (PDF) . Архивировано из оригинала (PDF) 2 июня 2006 г. Проверено 19 августа 2006 г.
  29. ^ Инструменты создания интерфейса: современное состояние и классификация Х. Эль Мрабета.
  30. ^ Джеральд Джей Сассман и Гай Льюис Стил-младший (декабрь 1975 г.). «Схема: интерпретатор расширенного лямбда-исчисления» (PDF) . Лаборатория искусственного интеллекта Массачусетского технологического института . АИМ-349 . Проверено 23 декабря 2021 г.
  31. ^ Стил, Гай Л. младший (1990). "Цель" . Common Lisp the Language (2-е изд.). Цифровая пресса. ISBN  0-13-152414-3 .
  32. ^ Кантровитц, Марк; Марголин, Барри (20 февраля 1996 г.). «История: откуда появился Лисп?» . FAQ: Часто задаваемые вопросы по Lisp 2/7 .
  33. ^ «ИСО/МЭК 13816:1997» . Исо.орг. 01.10.2007 . Проверено 15 ноября 2013 г.
  34. ^ «ИСО/МЭК 13816:2007» . Исо.орг. 30 октября 2013 г. Проверено 15 ноября 2013 г.
  35. ^ «Устав X3J13» .
  36. ^ «Опрос на пути к Lisp» . Архивировано из оригинала 4 октября 2006 г. Проверено 13 октября 2006 г.
  37. ^ «Тенденции будущего» . Faqs.org. Архивировано из оригинала 3 июня 2013 г. Проверено 15 ноября 2013 г.
  38. ^ Вайнреб, Дэниел. «Распространенные реализации Lisp: обзор» . Архивировано из оригинала 21 апреля 2012 г. Проверено 4 апреля 2012 г.
  39. ^ «Планета Лисп» . Проверено 12 октября 2023 г.
  40. ^ «ЛиспФорум» . Проверено 12 октября 2023 г.
  41. ^ «Лиспджобс» . Проверено 12 октября 2023 г.
  42. ^ «Квиклисп» . Проверено 12 октября 2023 г.
  43. ^ «LISP50@OOPSLA» . Lisp50.org . Проверено 15 ноября 2013 г.
  44. ^ Документы: Стандарты: R5RS . Schemers.org (11 января 2012 г.). Проверено 17 июля 2013 г.
  45. ^ «Почему MIT теперь использует Python вместо схемы для своей программы бакалавриата по информатике» . cemerick.com . 24 марта 2009 года. Архивировано из оригинала 17 сентября 2010 года . Проверено 10 ноября 2013 г.
  46. ^ Бродер, Эван (8 января 2008 г.). «Конец эпохи» . mitadmissions.org . Проверено 10 ноября 2013 г.
  47. ^ «Программы бакалавриата MIT EECS» . www.eecs.mit.edu . Массачусетский технологический институт электротехники и информатики . Проверено 31 декабря 2018 г.
  48. ^ «На вводный курс Python MITx записалось 1,2 миллиона человек» . MIT EECS . Массачусетский технологический институт электротехники и информатики . Проверено 31 декабря 2018 г.
  49. ^ Глава 1.1.2, История, стандарт ANSI CL
  50. ^ [1] Clasp — это реализация Common Lisp, которая взаимодействует с C++ и использует LLVM для JIT- компиляции в машинный код.
  51. ^ [2] «Armed Bear Common Lisp (ABCL) — это полная реализация языка Common Lisp, включающая как интерпретатор, так и компилятор, работающий в JVM»
  52. ^ [3] Архивировано 22 июня 2018 г. на сайте Wayback Machine Common Lisp Implements: опрос.
  53. ^ [4] Сравнение активно разрабатываемых реализаций Common Lisp.
  54. ^ Углубленный взгляд на коллекции Clojure , дата обращения 24 июня 2012 г.
  55. ^ «Кложур рациональный» . Проверено 27 августа 2019 г. Clojure — это Lisp, не ограниченный обратной совместимостью.
  56. ^ Script-fu в GIMP 2.4 , дата обращения 29 октября 2009 г.
  57. ^ librep в Sawfish Wikia, получено 29 октября 2009 г.
  58. ^ «Схема IEEE» . IEEE 1178-1990 — Стандарт IEEE для языка программирования Scheme . Проверено 27 августа 2019 г.
  59. ^ Пол Грэм (май 2002 г.). «Что отличало Лисп» .
  60. ^ «Предыстория LISP — лето 1956 г. — лето 1958 г.» . Я изобрел условные выражения в связи с набором правильных шахматных ходов, которые я написал на ФОРТРАНЕ для IBM 704 в Массачусетском технологическом институте в 1957–58 годах ... Документ, определяющий условные выражения и предлагающий их использование в Алголе, был отправлен в отдел сообщений ACM. но был произвольно понижен в должности до письма в редакцию, потому что оно было очень коротким.
  61. ^ «Значение« объектно-ориентированного программирования »по мнению доктора Алана Кея» . 2003-07-23. Тогда я не понимал чудовищной идеи LISP о материальном метаязыке, но был в некотором роде близок к идеям о расширяемых языках... Второй этап этого заключался в том, чтобы наконец понять LISP, а затем использовать это понимание, чтобы сделать намного лучше, меньше и больше. мощные и более поздние связанные подструктуры... ООП для меня означает только обмен сообщениями, локальное сохранение и защиту, а также сокрытие состояний-процессов и крайне позднее связывание всех вещей. Это можно сделать в Smalltalk и LISP. Возможно, есть и другие системы, в которых это возможно, но я о них не знаю.
  62. ^ Либерман, Генри; Хьюитт, Карл (июнь 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
  63. ^ Эдсгер В. Дейкстра (1972), Скромный программист (EWD 340) (лекция на премию ACM Turing).
  64. ^ «Взгляд на Clojure и возрождение Lisp» .
  65. ^ «Жаргонный файл — Лисп» . Проверено 13 октября 2006 г.
  66. ^ Себеста, Роберт В. (2012). " "2.4 Функциональное программирование: LISP";"6.9 Типы списков";"15.4 Первый язык функционального программирования: LISP" ". Концепции языков программирования (печать) (10-е изд.). Бостон, Массачусетс, США: Аддисон-Уэсли. стр. 47–52, 281–284, 677–680. ISBN  978-0-13-139531-2 .
  67. ^ Примечание: так называемый «пунктирный список» — это лишь один из видов «неправильного списка». Другой вид — это «круговой список», в котором минус-ячейки образуют цикл. Обычно это представляется с помощью #n=(...) для обозначения целевой ячейки cons, которая будет иметь несколько ссылок, а #n# используется для ссылки на эту cons. Например, (#1=(ab) . #1#) обычно печатается как ((ab) ab) (без включения печати круговой структуры), но делает очевидным повторное использование ячейки cons. #1=(a . #1#) обычно не может быть напечатан, поскольку он имеет круглую форму, хотя (a...) иногда отображается, CDR ячейки cons, определенной #1=, является самим собой.
  68. ^ «CSE 341: Схема: цитата, квазицитата и метапрограммирование» . Cs.washington.edu. 22 февраля 1999 г. Проверено 15 ноября 2013 г.
  69. ^ Квазицитата в Lisp. Архивировано 3 июня 2013 г. в Wayback Machine , Алан Боуден.
  70. ^ Время оценки — Общие расширения Lisp . Гну.орг. Проверено 17 июля 2013 г.
  71. ^ 3.2.2.3 Семантические ограничения в Common Lisp HyperSpec
  72. ^ 4.3. Абстракция управления (рекурсия и итерация) в учебнике по хорошему стилю программирования на Lisp Кента Питмана и Питера Норвига , август 1993 г.
  73. ^ стр. 17 Боброу, 1986 г.
  74. ^ Вейч, стр. 108, 1988 г.
  75. ^ Провен, Лиам (29 марта 2022 г.). «Дикий мир операционных систем, отличных от C» . Регистр . Проверено 4 апреля 2024 г.
  76. ^ «Символика Open Genera 2.0» . GitHub Интернет-архив . 7 января 2020 г. Проверено 2 февраля 2022 г.
  77. ^ «Проект Interlisp.org» . Interlisp.org . 15 марта 2022 г. Проверено 2 февраля 2022 г.
  78. ^ «Интерлисп Медли» . Гитхаб . Март 2022 года . Проверено 2 февраля 2022 г.
  79. ^ Фрогги (1 августа 2021 г.). «Меццано» . Гитхаб . Проверено 2 февраля 2022 г.
  80. ^ Хартманн, Лукас Ф. (10 сентября 2015 г.). «Промежуточный» . Промежуточная ОС . Проверено 2 февраля 2022 г.
  81. ^ Хартманн, Лукас Ф. (11 июня 2021 г.). «Промежуточный» . Гитхаб . Проверено 2 февраля 2022 г.
  82. ^ Хинсли, Крис (23 февраля 2022 г.). «ХрисаЛисп» . Гитхаб . Проверено 2 февраля 2022 г.
  83. ^ Смит, Тони (21 августа 2013 г.). «Пионер микротехнологий Великобритании Крис Шелтон: разум, стоящий за Nascom 1» . Регистр . Проверено 2 февраля 2022 г.

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

[ редактировать ]
[ редактировать ]
История
Ассоциации и встречи
Книги и учебные пособия
Интервью
Ресурсы
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 63eaf00716837b66e9de13f7757bb87b__1722361620
URL1:https://arc.ask3.ru/arc/aa/63/7b/63eaf00716837b66e9de13f7757bb87b.html
Заголовок, (Title) документа по адресу, URL1:
Lisp (programming language) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)