Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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