I am trying to learn Common Lisp with the book Common Lisp: A gentle introduction to Symbolic Computation. In addition, I am using SBCL, Emacs, and Slime.
In the last chapter, on Macros, the author presents examples to re-write the built-in
incf macro. He teaches the concept with two different approaches: using back-quote notation and without it. Such as:
(defmacro list-notation-my-incf (x) (list 'setq x (list '+ x 1))) (defmacro backquote-notation-my-incf (x) `(setq ,x (+ ,x 1)))
Later, the author introduces another example:
In the example below, TWO-FROM-ONE is a macro that takes a function
name and another object as arguments; it expands into a call to the
function with two arguments, both of which are the quoted object.
He only uses back-quote character to do it:
(defmacro two-from-one (func object) `(,func ',object ',object))
And it works as expected:
CL-USER> (two-from-one cons stack-overflow) (STACK-OVERFLOW . STACK-OVERFLOW)
slime-macroexpad-1, I have:
(CONS 'STACK-OVERFLOW 'STACK-OVERFLOW)
As an exercise that I created for myself, I tried doing the same, but avoiding the back-quote notation. Unfortunately, I could not make it work:
(defmacro list-two-from-one (func object) (list func (quote object) (quote object)))
Slime throws the error:
The variable OBJECT is unbound. [Condition of type UNBOUND-VARIABLE]
Doing a macro expansion, I see:
(CONS OBJECT OBJECT)
If I try a different approach, it seems to be closer, but it does not work either:
(defmacro list-two-from-one (func object) (list func object object))
Throws the error:
The variable STACK-OVERFLOW is unbound. [Condition of type UNBOUND-VARIABLE]
And, finally, the macro expansion indicates:
(CONS STACK-OVERFLOW STACK-OVERFLOW)
I feel stuck. How do I successfully re-write the macro without using back-quote notation?
What you are looking for is something like
(defmacro list-two-from-one (func object) (list func (list 'quote object) (list 'quote object)))
basically, the both of a macro should return the code, that, when evaluated, produced the desired result.
I.e., the macro body should produce
(CONS 'STACK-OVERFLOW 'STACK-OVERFLOW).
'a is the same as
(quote a), you want your macro to produce
(CONS (QUOTE STACK-OVERFLOW) (QUOTE STACK-OVERFLOW))
which is what my
defmacro above returns.