1 (in-package :alexandria
)
3 (defmacro with-unique-names
(names &body forms
)
4 "Binds each variable named by NAMES to a unique symbol."
5 `(let ,(mapcar (lambda (name)
6 `(,name
(gensym ,(symbol-name name
))))
10 (defmacro once-only
(names &body forms
)
11 "Evaluates FORMS with NAMES rebound to temporary variables,
12 ensuring that each is evaluated only once.
15 (defmacro cons1 (x) (once-only (x) `(cons ,x ,x)))
16 (let ((y 0)) (cons1 (incf y))) => (1 . 1)"
17 (let ((gensyms (make-gensym-list (length names
) "ONCE-ONLY")))
19 `(let ,(mapcar (lambda (g n
) (list g
`(gensym ,(string n
))))
21 ;; bind in final expansion
22 `(let (,,@(mapcar (lambda (g n
) ``(,,g
,,n
)) gensyms names
))
24 ,(let ,(mapcar #'list names gensyms
)
27 (defun parse-body (body &key documentation
)
28 "Parses BODY into documentation string, declarations, and remaining forms.
29 Documentation strings are recognized only if DOCUMENTATION is true. Returns
30 three values: list of remaining forms, list of declarations, and documentation
37 (setf current
(car body
))
38 (when (and documentation
(stringp current
) (not doc
) (cdr body
))
41 (when (starts-with 'declare current
)
42 (push (pop body
) decls
)
44 (values body
(nreverse decls
) doc
)))