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