Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

Лисп был первоначально создан в качестве практической математической нотации для компьютерных программ , под влиянием (хотя первоначально не получен из [6] ) нотации Алонзо Черч «s лямбда - исчисления . Он быстро стал излюбленным языком программирования для исследований в области искусственного интеллекта (ИИ). В качестве одного из самых ранних языков программирования Лисп инициатора многих идей в области информатики , в том числе структуры дерева данных , автоматическое управления хранением данных , динамической типизации , условные , функции высшего порядка , рекурсии, компилятор с собственным хостом , [7] и цикл чтения – оценки – печати . [8]

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

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

История [ править ]

Джон Маккарти (вверху) и Стив Рассел

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

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

В оригинальной нотации Маккарти использовались заключенные в скобки « М-выражения », которые переводились в S-выражения . Например, M-выражение car[cons[A,B]]эквивалентно S-выражению . После того, как Лисп был реализован, программисты быстро решили использовать S-выражения, и M-выражения были оставлены. M-выражения снова всплыли с короткоживущими попытками MLisp [11] по Хорас Enea и CGOL по Vaughan Pratt .(car (cons A B))

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

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

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

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

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

Хронология [ править ]

Связь с искусственным интеллектом [ править ]

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

Генеалогия и варианты [ править ]

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

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

Исторически значимые диалекты [ править ]

Машина Lisp в MIT музей
4.3 BSD из Университета Висконсина , отображающая страницу руководства для Franz Lisp
  • LISP 1 [19] - Первая реализация.
  • LISP 1.5 [16] - первая широко распространенная версия, разработанная Маккарти и другими в Массачусетском технологическом институте. Назван так потому, что он содержал несколько улучшений исходного интерпретатора "LISP 1", но не был серьезной реструктуризацией, как запланированный LISP 2 .
  • Stanford LISP 1.6 [20]. Это был преемник LISP 1.5, разработанный в Stanford AI Lab и широко распространенный в системах PDP-10 , работающих под управлением операционной системы TOPS-10 . Maclisp и InterLisp сделали его устаревшим.
  • MACLISP [21] - разработан для проекта MAC Массачусетского технологического института , MACLISP является прямым потомком LISP 1.5. Он работал на системах PDP-10 и Multics . MACLISP позже стал называться Maclisp и часто упоминается как MacLisp. «MAC» в MACLISP не имеет отношения ни к Macintosh Apple, ни к Маккарти .
  • Interlisp [22] - разработан BBN Technologies для систем PDP-10, работающих под управлением операционной системы TENEX , позже принят в качестве Лиспа «западного побережья» для машин Xerox Lisp как InterLisp-D . Небольшая версия под названием «INTERLISP 65» была опубликована в 6502 -А Atari 8-разрядное семейство компьютерной линии. Некоторое время Maclisp и InterLisp были сильными конкурентами.
  • Franz Lisp - первоначально проект Калифорнийского университета в Беркли ; позже разработано Franz Inc. Название представляет собой юмористическую деформацию имени « Franz Liszt » и не относится к Allegro Common Lisp , диалекту Common Lisp, продаваемому Franz Inc. в последние годы.
  • XLISP , на котором основан AutoLISP .
  • Стандартный Лисп и Переносимый Стандартный Лисп широко использовались и переносились, особенно с Системой компьютерной алгебры REDUCE.
  • ZetaLisp , также называемый Lisp Machine Lisp - используется на Lisp-машинах , прямой потомок Maclisp. ZetaLisp оказал большое влияние на Common Lisp.
  • LeLisp - это французский диалект Лиспа. Один из первых конструкторов интерфейсов (так называемый интерфейс SOS [23] ) был написан на LeLisp.
  • Схема (1975). [24]
  • Common Lisp (1984), как описано Common Lisp the Language - объединение нескольких расходящихся попыток (ZetaLisp, Spice Lisp , NIL и S-1 Lisp ) создать диалекты-преемники [25] Maclisp, с существенным влиянием Scheme диалект. Эта версия 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 (см. ниже).
  • В своей первой версии Дилан был смесью Scheme с объектной системой Common Lisp.
  • EuLisp - попытка разработать новый эффективный и очищенный Lisp.
  • ISLISP - попытка разработать новый эффективный и очищенный Lisp. Стандартизован как 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: язык в качестве базового документа и работу через общественный консенсус процесс поиска решений общие вопросы переносимости программ и совместимости реализаций Common Lisp. Хотя формально это стандарт ANSI, реализация, продажа, использование и влияние ANSI Common Lisp наблюдались и продолжают проявляться во всем мире.
  • ACL2 или «Вычислительная логика для аппликативного Common Lisp», аппликативный (без побочных эффектов) вариант Common LISP. ACL2 - это и язык программирования, который может моделировать компьютерные системы, и инструмент, помогающий доказывать свойства этих моделей.
  • Clojure , недавний диалект Lisp, который компилируется в виртуальную машину Java и уделяет особое внимание параллелизму .
  • Game Oriented Assembly Lisp (или GOAL) - это язык программирования видеоигр, разработанный Энди Гэвином и командой Jak and Daxter в Naughty Dog . Он был написан с использованием Allegro Common Lisp и использовался при разработке всей серии игр Jak and Daxter .

