10.2.6 Lisp 宏求值

如果正在被求值的列表的第一个元素是宏对象,那么该列表就是一个 宏调用(macro call)。对宏调用进行求值时,列表中其余元素一开始并 不会 被求值。相反,这些元素本身会直接作为宏的参数使用。宏的定义会计算出一个替换形式,称为该宏的 展开(expansion) 式,用来替代原来的形式并进行求值。展开式可以是任意形式:自求值常量、符号或列表。如果展开式本身又是一个宏调用,这个展开过程会重复进行,直到得到其他类型的形式为止。

宏调用的常规求值,最终就是对展开式进行求值。不过,宏展开式不一定会被立即求值,甚至可能完全不求值 —— 因为其他程序也会对宏调用进行展开,它们可能会对展开式求值,也可能不会。

通常情况下,参数表达式不会在计算宏展开的过程中被求值,而是作为展开式的一部分出现,等到展开式被求值时才会被计算。

例如,给定如下定义的一个宏:

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

(cadr (assq 'handler list)) 这样的表达式就是一个宏调用,它的展开式为:

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

注意参数 (assq 'handler list) 会出现在展开式中。

关于 Emacs Lisp 宏的完整说明,See

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike