What is the best practice for selectively passing evaluated arguments to macroscopic form?
To clarify: the usefulness of macros lies in its ability to receive an invaluable parameter, in contrast to the default evaluation rule for function forms. However, legitimate use cases exist to evaluate macro arguments.
Consider a far-fetched example:
(defparameter *func-body* '((print i) (+ i 1)))
Suppose it would be nice that *func-body* can serve as the body of our-defun macro, which is defined as:
(defmacro our-defun (fun args &body body) `(defun ,fun ,args ,@body))
So after (our-defun foo (i) (+ 1 i)) we could say (foo 1) to get 2 . However, if we use (our-defun foo (i) *func-body*) , the result (foo 1) will be ((PRINT I) (+ I 1)) (i.e. the value is *func-body* ). It would be nice if we could force *func-body* to be evaluated as an argument to our-defun macro.
Currently I can come up with a technique for using compile and funcall for this, as in
(funcall (compile nil `(lambda () (our-defun foo (i) ,@*func-body*))))
after which (our-defun 1) prints 1 and returns 2 , as expected. I can come up with a case for doing this work with eval , but I would prefer to stay away from eval due to its features in scope.
This leads to my question at the beginning, is there an easier or native way to do this?
PS
An ill-conceived example is presented in the function (UPDATE-HOOK) , which uses two library macros (ADD-HOOK) and (REMOVE-HOOK) and it is necessary to evaluate its parameters. The technique used here is (funcall (compile nil `(lambda () ...))) .
(defun update-hook (hook hook-name &optional code) (funcall (compile nil `(lambda () (remove-hook ,hook ',hook-name)))) (unless (null code) (compile hook-name `(lambda () ,@code)) (funcall (compile nil `(lambda () (add-hook ,hook ',hook-name))))))