Lars Brinkhoff <lars.spam@nocrew.org> wrote:
+---------------
| Kent M Pitman <pitman@nhplace.com> writes:
| > you might have a construct like
| >
| > (defmacro my-let-if (condition bindings &body forms)
| > `(if ,condition
| > (let ,bindings ,@forms)
| (locally ,@forms))) ;slight alteration
|
| How do experienced Lispers write macros such as this to handle
| declarations in the body? I.e. if FORMS has any declarations for
| variables in BINDINGS, you would like to include those in the body of
| LET, but not in LOCALLY.
+---------------
I don't know the portable way, if any, but CMUCL provides an
extension to macro LAMBDA lists which helps with this, the
&PARSE-BODY (&optional body decls doc-strings) keyword, which
could be used to do what you want [I think]:
(defmacro my-let-if (condition bindings &body (forms decls))
(multiple-value-bind (binding-decls other-decls)
(split-decls bindings decls)
`(if ,condition
(let ,bindings ,@binding-decls ,@other-decls ,@forms)
(locally ,@other-decls ,@forms))))
where SPLIT-DECLS is left as an exercise for the reader. ;-} ;-}
By the way, here's how CMUCL uses &PARSE-BODY to define DEFUN itself:
(defmacro defun (&whole source name lambda-list &parse-body (body decls doc))
(multiple-value-bind (valid block-name)
(valid-function-name-p name)
(declare (ignore valid))
(let ((def `(lambda ,lambda-list
,@decls
(block ,block-name ,@body))))
`(c::%defun ',name #',def ,doc ',source))))
The DECLS are separated out so that they can be placed in front of
the BLOCK which wraps BODY (and names it so RETURN-FROM will work).
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607