Существуют ли какие-либо практические различия между специальными формами и макросами? В чем они отличаются?
Каковы практические различия между специальными формами и макросами?
Ответ 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.