我很难理解宏扩展是如何工作的。elisp 解释器处理这两个代码片段的方式有什么区别?
(defmacro foo (arg)
(message "arg is: %s" arg))
(foo "bar")
和:
(defmacro foo (arg)
`(message "arg is: %s" ,arg))
(foo "bar")
message
两者都显示一条消息并返回它。(defconst zzz 123)
(defmacro zzz1 (arg)
`(insert (format "arg is: %s" ,arg)))
(defmacro zzz2 (arg)
(insert (format "arg is: %s" arg)))
C-x C-e在 3 种形式之后使用上面的代码来评估。
现在评估这些:
(zzz1 zzz)
口译员...
zzz1
(insert (format "arg is: %s" zzz))
"arg is: 123"
当前缓冲区,然后返回nil
(在底部的回显区域中看到)(zzz2 zzz)
口译员...
zzz2
"arg is: zzz"
当前缓冲区并返回nil
nil
为nil
(在回声中看到在底部)这里最重要的“要点”是宏只是在解释器(编译器)启动之前对代码进行操作的函数。
这些函数对它们的参数进行不求值(即,在zzz1
and zzz2
、arg
iszzz
和 not中123
)。
它们像任何其他 lisp 函数一样被评估(例如,它们的主体中可以有宏形式;主体被包裹在一个隐含的progn
; &c 中)。
它们的返回值由解释器评估,而不是原始形式。