(defmacro and
([] true)
([x] x)
([x & rest]
`(let [and# ~x]
(if and# (and ~@rest) and#))))
Clojure 是 Lisp 语言家族的一员。Lisp 的许多特性已经融入到其他语言中,但 Lisp 的代码即数据理念以及它的 宏系统 仍然使它与众不同。Clojure 将代码即数据系统从带括号的列表(S 表达式)扩展到向量和映射。因此,向量和映射可以用于宏语法,具有文字读取表示等。
Lisp 数据以及 Lisp 代码由 读取器 读取。读取的结果是表单所表示的数据结构。Clojure 可以编译表示代码的数据结构,并且在该过程中它会查找对宏的调用。当它看到一个宏时,它会调用该宏,将表单本身作为参数传递,然后使用宏的返回值来代替宏本身。因此宏是在编译时被调用的函数,用于执行代码的转换。由于代码是数据,所以整个 Clojure 库都可用于帮助转换。因此宏允许 Lisp 和 Clojure 支持语法抽象。您使用宏的原因与使用函数的原因相同——消除代码中的重复。宏应该保留在函数不足的情况下,例如当您需要控制评估、生成标识符等时。Clojure 的许多核心构造不是内置的基元,而是用户可以定义的宏。这里有 and
(defmacro and
([] true)
([x] x)
([x & rest]
`(let [and# ~x]
(if and# (and ~@rest) and#))))
请注意语法引号(`)的使用,它使定义宏变得容易,这些宏的表单模拟它们生成的表单。