我有以下宏:
(defparameter *current-state* 'foo)
(defmacro when-state ((state &key (test #'eq)) &body body)
`(when (funcall ,test *current-state* ,state)
,@body))
在 REPL 中使用它,无论是否指定关键参数,它都可以正常工作。
但是,在顶级defun
或lambda
变量声明中使用它时,如下所示:
(defun foo ()
(when-state ('foo)
(format t "Foo")))
然后该文件将无法使用 SBCL 编译,并出现以下错误:
; in: DEFUN FOO
; (SENTO.FSM:WHEN-STATE ('SENTO.FSM::FOO)
; (FORMAT T "Foo"))
; --> IF FUNCALL
; ==>
; 1
;
; caught ERROR:
; Objects of type COMPILED-FUNCTION can't be dumped into fasl files.
;
; note: The first argument never returns a value.
只有明确指定关键参数时,它才能顺利编译。
这里有什么问题?
看看区别:
在上面生成的源代码中,该函数
EQ
作为对象包含。这无法转储。现在在源中指定测试:
现在引用定义中的测试
WHEN-STATE
:看起来好多了……