From everything I’ve read, Lisp’s macros are most useful for abstracting commonly-used patterns. Well, I quickly noticed a pattern that seemed ripe for abstraction, but after trying to do so for the better part of a week, I haven’t met with any notable success.
The pattern in question involves the gensym
function, which creates new symbols for use in other macros. Any function that I’ve seen using it, always requires two lines to do so: the first is a let
that assigns the results of a gensym
to variables, and the second is a back-quoted let
that assigns values to those newly-created symbols. It seemed to me that I should be able to create a macro that combined the two, so I could just call the new gensym-let
function to do both. In other words, I wanted to take this
(defmacro macrotest (n expr)
(let ((n2 (gensym)) (expr2 (gensym)))
`(let ((,n2 ,n) (,expr2 ,expr))
(loop for x below ,n2 collecting ,expr2))))
and turn it into this
(defmacro macrotest (n expr)
(gensym-let ((n2 n) (expr2 expr))
`(loop for x below ,n2 collecting ,expr2)))
instead.
I came up with a way to do it, and it works, but Steel Bank Common Lisp (SBCL) gives warnings about using unknown symbols whenever I use it. I’m a little leery of relying on it, because such warnings usually mean there really is a problem, even if it seems to work. Does anyone know whether there’s a simple way to do this or not? And if not, why?
I’ve found the answer! I’ll post it later, after an associate has a chance to puzzle out the answer for himself — he loves puzzles like this as much as I do, and I’d hate to spoil it for him.
I’ve just posted my answer here, for the curious.