2000, чтобы представить [ править ]

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

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

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

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

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

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

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

В октябре 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 также позаимствовал некоторые функции из Scheme, такие каклексическая область видимости и лексические замыкания . Реализации Common Lisp для таргетинга доступны на различных платформах , таких как LLVM , [40] виртуальная машина Java , [41] x86-64, PowerPC, Alpha, ARM, Motorola 68000 и MIPS, [42] и операционные системы , такие как Windows , , macOS, Linux, Solaris, FreeBSD, NetBSD, OpenBSD, Dragonfly BSD и Heroku. [43]

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

Clojure является недавний диалект Lisp , что цели в основном виртуальной машины Java и среды CLR (CLR), то Python В.М., Рубин М. YARV и компиляции в JavaScript . Он разработан как прагматичный язык общего назначения. Clojure сильно зависит от Haskell и уделяет большое внимание неизменности. [44] Clojure обеспечивает доступ к инфраструктурам и библиотекам Java с дополнительными подсказками типов и выводом типов , так что вызовы Java могут избежать отражения и обеспечить быстрые примитивные операции. Clojure не предназначен для обратной совместимости с другими диалектами Лиспа.[45]

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

Стандартизированные диалекты [ править ]

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

Языковые нововведения [ править ]

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

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

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

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

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

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

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

Синтаксис и семантика [ править ]

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

Символьные выражения (S-выражения) [ править ]

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

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

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

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

Списки [ править ]

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

Пустой список ()также представлен как специальный атом 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синтаксисом, дающим имя

 ( incf  x )

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

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

 ( если  nil  ( список  1  2  "foo" )  ( список  3  4  "bar" ))

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

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

 ( или  ( и  «ноль»  ноль  «никогда» )  «  время выполнения задачи  Джеймса» )

