2012-02-22 4 views
18

Существуют ли какие-либо практические различия между специальными формами и макросами? В чем они отличаются?Каковы практические различия между специальными формами и макросами?

+1

Возможный дубликат [Можно ли безопасно игнорировать разницу между макросом и встроенным?] (Http://stackoverflow.com/questions/5120780/can-one-safely-ignore-the-difference-between- a-macro-and-a-built-in) – amalloy

ответ

18

Эти термины не вполне синонимичны, но они не являются исключительными либо (этот ответ предполагает схему):

  • особая форма (также известный как синтаксис в отчетах Scheme) это выражение, которое не оценивается в соответствии с правилом по умолчанию для приложения-функции. (Правило по умолчанию, просто чтобы быть явным, является eval все подвыражения, а затем apply результат первой в списке результатов других.)
  • система макросов является функция языка что позволяет определять новые специальные формы внутри самого языка. A макрос - специальная форма, определяемая с использованием макросистемы.

Таким образом, можно сказать, что «особая форма» это термин, который относится к интерфейсу или семантики, в то время как «макро» это термин, который относится к реализации. «Специальная форма» означает «эти выражения оцениваются специальным правилом», а «макрос» означает «вот реализация специального правила для оценки некоторых выражений."

Теперь одна важная вещь, что большинство Scheme специальные формы могут быть определены как макросы из очень небольшого ядра примитивов: lambda, if и макросов Минимальная реализация схемы, которая обеспечивает только они могут по-прежнему осуществлять остальные как макросы;. недавние отчеты о схемах сделали это различие, обратившись к таким специальным формам, как «синтаксис библиотек», которые могут быть определены в терминах макросов. На практике, однако, практические системы Схемы часто реализуют более богатый набор форм в качестве примитивов.

Семантически говоря, единственное, что имеет значение для выражения, - это то, какое правило используется для его оценки, а не как это правило реализовано. Поэтому в этом смысле не важно, реализуется ли специальная форма как макро или примитив. Но, с другой стороны, детали реализации системы Scheme часто «утечки», поэтому вы можете заботиться об этом ...

+1

Вы можете реализовать' if' в качестве макроса поверх 'lambda' также. Это не очень эффективно, но это нужно знать. – amalloy

+0

Я чувствую, что этот ответ наиболее ясен. Поскольку он определяет 'special-form' в соответствии с его семантикой - то есть - не полагаясь на детали реализации. –

+1

@amalloy, меня интересует, как это можно сделать, есть ли у вас ссылка? –

4

В отличие от специальных форм, макросов формы могут быть macroexpanded:

CL-USER(1): (macroexpand '(with-slots (x y z) 
           foo 
          (format t "~&X = ~A" x))) 

(LET ((#:G925 FOO)) 
    (DECLARE (IGNORABLE #:G925)) 
    (DECLARE (SB-PCL::%VARIABLE-REBINDING #:G925 FOO)) 
    #:G925 
    (SYMBOL-MACROLET ((X (SLOT-VALUE #:G925 'X)) 
        (Y (SLOT-VALUE #:G925 'Y)) 
        (Z (SLOT-VALUE #:G925 'Z))) 
    (FORMAT T "~&X = ~A" X))) 
T 
+0

Привет, Matthias. В tAoAI Norvig утверждает, что 'setf' - особая форма. Однако это макроэкспозиция. Например: '(macroexpand '(setf test 4))' расширяется до '(SETQ TEST 4)' Может быть, есть ошибка в книге? Я также не вижу здесь 'setf': http://www.lispworks.com/documentation/lw60/CLHS/Body/03_ababa.htm#clspecialops – tsikov

11

Лисп имеет определенные примитивы языка, которые составляют лисповские формы:

  • буквальных данных: числа, строки, конструкции, ...
  • функциональные вызовы, например (sin 2.1) или подобные ((lambda (a b) (+ a b 2)) 3 4)
  • специальные операторы используется в особых формах. Это примитивные встроенные языковые элементы. См. Special Operators в Common Lisp. Они должны быть реализованы в интерпретаторе и компиляторе. Common Lisp не дает разработчику возможности вводить новые специальные операторы или предоставлять свою собственную версию. Инструмент синтаксического анализа кода должен понимать эти специальные операторы; эти инструменты обычно называются «кодовыми ходоками» в сообществе Lisp. Во время определения стандарта Common Lisp было удостоверено, что число очень мало и что все расширения в противном случае выполняются с помощью новых функций и новых макросов.
  • макросы: макросы - это функции, которые преобразуют исходный код. Преобразование произойдет рекурсивно, пока в исходном коде не останется макрос. Common Lisp имеет встроенные макросы и позволяет пользователю писать новые.

Таким образом, самое важное практическое отличие между специальными формами и макросами заключается в следующем: специальные операторы являются встроенным синтаксисом и семантикой. Они не могут быть написаны разработчиком. Макросы могут быть написаны разработчиком.

4

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

+1

Это проблема, если у вас нет отладчика макросов, но некоторые Lisps на самом деле. Например, в Racket есть тот, который вы даже можете использовать из [REPL] (http: //docs.racket-lang.org/xrepl/index.html# \ (xrepl._syntax \)). –

2

супер короткий ответ для ленивых

Вы можете написать свои собственные макросы в любое время вы хотите, если вы не можете добавлять специальные формы без перекомпиляции Clojure.

Смежные вопросы