Subject: Re: Macros From: Erik Naggum <erik@naggum.no> Date: 11 Aug 2002 23:38:11 +0000 Newsgroups: comp.lang.lisp Message-ID: <3238097891764805@naggum.no> * Thomas Stegen CES2000 | Is using a macro the same as returning a form from a function and using eval | on that form? Not precisely correct, but pretty close. A macro invocation is replaced by the return value from the macro (expansion) function, and this would, when evaluated or compiled, retain the lexical environment of the form. If you have used a macro in a different setting, which is certainly possible, you would find that it would not necessarily be evaluated. | Are the following two forms semantically equivalent? Yes, but this is a very special case that probably only confuses you. | They return the same result, but is there some subtle difference somewhere? Well, yes, the call to `eval´. :) | What about in the general case? In the general case, a macro is called when encountered in the recursive evaluation of each argument. Recall that `eval´ is a recursive function that effectively does (funcall (car form) (mapcar #'eval (cdr form))) for a function call. For this to work properly, the innermost `eval´ call must return a form that works in the environment of the next outer `eval´. For this to work, the macro function stored in the function slot of a macro takes two parameters, the whole macro form and the environment in which it is to be understood. This is not entirely trivial to explain, since the environment has to be queried to find the macro expansion function. You can try this, instead (let ((form '(madd))) (funcall (macro-function (car form)) form nil)) | And one more question. When is a macro expanded? When the form is about to acquire its meaning in the compiler or interpreter as defined by the language. This need not necessarily lead to evaluation right away, but sooner or later it normally will. At issue is how late this happens and how much environmental baggage the evaluation requires. In general, a macro is called with all the information that the enclosing forms present to the expander. This is much more than just `eval´ does. I think the best way to understand macros is to study an implementation of `eval´. Using the traditional Scheme textbooks and exercies for this will work, if you remember that a macro call is replaced by its return value and then re-interpreted as if the return value was the original form and that this does not mean immediate evaluation, except insofar as the macro function has side-effects. (E.g., it could perform some book-keeping.) -- Erik Naggum, Oslo, Norway Act from reason, and failure makes you rethink and study harder. Act from faith, and failure makes you blame someone and push harder.