我正在编写一个Common宏define-computation,它以特定的方式定义函数,并通过向定义函数的符号的属性列表中添加一个属性:computation来标记它们。
define-computation正在寻找具有:computation属性集的函数的函数的表单,并使用特定的代码对它们进行包装。
当我在REPL中工作时,下面的代码按预期工作,宏展开允许我验证定义的-计算是否由supervise-computation正确地包装。
CL-USER> (macroexpand-1 '(define-computation c-2 ()
(c-1)
(format t "~&Compute something 2")))
(PROG1
(DEFUN C-2 ()
(DECLARE (OPTIMIZE (SAFETY 3) (SPACE 3)))
(SUPERVISE-COMPUTATION
(C-1))
(FORMAT T "~&Compute something 2"))
(EXPORT 'C-2)
(SETF (GET 'C-2 :COMPUTATION) T))
T但是,当我的代码组织在ADSF系统中,以便c-1和c-2在文件中,而c-3在另一个文件中时,我看到为c-2生成的代码实际上并不是包装c-1。
(PROG1
(DEFUN C-2 ()
(DECLARE (OPTIMIZE (SAFETY 3) (SPACE 3)))
(C-1)
(FORMAT T "~&Compute something 2"))
(EXPORT 'C-2)
(SETF (GET 'C-2 :COMPUTATION) T))对于SBCL和CCL64,这似乎是正确的。
我猜想这是由宏扩展和加载/编译逻辑的交互造成的,但我对Lisp的这些方面不够精通,无法解释和解决不想要的行为。
给定下面的代码,我如何将其组织在一个ADSF模块中,以便在一个文件中定义C1和C-2,在另一个文件中定义C-3,从而使C-2的宏扩展具有(SUPERVISE-COMPUTATION (C-1))形式,而不是在加载系统时只使用(C-1)。(同样,在REPL中计算下面的表单不会显示问题。)
(defmacro supervise-computation (&body body-forms)
"Supervise the computation BODY-FORMS."
`(progn
(format t "~&---> Computation starts")
,@body-forms
(format t "~&---> Computation stops")))
(defun define-computation/wrap-computation-forms (body-forms)
"Walks through BODY-FORMS and wrap computation forms in a fixture."
(labels
((is-funcall-p (form)
(when (and (listp form) (not (null form)) (symbolp (first form)) (listp (rest form)))
(case (first form)
((funcall apply)
(second form))
(t (first form)))))
(is-computation-form-p (form)
(get (is-funcall-p form) :computation))
(wrap-computation-forms (form)
(cond
((is-computation-form-p form)
`(supervise-computation ,form))
((is-funcall-p form)
(cons (first form) (mapcar #'wrap-computation-forms (rest form))))
(t
form))))
(mapcar #'wrap-computation-forms body-forms)))
(defmacro define-computation (computation-name computation-args &body body)
`(prog1
(defun ,computation-name ,computation-args
(declare (optimize (safety 3) (space 3)))
,@(define-computation/wrap-computation-forms body))
(export (quote ,computation-name))
(setf (get (quote ,computation-name) :computation) t)))
(define-computation c-1 ()
(format t "~&Compute something 1"))
(define-computation c-2 ()
(c-1)
(format t "~&Compute something 2"))
(define-computation c-3 ()
(c-2)
(format t "~&Compute something 3"))发布于 2022-04-02 04:39:14
睡在上面,看看别人的代码(谢谢你的回指),我可以想出一个更好的方法来编写宏
(defmacro define-computation (computation-name computation-args &body body)
(setf (get computation-name :computation) t)
`(prog1
(defun ,computation-name ,computation-args
(declare (optimize (safety 3) (space 3)))
,@(define-computation/wrap-computation-forms body)
(export (quote ,computation-name))))这将确保在宏计算时设置属性。
https://stackoverflow.com/questions/71713291
复制相似问题