【发布时间】:2014-11-23 23:58:27
【问题描述】:
我有一个函数可以替换列表中某个符号的所有实例:
(defun replace-symbol-in-sexp-fn (symbol-to-replace new-symbol sexp)
(if (eq sexp nil)
sexp
(cons
(if (listp (car sexp))
(replace-symbol-in-sexp-fn symbol-to-replace new-symbol (car sexp))
(if (eq (car sexp) symbol-to-replace)
(setf (car sexp) new-symbol)
(car sexp)))
(replace-symbol-in-sexp-fn symbol-to-replace new-symbol (cdr sexp)))))
(defmacro replace-symbol-in-sexp (symbol-to-replace new-symbol sexp)
`(replace-symbol-in-sexp-fn ,symbol-to-replace ,new-symbol ,sexp))
(macroexpand-1 (replace-symbol-in-sexp '+ '* (+ 2 3)))
; => TYPE-ERROR "The value 5 is not of type LIST" if sexp has comma,
; => UNBOUND-VARIABLE "The variable SEXP is unbound" if sexp has no comma
我在尝试计算最终表达式时遇到类型错误或未定义变量错误,具体取决于最后一行中的 sexp 是否为逗号。我已经测试并替换-symbol-in-sexp-fn 在给出时可以工作,比如:
(replace-symbol-in-sexp-fn '+ '* '(+ 2 3)) ; => (* 2 3)
我现在尝试使用宏来生成它,这样就不必像'(+ 2 3) 那样引用sexp,这样我就可以使用任意lisp 代码运行replace-symbol-in-sexp-fn。显然,我可以 eval 并传入引用的 sexp 以替换-symbol-in-sexp-fn,例如:
(eval (replace-symbol-in-sexp-fn '+ '* '(+ 2 3))
但这是一种笨拙的模仿宏的尝试,所以我宁愿实际上只使用宏。有没有一种干净的方法来做我想要用宏做的事情?我错过了什么?
【问题讨论】:
-
“我收到类型错误或未定义变量错误”我在问题中看不到任何一个。你能举个例子吗?
-
经过精确编辑。
标签: macros lisp common-lisp quote