I read / work through Practical Common Lisp. I am in the chapter on creating a test framework in Lisp.
I have a function "test- +" implemented below, and it works:
(defun test-+ () (check (= (+ 1 2) 3) (= (+ 5 6) 11) (= (+ -1 -6) -7)))
Remember, I said it works, that's why what follows is so perplexing ....
Here is the code that "test- +" means:
(defmacro check (&body forms) `(combine-results ,@(loop for f in forms collect `(report-result ,f ',f)))) (defmacro combine-results (&body forms) (with-gensyms (result) `(let ((,result t)) ,@(loop for f in forms collect `(unless ,f (setf ,result nil))) ,result))) (defmacro with-gensyms ((&rest names) &body body) `(let ,(loop for n in names collect `(,n (gensym))) ,@body)) (defun report-result (value form) (format t "~:[FAIL~;pass~] ... ~a~%" value form) value)
Now what I was doing is using Slime for macro distribution, step by step (using ctrl-c RET, which maps to macro-instance-1).
So, the call to "check" "test- +" expands to this:
(COMBINE-RESULTS (REPORT-RESULT (= (+ 1 2) 3) '(= (+ 1 2) 3)) (REPORT-RESULT (= (+ 5 6) 11) '(= (+ 5 6) 11)) (REPORT-RESULT (= (+ -1 -6) -7) '(= (+ -1 -6) -7)))
And then this macro expands to this:
(LET ((
And this is the TO code, right on this sentence, which does not work. If I insert this into the REPL, I get the following error (I use Clozure Common Lisp):
Unbound variable: #: G2867 [UNBOUND-VARIABLE type condition]
Now, if I take the same code, replace gensym with a variable name like "x", it works fine.
So, how can we explain the following surprises:
The "test- +" macro that causes all this works fine.
The macro volume of the Combined Results macro is not executed.
If I remove gensym from the "comb-results" macro decomposition, it really works.
The only thing I can guess is that you cannot use code that contains literary uses of gensyms. If so, why not, and how does it work? And if this is not an explanation, what is it?
Thanks.