Question

Essentially I am trying to code up a macro which will print out exactly some statement I am trying to evaluate, and the value it evaluates to.

What I have so far is the following:

(defmacro dbg (statement)
  (format t "~a: ~a" statement (eval statement)))

and by typing the following into the slime repl: (dbg (* 2 2)) I get the desired result which is:

"(* 2 2): 4"

However when I try to use it in the following function **:

(defun get-start-position (curr-prime)

  (dbg (/ (- (* curr-prime curr-prime) 3) 2))

  (/ (- (* curr-prime curr-prime) 3) 2))

slime reports that curr-prime is unbound (and just sticking everything in a let doesn't help). To be more specific the act of trying to compile the function get-start-position results in:

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.

Presumably (and the second warning baffles me), the error comes about because the macro is expanded before the function which calls it gets a chance to bind curr-prime to some value (am I correct here?). That said I have no clue how to get round this issue

What am I doing wrong?


** for what its worth I am coding up a prime sieve where the indicator array has the following elements:

(3,5,7,9, ...)

This particular function will get me the index of the square of a given prime

Was it helpful?

Solution

Not a pro on Lisp macros, but this will do:

(defmacro dbg (statement)
  (let ((result (gensym)))
  `(let ((,result ,statement))
     (format t "~a: ~a" ',statement ,result)
     ,result)))

then

(dbg (* 2 2))

=> (* 2 2): 4
4

and

(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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top