В языках программирования Lisp fexpr - это функция, операнды которой передаются ей без оценки. Когда вызывается fexpr, оценивается только тело fexpr; никакие другие оценки не выполняются, кроме случаев, когда они явно инициированы fexpr. Напротив, когда вызывается обычная функция Lisp, операнды вычисляются автоматически, и только результаты этих вычислений передаются функции; и когда вызывается (традиционный) макрос Лиспа , операнды передаются без оценки, но какой бы результат ни возвращала функция макроса, вычисляется автоматически.
Происхождение названия "fexpr"
В раннем Лиспе среда отображала каждый символ в список ассоциаций , а не непосредственно в значение. [1] Стандартные ключи для этих списков включали два ключа, используемые для хранения значения данных, которые нужно искать, когда символ встречается в качестве аргумента ( APVAL и APVAL1 ); и четыре клавиши, используемые для сохранения функции, которую нужно искать, когда символ встречается как оператор. Из функциональных клавиш SUBR указывает на скомпилированную обычную функцию, операнды которой были вычислены и переданы ей; FSUBR указал скомпилированную специальную форму, операнды которой были переданы без вычисления; EXPR указывает на определяемую пользователем обычную функцию; а также FEXPR указал специальную форму, определяемую пользователем. Единственная разница между FEXPR и EXPR заключалась в том, автоматически ли вычислялись операнды.
Таким образом, в строгом первоначальном использовании FEXPR является определяемой пользователем функцией, операнды которой передаются без оценки. Однако в дальнейшем термин fexpr может описывать любую первоклассную функцию , операнды которой передаются без оценки, независимо от того, является ли функция примитивной или определяемой пользователем. [2]
Ключ | магазины | Определяется | Функция / Специальная форма |
---|---|---|---|
APVAL | значение данных | - | - |
APVAL1 | значение данных | - | - |
СУБР | функция | система | функция |
ФСУБР | функция | система | особая форма |
EXPR | функция | Пользователь | функция |
FEXPR | функция | Пользователь | особая форма |
Пример
В качестве простой иллюстрации того, как работают fexprs, вот определение fexpr, написанное на языке программирования Kernel , которое похоже на Scheme . (По соглашению в Kernel имена fexprs всегда начинаются с $ .)
( $ определить! $ f ( $ vau ( x y z ) e ( $ if ( > =? ( eval x e ) 0 ) ( eval y e ) ( eval z e ))))
Это определение предоставляет fexpr под названием $ f , который принимает три операнда. Когда вызывается fexpr, создается локальная среда путем расширения статической среды, в которой был определен fexpr. Затем создаются локальные привязки: символы х , y , и z связаны с тремя операндами вызова fexpr, а символ e привязан к динамической среде, из которой вызывается fexpr. Тело fexpr, ($ если ... ) , затем оценивается в этой локальной среде, и результат этой оценки становится результатом вызова fexpr. В результате первый операнд оценивается в динамической среде, и, в зависимости от того, является ли результат этой оценки неотрицательным, оценивается второй или третий операнд и возвращается этот результат. Другой операнд, третий или второй, не оценивается.
Этот пример имеет статическую область видимости : локальная среда является расширением статической среды. Примерно до 1980 года языки Lisp, поддерживающие fexprs, имели в основном динамическую область видимости: локальная среда была расширением динамической среды, а не статической среды. [3] Однако иногда все же необходимо было указать локальное имя для динамической среды, чтобы избежать захвата имен локальных параметров. [4]
Обычное использование и устаревание
Поддержка Fexpr продолжилась в Lisp 1.5 , последнем стандартном диалекте Lisp до того, как он был разделен на несколько языков. [5] В 1970-х годах два доминирующих языка Lisp [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 или их смесь.
fexprs с 1980 года
Начиная с Brian Smith «s 3-Лиспом в 1982 году, несколько экспериментальных диалектов Lisp были разработаны , чтобы исследовать пределы вычислительной рефлексии . Для поддержки отражения эти Лиспы поддерживают процедуры, которые могут реифицировать различные структуры данных, связанные с их вызовом, включая неоцененные операнды вызова, что делает эти процедуры fexprs. К концу 1990-х годов fexprs стали ассоциироваться в первую очередь с вычислительным отражением. [10]
Получены некоторые теоретические результаты по fexprs. В 1993 году Джон С. Митчелл использовал Лисп с fexprs в качестве примера языка программирования, исходные выражения которого не могут быть формально абстрактными (поскольку конкретный синтаксис исходного выражения всегда может быть извлечен контекстом, в котором он является операндом для fexpr ). [11] В 1998 году Митчелл Уанд показал, что добавление устройства fexpr к лямбда-исчислению - устройства, подавляющего перезапись операндов - создает формальную систему с тривиальной эквациональной теорией , что делает невозможным оптимизацию от источника к источнику без единой -программный анализ . [10] В 2007 году Джон Н. Шатт предложил расширение лямбда-исчисления, которое будет моделировать fexprs без подавления перезаписи операндов, якобы избегая результата Ванда. [12]
Смотрите также
Следующие языки реализуют fexprs или близкие к ним эквиваленты:
- Язык программирования ECL
- Io (язык программирования)
- Ядро (язык программирования)
- newLISP
- Пиколисп
- R (язык программирования)
- REBOL
Сноски
- ^ McCarthyдр., Lisp I Руководство программиста , стр. 88-91.
- ↑ Pitman, The Revised MacLisp Manual , p. 75.
- ↑ Стил и Габриэль, «Эволюция Лиспа», стр. 239–240.
- ↑ Pitman, The Revised MacLisp Manual , p. 62
- ↑ Стил и Габриэль, «Эволюция Лиспа», стр. 231-232.
- ↑ Стил и Габриэль, «Эволюция Лиспа», стр. 235.
- ↑ Pitman, The Revised MacLisp Manual , p. 182.
- ^ Питман, "Специальные формы в Лиспе", стр. 179.
- ↑ Стил и Габриэль, «Эволюция Лиспа», стр. 245–248
- ^ a b Жезл, "Теория Fexprs тривиальна", стр. 189.
- ^ Митчелл, "Об абстракции и выразительной силе языков программирования", раздел 7.
- ^ Шатт, "Vau-Calculi и теория fexprs".
Рекомендации
- Маккарти, Дж . ; Брайтон, Р .; Эдвардс, Д .; Фокс, П .; Ходс, Л .; Лакхэм, Д .; Малинг, К .; Парк, Д .; Рассел С. (март 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 г.
- Кент М. Питман, The Revised MacLisp Manual (субботнее вечернее издание), MIT Laboratory for Computer Science Technical Report 295, 21 мая 1983 г.
- Джон Н. Шатт, "Vau-Calculi и теория fexprs", доклад, Серия симпозиумов по языкам программирования и системам Новой Англии (NEPLS) , 18 октября 2007 г. Реферат получен 27 января 2008 г.
- Гай Л. Стил и Ричард П. Габриэль, «Эволюция Лиспа», ACM SIGPLAN Notices 28 no. 3 (март 1993 г.), стр. 231–270.
- Митчелл Ванд, "Теория Fexprs тривиальна" , Lisp и символические вычисления 10 no. 3 (май 1998 г.), стр. 189–199. По состоянию на 25 января 2008 г.