10.2.6 Lisp 宏求值(DONE)

如果非空列表的第一个符号求值为 宏对象,那么这个列表称为 宏调用。当一个宏被求值时,列表余下元素并不会立刻被求值。相反的,这些未求值元素本身作为宏的参数。宏定义会计算出一个替代表达式,称为宏展开,来代替之前原本的宏表达式。宏展开可以为任何表达式:自求值常量,符号,或列表。如果宏展开中包含宏,那么Lisp会递归的展开所有宏。

通常的宏调用结束于宏展开。宏展开并不一定会被立刻求值,或者可能根本不会用于求值。其他的程序也可能会将宏展开,它们可能也可能不会对宏展开求值。

通查来说,参数表达式并不会被求值,而是会作为宏展开的一部分。当所有的宏都展开后,它们会被统一求值。

举个例子,给出以下的宏定义:

(defmacro cadr (x)
  (list 'car (list 'cdr x)))

表达式 (cadr (assq 'handler list)) 进行宏调用,会展开成:

(car (cdr (assq 'handler list)))

请注意,参数 (assq 'handler list) 出现在了展开结果中。

查阅 宏 章节,以获取 Emacs Lisp 宏 的完整介绍。

最后更新于