I'm experiencing a problem with a macro that takes a list as one of its parameters when it's called inside a LOOP. There is obviously some cloudy thinking on my part about how macro parameters are handled, but I am having a hard time spotting where I am going wrong. A contrived example that shows my problem is given below. The macro works fine when I call it directly, but when pulling the parameters from a structured list in a LOOP, it fails to do what I expected. Trying to macroexpand it out (even in the loop) isn't showing me the issue (thought it might be right in front of me.) Any guidance is appreciated.
Thanks,
Sean
Code: Select all
;;; The code below shows a problem I'm having when trying to invoke a macro
;;; that accepts a list as one of the parameters while inside a LOOP.
;; Here is a sample macro. It generates a class and associated stream-formatter
;; based on the NAME and SLOT-LIST parameters.
(defmacro create-class-and-printer (class slot-list)
`(progn
(defclass ,class ()
,(loop for (slot value) in slot-list
collect (list slot :initform (string value))))
(defmethod print-object ((obj ,class) stream)
(format stream "~{~a ~}" (loop for (slot nil) in 'slot-list
collect (slot-value obj slot))))))
;; If I invoke the macro directly, it works just fine.
(create-class-and-printer spanish-dictionary ((one uno) (two dos) (three tres)))
;; But if I try to invoke the macro while iterating through a list, it appears
;; to have trouble with the slot-list parameter, and doesn't recognize it as a
;; LIST, but printing the type shows it as a CONS.
(let ((language-list '((spanish-dictionary ((one uno) (two dos) (three tres)))
(french-dictionary ((one un) (two deux) (three trois)))
(german-dictionary ((one ein) (two zwei) (three drei)))
(japanese-dictionary ((one ichi) (two ni) (three san))))))
(loop for (language dictionary) in language-list
do (format t "Dictionary is type: ~a~%" (type-of dictionary))
do (format t "Value of Dictionary is: ~a~%" dictionary)
do (format t "Is this a list? ~a~%" (listp dictionary))
do (create-class-and-printer language dictionary)))
;; I think this might have something to do with macro parameters being
;; "destructured" but am not clear on how to resolve it. My google searches
;; haven't turned up much, which either means I'm doing something extremely
;; dumb, extremely rare, or a combination of the two.