Take 4 (alteration based on feedback from Rainer Joswig):(defmacro with-gensyms ((&rest names) &body body)  `(let ,(loop for n in names collect `(,n (gensym)))     ,@body))(defmacro let-alist ((&rest lookups) alist &body body)  (with-gensyms (alist-form)    `(let ((,alist-form ,alist))        (let ,(loop for l in lookups            if (keywordp l)             collect `(,(intern (symbol-name l)) (cdr (assoc ,l ,alist-form)))           else             collect `(,l (cdr (assoc ',l ,alist-form))))     ,@body))))This revision can still be used the same way> (defparameter test '((|foo| . 1) (:bar . 2) (baz . 3)))TEST> (let-alist (:bar |foo| baz) test       (list |foo| bar baz))(1 2 3)but the macro only expands the passed-in alist form once. The following is the output of slime-macroexpand-1:(LET ((#:G1299 TEST))  (LET ((BAR (CDR (ASSOC :BAR #:G1299)))        (|foo| (CDR (ASSOC '|foo| #:G1299)))        (BAZ (CDR (ASSOC 'BAZ #:G1299))))    (LIST |foo| BAR BAZ)))All comments welcome, but specifically (in order of descending importance),Can you think of a good docstring?Can you think of a situation wherein this would explode?Is there a built-in macro that does the same thing, or close to it?
with-alist-bind
lisp;common lisp;macros
The main problem with it is alist- the variable of the macro.CL-USER > (pprint (macroexpand-1 '(let-alist (:bar |foo| baz)                                      (this-function-takes-a-long-time-or-has-side-effects)                                    (list |foo| bar baz))))(LET ((BAR (CDR (ASSOC :BAR (THIS-FUNCTION-TAKES-A-LONG-TIME-OR-HAS-SIDE-EFFECTS))))      (|foo|       (CDR (ASSOC '|foo| (THIS-FUNCTION-TAKES-A-LONG-TIME-OR-HAS-SIDE-EFFECTS))))      (BAZ       (CDR (ASSOC 'BAZ (THIS-FUNCTION-TAKES-A-LONG-TIME-OR-HAS-SIDE-EFFECTS)))))  (LIST |foo| BAR BAZ))As you can see the function is expanded multiple times into the code.Rule 1: Always check the expansion for problems.Rule 2: Do not expand the same code multiple times into the code.Read 'On Lisp' by Paul Graham (free download available) for the various pitfalls of macros in Common Lisp and how to deal with those.For above you need to generate a new unique variable and bind the value once.