2

Is it possible to write the following without using backquote?

(defmacro while (test &rest body)
  `(do ()
       ((not ,test))
     ,@body))

Thought I'd try this as an experiment to understand benefit of backquote.

I got as far as this:

(let* ((test '(> 10))
       (x 0)
       (body '((princ x) (incf x))))
  (list 'do nil (list (list 'not test))))

Which successfully generates:

(DO NIL ((NOT (> 10))))

To finish this I need a way to spread the n elements of the list body into the generated form. I know that's the entire purpose of the unquote splice ,@ but is this actually impossible without it? Curious... It's similar to what apply does but I don't want to call a function at this point obviously.

mwal
  • 2,803
  • 26
  • 34

1 Answers1

5

In your case the body contains the remaining forms to be evaluated, and can be added with LIST*:

(let* ((test '(> 10))
       (x 0)
       (body '((princ x) (incf x))))
  (list* 'do
         nil   
         (list (list 'not test))
         body))

Another example, where the spliced list is not at the end:

`(,x ,@y ,z)

The above can be written without backquotes as:

(list* x (append y (list z)))
coredump
  • 37,664
  • 5
  • 43
  • 77