Here's a macro example. It's to prevent multiple evaluation when writing other macros. Each variable is rebound to a gensym that will then hold the value.

The effect is that each value is evaluated only once, up-front in the binding thus introduced (hence the alternate name once-only). An implementation is:

(defmacro rebinding (variables &body body) (loop with prefix = (symbol-name '#:re) for var in variables for g = (gensym prefix) for temp = `(gensym ,(string var)) collect `(,g ,temp) into gensyms collect ``(,,g ,,var) into temps collect `(,var ,g) into renames finally (return `(let ,gensyms `(let (,,.temps) ,(let ,renames ,@body))))))

In use:

(rebinding (x y z) `(quux (+ ,x ,y) (* ,x ,z)))

Applying macroexpand-1 to this expression produces (in backquote notation):

(LET ((#:RE23691 (GENSYM "X")) (#:RE23692 (GENSYM "Y")) (#:RE23693 (GENSYM "Z"))) `(LET ((,#:RE23691 ,X) (,#:RE23692 ,Y) (,#:RE23693 ,Z)) ,(LET ((X #:RE23691) (Y #:RE23692) (Z #:RE23693)) `(QUUX (+ ,X ,Y) (* ,X ,Z)))))

Propagating values from the outermost LET gives:

`(LET ((#:X23706 ,X) (#:Y23707 ,Y) (#:Z23708 ,Z)) ,(LET ((X '#:X23706) (Y '#:Y23707) (Z '#:Z23708)) `(QUUX (+ ,X ,Y) (* ,X ,Z))))

Evaluating the inner, comma-fronted LET reduces this to:

`(LET ((#:X23706 ,X) (#:Y23707 ,Y) (#:Z23708 ,Z)) (QUUX (+ #:X23706 #:Y23707) (* #:X23706 #:Z23708)))

In the above output, keep in mind that READing the same gensym twice would produce two different (uninterned) symbols. In the REPL:

? (eq '#:X23706 '#:X23706)

The *print-circle* option controls whether the printer will detect shared components.

An Exercise for the Reader

There's a variant where the body is "spliced" into the expansion. This would allow—intentionally or otherwise—for (say) declarations:

(rebinding (x y) `(declare (fixnum ,x ,y)) `(do-fixnum-stuff ,x ,y))

Hint: it's been posted to comp.lang.lisp.