特殊表格和宏之间是否存在实际差异?他们有什么不同?
答案 0 :(得分:19)
这些术语不完全是同义词,但它们也不是排他性的(这个答案假定为Scheme):
eval
所有子表达式,然后apply
第一个的结果到其他子结果的列表。)所以你可以说“特殊形式”是一个与接口或语义相关的术语,而“宏”是与实现相关的术语。 “特殊形式”表示“这些表达式使用特殊规则进行评估”,而“宏”表示“这里是评估某些表达式的特殊规则的实现。”
现在一个重要的事情是大多数Scheme特殊形式可以从一个非常小的原始核心定义为宏:lambda
,if
和宏。仅提供这些的最小Scheme实现仍然可以将其余部分实现为宏;最近的Scheme Reports通过引用可以用宏定义的“库语法”这样的特殊形式来区分。然而,在实践中,实际的Scheme系统通常将更丰富的形式集实现为原语。
从语义上讲,对表达式唯一重要的是使用什么规则来评估它,而不是如何实现该规则。因此,从这个意义上说,将特殊表单实现为宏还是原语并不重要。但另一方面,Scheme系统的实现细节经常“泄漏”,所以你可能会发现自己关心它......
答案 1 :(得分:11)
Lisp有一些语言原语,构成了Lisp形式:
(sin 2.1)
或类似((lambda (a b) (+ a b 2)) 3 4)
因此,特殊形式和宏之间最重要的实际区别是:特殊运算符是内置语法和语义。它们不能由开发人员编写。宏可以由开发人员编写。
答案 2 :(得分:4)
与特殊形式相比,宏形式可以进行宏扩展:
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
答案 3 :(得分:4)
对我来说,最实际的区别在于调试器:宏不会出现在调试器中;相反,宏的扩展中的(通常)模糊代码显示在调试器中。调试这样的代码真是太痛苦了,并且在开始依赖它们之前确保宏是坚如磐石的一个很好的理由。
答案 4 :(得分:2)
懒惰的超短答案
您可以随时编写自己的宏,但无法添加特殊表单而无需重新编译clojure。