Curious?
I must be missing something...I defined a macro that defines a macro.
(defmacro defwrapper (name args &body body)
;; defines a macro that encapsulates its &body arg into a lambda and
;; calls a do-it routine with the lambda function. The do-it routine
;; contains the bulk of the the wrapper code. And the macro
;; generated wrapped code contains only a function call to the doit
;; routine.
(let ((g!fn-name (gensym))
(g!fn (gensym))
(g!body (gensym)))
`(progn
(defun ,g!fn-name (,@args ,g!fn)
,@(subst `(funcall ,g!fn) '&body body))
(defmacro ,name ((,@args) &body ,g!body)
`(,',g!fn-name ,,@args (lambda () ,@,g!body))))))
When I evaluate this macro, and then use the resulting new macro to define another symbol, it works just fine.
(defwrapper with-wrapped-thingy (a b c)
(let ((ans (startup-fn a)))
(unwind-protect
&body ;; <-- this is where a funcall will be placed
(shutdown ans b c))))
;; and now try to use the new macro
(with-wrapped-thingy (x y z)
(doit x y z))
==> expands to: (#:G31850 X Y Z (LAMBDA () (DOIT X Y Z)))
where #:G31850 is the name of the companion do-it function defined by defwrapper for with-wrapped-thingy.
But if I take the macro expansion of the newly created macro, evaluate it, and then try to apply it to produce a new binding, I get an error that the &body argument in the lambda expression is unbound.
The macro expansion for "with-wrapped-thingy" is:
(PROGN
(DEFUN #:G31872 (A B C #:G31873)
(LET ((ANS (STARTUP-FN A))) (UNWIND-PROTECT (FUNCALL #:G31873) (SHUTDOWN ANS B C))))
(DEFMACRO WITH-WRAPPED-THINGY ((A B C) &BODY #:G31874)
`(#:G31872 ,A ,B ,C (LAMBDA () ,@#:G31874))))
When I evaluate this expansion, and then use WITH-WRAPPED-THINGY, then I get the error:
(with-wrapped-thingy (x y z)
(doit x y z))
==> The variable #:G31874 is unbound.
Eh???