[pro] The Best Examples of "Code is Data"

Peter Seibel peter at gigamonkeys.com
Mon Sep 6 03:16:32 UTC 2010


On Sun, Sep 5, 2010 at 5:24 AM, Kazimir Majorinc <kazimir at chem.pmf.hr> wrote:

> Imagine that someone invited you to write the presentation "Five best CL
> macros ... I seen" or "Five best CL macros ... I wrote." What would you
> chose and why?

I look forward to seeing other folks' answers. In the meantime, here
are some very short versions of two classic macros that I came up with
the other day after someone on #lisp pointed out that my old version
of ONCE-ONLY was too complicated. I'm not really sure whether I should
be proud or ashamed of these but they're sort of fun and only a few
lines of code. (It's also possible I've botched something up and these
are busted in some way I haven't realized. If so, I'd be glad to hear
about it.)

First, a helper function of no particular interest:

  (defun gensyms (names)
    (mapcar (lambda (x) (gensym (string x))) names))

Then a slightly evil macro that abstracts the pattern of mapping over
lists and generating backquoted expressions from their contents. In
order to make things concise I assume the lists arguments are in fact
going to be symbols naming lists so I can reuse those symbols as names
of variables in the backquoted expressions:

(defmacro mapticks (form &rest lists)
  `(mapcar (lambda (, at lists) ,form) , at lists))

Now the classic WITH-GENSYMS:

  (defmacro with-gensyms ((&rest n) &body body)
    `(let ,(mapticks `(,n (gensym ,(string n))) n) , at body))

And ONCE-ONLY:

  (defmacro once-only ((&rest n) &body body &aux (g (gensyms n)))
    ``(let (,,@(mapticks ``(,',g ,,n) g n))
        ,(let (,@(mapticks `(,n ',g) n g)) , at body)))

-Peter

-- 
Peter Seibel
http://www.codequarterly.com/




More information about the pro mailing list