Variable capture in CL can be avoided with few helpful macros.
(defmacro WITH-GENSYMS (syms &body body)
`(let ,(loop for s in syms collect `(,s (gensym)))
,@body))
(defmacro WITH-UNIQUE-NAMES (vars &body body)
`(let ,(loop for var in vars
collect `(,var (make-symbol ,(symbol-name var))))
,@body))
(defmacro REBINDING (vars &body body)
(loop for var in vars
for name = (make-symbol (symbol-name var))
collect `(,name ,var) into renames
collect ``(,,var ,,name) into temps
finally (return `(let ,renames
(with-unique-names ,vars
`(let (,,@temps)
,,@body))))))
(defmacro ONCE-ONLY ((&rest names) &body body)
(let ((gensyms (loop for n in names collect (gensym))))
`(let (,@(loop for g in gensyms collect `(,g (gensym))))
`(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n)))
,(let (,@(loop for n in names for g in gensyms collect `(,n ,g)))
,@body)))))
edit: added once-only