Фекспр
В Lisp языках программирования fexpr — это функция, операнды которой передаются ей без вычисления. При вызове fexpr оценивается только тело fexpr; никакие другие оценки не проводятся, за исключением случаев, явно инициированных fexpr. Напротив, когда вызывается обычная функция Лиспа, операнды вычисляются автоматически, и функции передаются только результаты этих оценок; и когда вызывается (традиционный) макрос Lisp , операнды передаются без оценки, но какой бы результат ни возвращала макрофункция, вычисляется автоматически.
Происхождение названия «fexpr»
[ редактировать ]В ранних версиях Lisp среда сопоставляла каждый символ со списком ассоциаций , а не напрямую со значением. [1] Стандартные ключи для этих списков включали два ключа, используемые для хранения значения данных, которые нужно было искать, когда символ встречается в качестве аргумента ( АПВАЛ и АПВАЛ1 ); и четыре клавиши, используемые для хранения функции, которую нужно искать, когда символ встречается в качестве оператора. Из функциональных клавиш SUBR указывал скомпилированную обычную функцию, операнды которой были оценены и переданы ей; FSUBR указал скомпилированную специальную форму, операнды которой передавались без оценки; EXPR указывает на обычную функцию, определяемую пользователем; и FEXPR указал специальную форму, определяемую пользователем. Единственная разница между FEXPR и EXPR заключалась в том, вычислялись ли операнды автоматически.
Таким образом, в строгом исходном использовании FEXPR представляет собой определяемую пользователем функцию, операнды которой передаются без оценки. Однако в дальнейшем термин fexpr может описывать любую функцию первого класса , операнды которой передаются без оценки, независимо от того, является ли функция примитивной или определяемой пользователем. [2]
Ключ | Магазины | Определено | Функция/Специальная форма |
---|---|---|---|
АПВАЛ | значение данных | — | — |
ОДОБРЕНИЕ1 | значение данных | — | — |
СУБР | функция | система | функция |
ФГУБР | функция | система | специальная форма |
ЭКСПР | функция | пользователь | функция |
ФЭКСПР | функция | пользователь | специальная форма |
Пример
[ редактировать ]В качестве простой иллюстрации того, как работает fexprs, вот определение fexpr, написанное на языке программирования Kernel , похожем на Scheme . (По соглашению в Kernel имена fexprs всегда начинаются с $ .)
($define! $f
($vau (x y z) e
($if (>=? (eval x e) 0)
(eval y e)
(eval z e))))
Это определение предоставляет fexpr, называемый $f , который принимает три операнда. При вызове fexpr создается локальная среда путем расширения статической среды, в которой был определен fexpr. Затем создаются локальные привязки: символы х , й , и z привязаны к трем операндам вызова fexpr, а символ e привязан к динамической среде, из которой вызывается fexpr. Тело фекспра, ($если ... ) затем оценивается в этой локальной среде, и результат этой оценки становится результатом вызова fexpr. Конечным результатом является то, что первый операнд оценивается в динамической среде, и, в зависимости от того, является ли результат этой оценки неотрицательным, оценивается либо второй, либо третий операнд, и этот результат возвращается. Другой операнд, третий или второй, не оценивается.
Этот пример имеет статическую область действия : локальная среда является расширением статической среды. Примерно до 1980 года языки Лисп, поддерживавшие fexprs, в основном имели динамическую область видимости: локальная среда была расширением динамической среды, а не статической среды. [3] Однако иногда все же было необходимо предоставить локальное имя для динамической среды, чтобы избежать захвата имен локальных параметров. [4]
Основное использование и устаревание
[ редактировать ]Поддержка Fexpr продолжилась в Lisp 1.5 , последнем практически стандартном диалекте Lisp до того, как он был фрагментирован на несколько языков. [5] В 1970-е годы два доминирующих языка Лисп [6] — MacLisp и Interlisp — оба поддерживают fexprs. [7]
На конференции 1980 года по Лиспу и функциональному программированию Кент Питман представил доклад «Специальные формы в Лиспе», в котором он обсуждал преимущества и недостатки макросов и fexprs и в конечном итоге осудил fexprs. Его центральное возражение заключалось в том, что в диалекте Лиспа, допускающем fexprs, статический анализ не может вообще определить, представляет ли оператор обычную функцию или fexpr — следовательно, статический анализ не может определить, будут ли вычисляться операнды. В частности, компилятор не может определить, можно ли безопасно оптимизировать подвыражение, поскольку подвыражение может рассматриваться как невычисленные данные во время выполнения.
MACRO предлагают адекватный механизм для определения специальных определений форм и... FEXPR этого не делает. ... Предлагается, чтобы при разработке будущих диалектов Лиспа серьезное внимание уделялось предположению, что FEXPR следует вообще исключить из языка. [8]
После упадка MacLisp и Interlisp, двух языков Lisp, которые стали доминировать к 1993 году. [9] — Scheme и Common Lisp — не поддерживают fexprs. newLISP поддерживает fexprs, но называет их «макросами». В Picolisp все встроенные функции — это fsubrs, тогда как функции уровня Lisp — это exprs, fexprs, lexprs или их смесь.
Фекспрс с 1980 года.
[ редактировать ]Начиная с Брайана Смита в 3-Lisp 1982 году, было разработано несколько экспериментальных диалектов Lisp для исследования пределов вычислительного отражения . Для поддержки отражения эти Lisps поддерживают процедуры, которые могут конкретизировать различные структуры данных, связанные с вызовом к ним, включая невычисленные операнды вызова, что делает эти процедуры fexprs. К концу 1990-х годов fexprs стал ассоциироваться в первую очередь с вычислительным отражением. [10]
Получены некоторые теоретические результаты по fexprs. В 1993 году Джон К. Митчелл использовал Лисп с fexprs как пример языка программирования, исходные выражения которого не могут быть формально абстрактными (поскольку конкретный синтаксис исходного выражения всегда можно извлечь из контекста, в котором оно является операндом для fexpr). ). [11] В 1998 году Митчелл Ванд показал, что добавление устройства fexpr к лямбда-исчислению — устройства, которое подавляет перезапись операндов — создает формальную систему с тривиальной эквациональной теорией , что делает невозможным оптимизацию от источника к источнику без анализа всей программы. . [10] В 2007 году Джон Н. Шатт предложил расширение лямбда-исчисления, которое будет моделировать fexprs, не подавляя перезапись операндов, избегая результата Ванда. [12]
См. также
[ редактировать ]Следующие языки реализуют fexprs или близкие к ним эквиваленты:
- язык программирования ECL предоставляет тип параметра («класс привязки»)
UNEVAL
, который указывает, что синтаксическое дерево для выражения аргумента. к параметру должно быть привязано - io методы (блоки) могут использовать самоанализ, используя
call
чтобы обратиться ко всему вызову и манипулировать им. См. слоты для звонков и самообслуживания в io . - Ядро использует
$vau
для создания fexprs, аналогично тому, какlambda
создает функции в Scheme . - newLISP использует
define-macro
определить fexprs. См . раздел «Макросы Fexpr и макросы перезаписи» . - В ПикоЛиспе
(de foo X ...)
определяет фекспрfoo
что при вызове связываетсяX
в список невычисленных выражений аргументов. См. Оценка в PicoLisp . - Параметры R обычно привязаны к обещаниям (что приводит к ленивому вычислению ) и вызову
substitute(param)
для параметра дает выражение аргумента, см. Замены в R . - В REBOL выражения аргументов, которые не подлежат оценке, должны быть заключены вызывающей стороной в блок (квадратные скобки). Другими словами, вы не можете определить вызываемую сторону, которая предотвращает вычисление аргументов. См. эту статью с примерами. В этом смысле в REBOL нет fexprs, он просто позволяет легко эмулировать некоторые из их применений. В языке с настоящими fexprs вызовы fexpr выглядят как обычные вызовы функций. С другой стороны, в REBOL вызовы, аргументы которых не оцениваются, всегда выглядят иначе, чем обычные вызовы функций.
Сноски
[ редактировать ]- ^ Маккарти и др., Руководство программиста Lisp I , стр. 88–91.
- ^ Питман, Пересмотренное руководство MacLisp , стр. 75.
- ^ Стил и Габриэль, «Эволюция Лиспа», стр. 239–240.
- ^ Питман, Пересмотренное руководство MacLisp , стр. 62
- ^ Стил и Габриэль, «Эволюция Лиспа», стр. 231-232.
- ^ Стил и Габриэль, «Эволюция Лиспа», стр. 235.
- ^ Питман, Пересмотренное руководство MacLisp , стр. 182.
- ^ Питман, «Специальные формы в Лиспе», с. 179.
- ^ Стил и Габриэль, «Эволюция Лиспа», стр. 245–248.
- ^ Перейти обратно: а б Ванд, «Теория Fexprs тривиальна», с. 189.
- ^ Митчелл, «Об абстракции и выразительной силе языков программирования», раздел 7.
- ^ Шатт, «вау-исчисления и теория фекспр».
Ссылки
[ редактировать ]- Маккарти, Дж .; Брайтон, Р .; Эдвардс, Д .; Фокс, П .; Ходс, Л. ; Лакхэм, Д .; Малинг, К .; Парк, Д. ; Рассел, С. (март 1960 г.), Руководство для программистов LISP I (PDF) , Бостон , Массачусетс : Группа искусственного интеллекта, Вычислительный центр и исследовательская лаборатория Массачусетского технологического института , доступ 11 мая 2010 г.
- Джон К. Митчелл, «Об абстракции и выразительной силе языков программирования» , Science of Computer Programming 212 (1993), стр. 141–163. (Специальный выпуск статей Symp. Theor. Aspects of Computer Software, Сендай, Япония, 1991 г.) По состоянию на 24 января 2008 г.
- Кент М. Питман, «Специальные формы в Лиспе» , Материалы конференции ACM 1980 года по Лиспу и функциональному программированию, 1980, стр. 179–187. По состоянию на 25 января 2008 г.
- Кент М. Питман, Пересмотренное руководство MacLisp (выпуск в субботу вечером), Технический отчет 295 Лаборатории компьютерных наук Массачусетского технологического института, 21 мая 1983 г.
- Джон Н. Шатт, «вау-исчисления и теория fexprs», доклад, Серия симпозиумов по языкам и системам программирования Новой Англии (NEPLS) , 18 октября 2007 г. Доступ к реферату получен 27 января 2008 г.
- Гай Л. Стил и Ричард П. Габриэль, «Эволюция Лиспа», Уведомления ACM SIGPLAN 28 вып. 3 (март 1993 г.), стр. 231–270.
- Митчелл Ванд, «Теория Fexprs тривиальна» , LISP и символические вычисления 10 вып. 3 (май 1998 г.), стр. 189–199. По состоянию на 25 января 2008 г.