оценит "Джеймсу".

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

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

 ( лямбда  ( аргумент )  ( +  аргумент  1 ))

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

 (( лямбда  ( аргумент )  ( +  аргумент  1 ))  5 )

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

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

 ( DEFUN  Foo  ( б с д ) ( + б с д ))        

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

 ( setf  ( fdefinition  'f )  #' ( лямбда  ( a )  ( блок  f  b ... )))

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

Атомы [ править ]

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

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

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

Консультации и списки [ править ]

График в виде прямоугольника для списка (42 69 613)

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

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

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

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

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

S-выражения представляют собой списки [ править ]

Заключенные в скобки S-выражения представляют собой структуры связанных списков. Есть несколько способов представить один и тот же список в виде S-выражения. Минусы могут быть записаны в виде пар, разделенных точками, как , где - автомобиль и cdr. Более длинный правильный список может быть записан в виде пар с точками. Это условно сокращенно, как в обозначении списка . Неправильный список [56] может быть записан в комбинации из двух - как для списка из трех conses, последний cdr которых равен (т. Е. Список в полностью определенной форме).(a . b)ab(a . (b . (c . (d . nil))))(a b c d)(a b c . d)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процедура может использоваться для добавления элемента в начало списка. Обратите внимание, что consпроцедура асимметрична в том, как она обрабатывает аргументы списка, из-за того, как списки построены.

 ( cons  1  ' ( 2  3 ))  ; Вывод: (1 2 3)
 ( cons  ' ( 1  2 )  ' ( 3  4 ))  ; Вывод: ((1 2) 3 4)

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

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

Общая структура [ править ]

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

( setf  foo  ( список  'a  ' b  'c )) ( setf  bar  ( cons  ' x  ( cdr  foo )))

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

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

 ( setf  ( третий  фу )  'гусь )

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

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

Формы самооценки и цитирование [ править ]

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

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

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

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

( defun  should-be-constant  ()  ' ( один,  два,  три ))( let  (( штука  ( должно быть-константой )))  ( setf  ( третья  штука )  'причудливая ))  ; Плохо!( должно быть постоянным )  ; возвращается (один, два странных)

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

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

Сфера действия и закрытие [ править ]

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

Списочная структура программного кода; использование макросами и компиляторами [ править ]

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

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

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

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

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

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

Оценка и цикл чтения – оценки – печати [ править ]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Из-за раннего наследия Lisp в обработке списков, он имеет широкий спектр функций высшего порядка, связанных с итерацией по последовательностям. Во многих случаях, когда явный цикл потребуется в других языках (например, 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.

Базовая программа « Hello, World! »:

( напечатайте  «Hello, World!» )

Синтаксис 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 Lisp «s loopмакрос:

( defun  factorial  ( n )  ( цикл  для  i  от  1  до  n  для  fac  =  1,  затем  ( *  fac  i )  finally  ( return  fac )))

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

( defun  -reverse  ( список )  ( let  (( return-value  ' ()))  ( dolist  ( e  list )  ( push  e  return-value ))  return-value ))

Системы объектов [ править ]

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

  • System Object Common Lisp , Клоса, является неотъемлемой частью ANSI Common Lisp. CLOS произошел от New Flavors и CommonLOOPS. ANSI Common Lisp был первым стандартизированным объектно-ориентированным языком программирования (1994, ANSI X3J13).
  • ObjectLisp [62] или Object Lisp , используемый Lisp Machines Incorporated и ранними версиями Macintosh Common Lisp
  • LOOPS (объектно-ориентированная система программирования Lisp) и более поздняя версия CommonLOOPS
  • Flavors , созданные в Массачусетском технологическом институте , и его потомки New Flavors (разработанные Symbolics ).
  • KR (сокращение от «Представление знаний»), объектная система на основе ограничений , разработанная для помощи в написании Garnet, библиотеки графического интерфейса для Common Lisp .
  • Среда инженерии знаний (KEE) использовала объектную систему UNITS и интегрировала ее с механизмом вывода [63] и системой поддержания истины (ATMS).

См. Также [ править ]

  • Самомодифицирующийся код

Ссылки [ править ]

  1. ^ «Введение» . Руководство Джулии . Прочтите Документы. Архивировано из оригинала на 2016-04-08 . Проверено 10 декабря 2016 .
  2. ^ "Wolfram Language Q&A" . Wolfram Research . Проверено 10 декабря 2016 .
  3. Эдвин Д. Рейли (2003). Основные этапы развития информатики и информационных технологий . Издательская группа «Гринвуд». С. 156–157. ISBN 978-1-57356-521-9.
  4. ^ «SICP: Предисловие» . Архивировано из оригинала на 2001-07-27. Лисп пережил уже около четверти века. Среди активных языков программирования только Фортран прожил дольше.
  5. ^ «Выводы» . Архивировано из оригинала на 2014-04-03 . Проверено 4 июня 2014 .
  6. ^ «Искусство переводчика или комплекс модульности (части ноль, один и два), часть ноль, стр. 4» . Библиотеки MIT. ЛВП : 1721,1 / 6094 . Проверено 1 августа 2020 .
  7. ^ Пол Грэм. «Месть ботаников» . Проверено 14 марта 2013 .
  8. ^ Chisnall, Дэвид (2011-01-12). Влиятельные языки программирования, часть 4: Лисп .
  9. ^ Джонс, Робин; Мейнард, Клайв; Стюарт, Ян (6 декабря 2012 г.). Искусство программирования на Лиспе . Springer Science & Business Media. п. 2. ISBN 9781447117193.
  10. ^ Джон Маккарти. «Рекурсивные функции символьных выражений и их машинное вычисление, часть I» . Архивировано из оригинала на 2013-10-04 . Проверено 13 октября 2006 .
  11. ^ Дэвид Кэнфилд Смит. «Руководство пользователя MLISP» (PDF) . Проверено 13 октября 2006 .
  12. Джон Маккарти (12 февраля 1979 г.). "История Lisp: Лаборатория искусственного интеллекта" (PDF) .
  13. Согласно сообщениям Пола Грэма в Hackers & Painters , стр. 185, Маккарти сказал: «Стив Рассел сказал, послушайте, почему бы мне не запрограммировать этот eval  ... и я сказал ему, хо-хо, вы путаете теорию с практикой, этот eval предназначен для чтения, а не для Но он пошел дальше и сделал это. То есть он скомпилировал eval в моей статье вмашинный код IBM 704 , исправив ошибку , а затем объявил это интерпретатором Лиспа, что, безусловно, им и было. Так что на тот момент Лисп по существу имел форма, которую он имеет сегодня ... "
  14. ^ Джон Маккарти. «Предыстория LISP - лето 1956 - лето 1958» . Проверено 14 марта 2010 .
  15. ^ Тим Харт и Майк Левин. «AI Memo 39-Новый компилятор» (PDF) . Проверено 18 марта 2019 .
  16. ^ а б Маккарти, Джон; Abrahams, Paul W .; Эдвардс, Дэниел Дж .; Харт, Тимоти П .; Левин, Михаил I. (1985) [1962]. Руководство программиста LISP 1.5 (2-е изд.). MIT Press . ISBN 0-262-13011-4.
  17. ^ На 36-битный размер слова PDP-6 / PDP-10 повлияла полезность наличия двух 18-битных указателей Лиспа в одном слове. Питер Дж. Херли (18 октября 1990 г.). «История ТОПов или жизнь в быстрых АС» . Группа новостейalt.folklore.computers . Usenet: [email protected] . Проект PDP-6 стартовал в начале 1963 года как 24-битная машина. Он вырос до 36 бит для LISP, что было целью разработки. 
  18. ^ Common Lisp:(defun f (x) x)
    Схема:(define f (lambda (x) x))или(define (f x) x)
  19. ^ Маккарти, Дж . ; Брайтон, Р .; Эдвардс, Д .; Фокс, П .; Ходс, Л .; Лакхэм, Д .; Малинг, К .; Парк, Д .; Рассел, С. (март 1960). «Руководство программиста LISP I» (PDF) . Бостон , Массачусетс : Группа искусственного интеллекта, Вычислительный центр Массачусетского технологического института и исследовательская лаборатория . Архивировано из оригинального (PDF) 17 июля 2010 года. Цитировать журнал требует |journal=( помощь ) По состоянию на 11 мая 2010 г.
  20. ^ Quam, Lynn H .; Диффл, Уитфилд. Стэнфордское руководство LISP 1.6 (PDF) .
  21. ^ "Справочное руководство Maclisp" . 3 марта, 1979. Архивировано из оригинала на 2007-12-14.
  22. ^ Тейтельман, Уоррен (1974). Справочное руководство InterLisp (PDF) . Архивировано из оригинального (PDF) 02.06.2006 . Проверено 19 августа 2006 .
  23. ^ Outils de generation d'interfaces: etat de l'art et классификация Х. Эль Мрабет
  24. ^ ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-349.pdf [ постоянная мертвая ссылка ]
  25. ^ Стил, Гай Л., младший "Цель" . Общий Лисп язык (2-е изд.). ISBN 0-13-152414-3.
  26. ^ Кантровиц, Марк; Марголин, Барри (20 февраля 1996 г.). «История: откуда появился Лисп?» . FAQ: Часто задаваемые вопросы по Lisp 2/7 .
  27. ^ «ISO / IEC 13816: 1997» . Iso.org. 2007-10-01 . Проверено 15 ноября 2013 .
  28. ^ «ISO / IEC 13816: 2007» . Iso.org. 2013-10-30 . Проверено 15 ноября 2013 .
  29. ^ "X3J13 Устав" .
  30. ^ "Дорога к обзору Lisp" . Архивировано из оригинала на 2006-10-04 . Проверено 13 октября 2006 .
  31. ^ «Тенденции на будущее» . Faqs.org . Проверено 15 ноября 2013 .
  32. ^ Вайнреб, Даниэль. «Реализации Common Lisp: Обзор» . Архивировано из оригинала на 2012-04-21 . Проверено 4 апреля 2012 года .
  33. ^ "LISP50 @ OOPSLA" . Lisp50.org . Проверено 15 ноября 2013 .
  34. ^ Документы: Стандарты: R5RS . schemers.org (11 января 2012 г.). Проверено 17 июля 2013.
  35. ^ «Почему MIT теперь использует python вместо схемы для своей программы CS для студентов» . cemerick.com . 24 марта 2009 . Проверено 10 ноября 2013 года .
  36. Бродер, Эван (8 января 2008 г.). «Конец эпохи» . mitadmissions.org . Проверено 10 ноября 2013 года .
  37. ^ "Программы бакалавриата MIT EECS" . www.eecs.mit.edu . MIT Электротехника и информатика . Проверено 31 декабря 2018 года .
  38. ^ «Вводный курс Python MITx набирает 1,2 миллиона человек» . MIT EECS . MIT Электротехника и информатика . Проверено 31 декабря 2018 года .
  39. ^ Глава 1.1.2, История, Стандарт ANSI CL
  40. ^ [1] Clasp - это реализация Common Lisp, которая взаимодействует с C ++ и использует LLVM для своевременной компиляции (JIT) машинного кода.
  41. ^ [2] "Armed Bear Common Lisp (ABCL) - это полная реализация языка Common Lisp, включающая как интерпретатор, так и компилятор, работающий в JVM"
  42. ^ [3] Архивировано 22 июня 2018 г. на сайте Wayback Machine Common Lisp Implementations: Обзор
  43. ^ [4] Сравнение активно разрабатываемых реализаций Common Lisp
  44. ^ Подробный обзор коллекций Clojure , дата обращения 24.06.2012
  45. ^ "Clojure рациональный" . Проверено 27 августа 2019 . Clojure - это Лисп, не ограниченный обратной совместимостью
  46. ^ Script-fu в GIMP 2.4 , дата обращения 29.10.2009.
  47. ^ librep в Sawfish Wikia, получено 29 октября 2009 г.
  48. ^ «Схема IEEE» . IEEE 1178-1990 - Стандарт IEEE для языка программирования схем . Проверено 27 августа 2019 .
  49. ^ "Предыстория LISP - лето 1956 года по лето 1958 года" . Я изобрел условные выражения в связи с набором процедур легальных ходов в шахматах, которые я написал на FORTRAN для IBM 704 в Массачусетском технологическом институте в 1957–58 ... Документ, определяющий условные выражения и предлагающий их использование в Algol, был отправлен в Коммуникацию ACM но произвольно понижен в должности до письма редактору, потому что оно было очень коротким.
  50. ^ «Значение« объектно-ориентированного программирования »по доктору Алану Кею» . 2003-07-23. Тогда я не понимал монструозную идею LISP о материальном метаязыке, но немного сблизился с идеями о расширяемых языках ... Второй этап заключался в том, чтобы наконец понять LISP, а затем использовать это понимание, чтобы сделать намного лучше, меньше и больше. мощные и более поздние связанные структуры ... ООП для меня означает только обмен сообщениями, локальное сохранение и защиту, а также сокрытие состояния-процесса и крайнее позднее связывание всех вещей. Это можно сделать в Smalltalk и LISP. Возможно, существуют другие системы, в которых это возможно, но я о них не знаю.
  51. ^ Либерман, Генри; Хьюитт, Карл (июнь 1983), «В режиме реального времени сборщик мусора , основанный на время жизни объектов» , коммуникации АСМА , 26 (6): 419-429, CiteSeerX 10.1.1.4.8633 , DOI : 10,1145 / 358141,358147 , ЛВП : 1721,1 / 6335 , S2CID 14161480  
  52. Эдсгер В. Дейкстра (1972), скромный программист (EWD 340) (Лекция ACM Turing Award).
  53. ^ "Взгляд на Clojure и возрождение Лиспа" .
  54. ^ "Файл жаргона - Лисп" . Проверено 13 октября 2006 .
  55. ^ Себеста, Robert W. (2012). « » 2,4 Функциональное программирование: LISP «» Типы 6,9 Список «;» 15,4 Первый функциональный Язык программирования: LISP « ». Концепции языков программирования (печать) (10-е изд.). Бостон, Массачусетс, США: Аддисон-Уэсли. С. 47–52, 281–284, 677–680. ISBN  978-0-13-139531-2.
  56. ^ NB: так называемый «точечный список» - это только один из видов «неправильного списка». Другой вид - это «круговой список», в котором cons-ячейки образуют цикл. Обычно это представляется с помощью #n = (...) для представления целевой cons-ячейки, которая будет иметь несколько ссылок, а # n # используется для ссылки на эту cons-ячейку. Например, (# 1 = (ab). # 1 #) обычно печатается как ((ab) ab) (без включения печати круговой структуры), но делает возможным повторное использование cons-ячейки. # 1 = (a. # 1 #) обычно не может быть напечатано, поскольку оно является круглым, хотя (a ...) иногда отображается, CDR cons-ячейки, определяемой # 1 =, является самим собой.
  57. ^ «CSE 341: Схема: цитата, квазицитат и метапрограммирование» . Cs.washington.edu. 1999-02-22 . Проверено 15 ноября 2013 .
  58. ^ Quasiquotation в Лиспе Архивированных 2013-06-03 в Wayback Machine , Алан Боуден
  59. ^ Время оценки - Common Lisp Extensions . Gnu.org. Проверено 17 июля 2013.
  60. ^ 3.2.2.3 Семантические ограничения в Common Lisp HyperSpec
  61. ^ 4.3. Контроль Абстракция (Рекурсия против Итерации) в учебнике по добросовестной Lisp стиля программирования на Кент Питман и Питер Норвиг , августа 1993 года.
  62. ^ стр. 17 из Bobrow 1986
  63. Перейти ↑ Veitch, p 108, 1988

Дальнейшее чтение [ править ]

  • Маккарти, Джон (1979-02-12). «Реализация Лиспа» . История Lisp . Стэнфордский университет . Проверено 17 октября 2008 .
  • Стил младший, Гай Л .; Ричард П. Габриэль (1993). Эволюция Лиспа (PDF) . Вторая конференция ACM SIGPLAN по истории языков программирования. Нью-Йорк, штат Нью-Йорк: ACM. С. 231–270. ISBN 0-89791-570-4. Проверено 17 октября 2008 .
  • Вейтч, Джим (1998). «История и описание CLOS». В Салусе, Питер Х (ред.). Справочник по языкам программирования . Том IV, Функциональные и логические языки программирования (первое изд.). Индианаполис, Индиана: Техническое издательство Macmillan. С.  107–158 . ISBN 1-57870-011-6.
  • Абельсон, Гарольд ; Сассман, Джеральд Джей ; Суссман, Джули (1996). Структура и интерпретация компьютерных программ (2-е изд.). MIT Press. ISBN 0-262-01153-0.
  • Мой Лисп опыт и развитие GNU Emacs , стенограмма из Ричарда Столлмана речи «s, 28 октября 2002 года на Международной конференции Лиспа
  • Грэм, Пол (2004). Хакеры и художники. Большие идеи эпохи компьютеров . О'Рейли. ISBN 0-596-00662-4.
  • Беркли, Эдмунд К .; Боброу, Дэниел Г. , ред. (Март 1964 г.). Язык программирования LISP: его работа и приложения (PDF) . Кембридж, Массачусетс: MIT Press.
    • Статья в значительной степени основана на главе LISP - A Simple Introduction : Berkeley, Edmund C. (сентябрь 1964 г.). "ЯЗЫК ПРОГРАММИРОВАНИЯ LISP: ВВЕДЕНИЕ И ОЦЕНКА" . Компьютеры и автоматика : 16 -23.
  • Вайсман, Кларк (1967). Праймер LISP 1.5 (PDF) . Белмонт, Калифорния: Dickenson Publishing Company Inc.

Внешние ссылки [ править ]

История
  • История Лиспа - история Джона Маккарти от 12 февраля 1979 г.
  • История Лиспа - история Герберта Стояна, составленная из документов (признанных Маккарти более полной, чем его собственная, см .: Ссылки на историю Маккарти )
  • История LISP в Музее компьютерной истории
Ассоциации и встречи
  • Ассоциация пользователей Lisp
  • Европейское собрание Common Lisp
  • Европейский симпозиум по Лисп
  • Международная конференция Lisp
Книги и учебные пособия
  • Приведение SPEL в Лисп , вводное руководство в стиле комиксов
  • О Лиспе , бесплатной книге Пола Грэма
  • Практический Common Lisp , бесплатное издание Питера Сейбеля
  • Lisp для Интернета
  • Земля Лиспа
  • Let over Lambda
Интервью
  • Устное интервью истории с Джоном Маккарти в Институте Чарльза Бэббиджа , Университет Миннесоты, Миннеаполис. Маккарти обсуждает свою роль в развитии разделения времени в Массачусетском технологическом институте. Он также описывает свою работу в области искусственного интеллекта (ИИ), финансируемую Агентством перспективных исследовательских проектов, включая ИИ на основе логики (LISP) и робототехнику.
  • Интервью с Ричардом П. Габриэлем (Подкаст)
Ресурсы
  • CLiki: вики Common Lisp
  • Каталог Common Lisp (через Wayback Machine ; заархивировано из оригинала )
  • Индекс FAQ по Lisp
  • лиспаста
  • Планета Лисп
  • Еженедельные новости Lisp
  • newLISP - современный язык сценариев общего назначения
  • Лисп в Керли