On Sun, Sep 5, 2010 at 5:24 AM, Kazimir Majorinc kazimir@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 (,@lists) ,form) ,@lists))
Now the classic WITH-GENSYMS:
(defmacro with-gensyms ((&rest n) &body body) `(let ,(mapticks `(,n (gensym ,(string n))) n) ,@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)) ,@body)))
-Peter