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

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

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

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

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

По состоянию на 2010 год было одиннадцать активно поддерживаемых реализаций Common Lisp. [32] 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 со вкусом Lisp). Парсер для 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, изобретенный Гаем Л. Стилом-младшим и Джеральдом Джеем Сассманом . Он был разработан, чтобы иметь исключительно ясную и простую семантику и несколько различных способов формирования выражений. Scheme, созданный примерно на десять лет раньше Common Lisp, имеет более минималистичный дизайн. Он имеет гораздо меньший набор стандартных функций, но с некоторыми функциями реализации (такими как оптимизация хвостового вызова и полные продолжения) не указан в 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 ; и, в свою очередь, Lisp находился под влиянием 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 написаны в виде списков, их можно обрабатывать точно так же, как данные. Это позволяет легко писать программы, которые манипулируют другими программами ( метапрограммирование ). Многие диалекты Лиспа используют эту возможность с помощью макросистем, которые позволяют расширять язык почти без ограничений.

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

Список Лиспа записывается с элементами, разделенными пробелами и заключенными в круглые скобки. Например, список, элементами которого являются три атома , и . Эти значения неявно типизированы: они представляют собой соответственно два целых числа и специфичный для 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!(читай: set car bang ), который заменяет автомобиль на минус. В диалекте 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) в Common Lisp не приветствуется [61], является не только вопросом стилистических предпочтений, но и потенциально вопросом эффективности (поскольку очевидный хвостовой вызов в 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!» )

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

( 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, библиотеки GUI для 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. Lisp выжил уже около четверти века. Среди активных языков программирования только Фортран прожил дольше.
  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. ^ Дэвид Кэнфилд Смит. «Руководство пользователя МЛИСП» (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-битных указателей Lisp в одном слове. Питер Дж. Херли (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. ^ Себеста, Роберт В. (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 . 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 - современный язык сценариев общего назначения
  • Лисп в Керли