Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to re-write this Common Lisp macro avoiding the back-quote notation?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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)

Using 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?

Thanks.

>Solution :

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).

Since '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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading