当宏观控制在elisp中流动时

时间:2015-01-29 14:46:32

标签: emacs elisp

来自subr.el

when宏代码
(defmacro when (cond &rest body)
  (declare (indent 1) (debug t))
  (list 'if cond (cons 'progn body)))

这里,最后一个表格很复杂,如

(list 'if cond (cons 'progn body))

构建列表时,是否已经对condbody表单进行了评估? 为什么程序员在一个地方使用list& cons在另一个地方?它们都不是采取多种形式和列出一份清单?

(list 'if cond (.......))
(cons 'progn body)

2 个答案:

答案 0 :(得分:5)

宏对代码进行操作。因此,当宏when被扩展(即,调用宏扩展函数)时,符号condbody被绑定到您编写的表达式(符号或列表)。

,例如,如果你写

(when (plusp 1)
  (print 'yes)
  (+ 1 2 3))

使用绑定到的参数调用macroexpansion:

cond = (plusp 1)
body = ((print 'yes) (+ 1 2 3))

因此表达式

(list 'if cond (cons 'progn body))

回到

(let ((cond '(plusp 1))
      (body '((print 'yes) (+ 1 2 3))))
  (list 'if cond (cons 'progn body)))
==> (if (plusp 1) (progn (print (quote yes)) (+ 1 2 3)))

这正是你想要的。

最后,list and cons完全不同,请阅读他们的文档( C-h f list RET & c)和the fine manual

答案 1 :(得分:3)

listcons之间的差异:

(list 'progn '((foo) (bar)))
;;=> (progn ((foo) (bar)))

(cons 'progn '((foo) (bar)))
;;=> (progn (foo) (bar))