Lisp 调试宏-调用时取消绑定变量
从本质上讲,我试图编写一个宏,它将准确地打印出我试图计算的某个语句,以及它的计算结果 到目前为止,我掌握的情况如下:Lisp 调试宏-调用时取消绑定变量,lisp,Lisp,从本质上讲,我试图编写一个宏,它将准确地打印出我试图计算的某个语句,以及它的计算结果 到目前为止,我掌握的情况如下: (defmacro dbg (statement) (format t "~a: ~a" statement (eval statement))) 通过在slime repl中键入以下内容:(dbg(*2))我得到了期望的结果,即: "(* 2 2): 4" 但是,当我尝试在以下函数**中使用它时: (defun get-start-position (curr-prim
(defmacro dbg (statement)
(format t "~a: ~a" statement (eval statement)))
通过在slime repl中键入以下内容:(dbg(*2))我得到了期望的结果,即:
"(* 2 2): 4"
但是,当我尝试在以下函数**中使用它时:
(defun get-start-position (curr-prime)
(dbg (/ (- (* curr-prime curr-prime) 3) 2))
(/ (- (* curr-prime curr-prime) 3) 2))
slime报告说curr prime是未绑定的(只是将所有内容都粘贴在let中也无济于事)。更具体地说,尝试编译函数get start position的行为会导致:
2 compiler notes:
primes.lisp:27:3:
error:
during macroexpansion of (DBG (- # 3)). Use *BREAK-ON-SIGNALS* to intercept:
The variable CURR-PRIME is unbound.
primes.lisp: 29:9:
note:
deleting unreachable code
==>
CURR-PRIME
Compilation failed.
据推测(第二个警告让我困惑),之所以会出现错误,是因为宏在调用它的函数有机会将curr prime绑定到某个值之前被展开(我在这里正确吗?)。也就是说,我不知道如何回避这个问题
我做错了什么
**为了实现其价值,我编写了一个素筛,其中指示符数组包含以下元素: (3,5,7,9,…)
此特定函数将获取给定素数的平方的索引,而不是Lisp宏上的pro,但这将执行以下操作:
(defmacro dbg (statement)
(let ((result (gensym)))
`(let ((,result ,statement))
(format t "~a: ~a" ',statement ,result)
,result)))
然后
及
多亏了这一点,这确实有效(尽管它现在表明(在我的设计中)我需要修复一个bug,我应该找到一种方法,在调用宏时将curr prime扩展到它的值)。使用名称
result
不是一个好主意。这就是函数GENSYM
的作用:它生成一个符号,不能与其他名称冲突。@RainerJoswig是的,当然。。。编辑。非常感谢。@HexedAgain只需添加一个(dbg curr prime)
作为get start position
@uselpa的第一种形式,这就是我到目前为止使用它的方式;老实说,在我目前的水平上,我可能还没有完全准备好改进它。再次感谢你的帮助!记住:宏应该生成代码。你不生成代码。@Rainer Joswig我现在明白你的意思了。研究给出的解决方案,观察到我从未引用过任何东西,我发现我在宏中计算(格式t blah),而不是生成我想要的代码)。谢谢
(dbg (* 2 2))
=> (* 2 2): 4
4
(defun get-start-position (curr-prime)
(dbg (/ (- (* curr-prime curr-prime) 3) 2)))
(get-start-position 1)
=> (/ (- (* CURR-PRIME CURR-PRIME) 3) 2): -1
-1