Common Lisp recursive macro expansion

common-lisp, macros

Solution

`MACROEXPAND` takes a form and expands it. It does it multiple times until the form is no longer a macro form.

In your example, the top level call to `my-recursive-fact` is a macro form. The result form with the multiplication in front is not a macro form, since `*` is not a macro. It is a function. The form has an argument, which is a macro form. But `MACROEXPAND` does not look at those.

If you want to expand code on all levels, you need to use a code walker. Some Lisps have it in the IDE directly accessible, like Lispworks.

Problem

Once upon a time I was playing with macros and came up with this: ``` (defmacro my-recursive-fact (n) (if (= 0 n) '1 (let ((m (1- n))) `(* ,n (my-recursive-fact ,m))))) ``` And it worked. ``` CL-USER> (my-recursive-fact 5) 120 ``` So then I thought it could be a nice way to show students an example of recursion, if I expand this macro using `macroexpand`: ``` CL-USER> (macroexpand '(my-recursive-fact 5)) (* 5 (MY-RECURSIVE-FACT 4)) T ``` That is, no difference between `macroexpand-1` and `macroexpand` in this case. I'm sure that I'm missing some crucial point in understanding `macroexpand`, and HyperSpec says nothing special about recursive macros. And also I'm still curious to know if there is a way to expand such kind of macro to it's end.

Original source