Last night, I posted a long article on my
website about How I Know I Don't Know Enough About Lisp Macros.
For those who are unfamiliar with Lisp macros, you might enjoy reading
the article. I spend a good deal of setup time talking about how Lisp
macros kick the pants off of anything else you've heard called a
macro
before. For here, I will just excerpt the relevant bits
for those already familiar with Lisp macros in hopes that you might
give me guidance.
In the article, the main example that I work with is assuming that
you want to think about your code in terms of jump tables, but you
don't necessarily want to write a separate function for each item
in the table. You might write some macro like this:
(defmacro do-jump-table ( choice &rest options )
`(case ,choice
,@(loop for ii from 0
for oo in options
collecting (list ii oo))
(otherwise (do-something-graceful))))
Then, you could use it something like this:
(do-jump-table op-code
(write "NOOP")
(write "SYNC")
(when (>= +protocol-version+ 1)
(write "QUIT")))
Which would expand to:
(case op-code
(0 (write "NOOP"))
(1 (write "SYNC"))
(2 (when (>= +protocol-version+ 1)
(write "QUIT")))
(otherwise (do-something-graceful)))
The do-jump-table macro we just defined expands to one statement (one lisp form): (CASE ...). There are many times when I want my macro to expand to more than one form, however. This isn't legit. I still end up wanting to do it. For example, I might think that since I'm doing things with macros, that I might want the whole (CASE ...) construct to be in the main code and just have the macro expand the different cases:
(case op-code
(do-jump-table-cases (write "NOOP")
(write "SYNC")
(when (>= +protocol-version+ 1)
(write "QUIT")))
(otherwise (do-something-especially-graceful)))
Lisp says no. I can understand why it says that. In this case, it's easy enough to work around. But, in other cases, I end up flailing.
I feel that once I understand Lisp macros more completely, I won't keep trying to jam that gorgeous, round peg into all of these square holes in my logic. Anyone have any guidance here?