Alternative (MACROEXPAND ...)
Posted: Thu Mar 17, 2011 1:07 am
Hi all,
I've been programming in common-lisp for a couple of years now, and in that time I've grown somewhat frustrated with (MACROEXPAND ...) for debugging macros, because quite a lot of symbols in COMMON-LISP are macros with ugly expansions. e.g. (AND ...) and (OR ...) are changed to (IF ...) chains, (DEFUN ...) is defined in terms of a number of different sbcl internals, etc. This means that any reasonably complicated macro will expand into a lot of detail that you only need to see if you suspect that there is a bug in the macro provided by your implementation. So I decided to try and write my own version (How hard could it be?) that would special-case the COMMON-LISP macros, and call (MACROEXPAND-1 ...) only for unknown macros.
After quite a bit more effort than I expected (symbol macros interact with every form that binds variables, and I still need some kind of test suite to be sure that I've got it right for all of them) I've now got it working "good enough for me", and my next step is to figure out how to get it hooked up to C-c Ret in slime (my first attempt produced only errors).
I'm wondering whether this would be useful to others?
There are some caveats: some macros I wrote expanders for purely from my (mis?)understanding of the hyperspec (most of the condition handling stuff and PROGV spring to mind here), there may easily be some bugs in the ones that I *have* used regularly, and I've not even attempted expanders for DEFCLASS, DEFINE-COMPILER-MACRO, DEFINE-METHOD-COMBINATION, DEFINE-MODIFY-MACRO, DEFINE-SETF-EXPANDER, DEFSETF, DEFSTRUCT, DEFTYPE and (probably most important for people that choose to use it) LOOP.
I've been programming in common-lisp for a couple of years now, and in that time I've grown somewhat frustrated with (MACROEXPAND ...) for debugging macros, because quite a lot of symbols in COMMON-LISP are macros with ugly expansions. e.g. (AND ...) and (OR ...) are changed to (IF ...) chains, (DEFUN ...) is defined in terms of a number of different sbcl internals, etc. This means that any reasonably complicated macro will expand into a lot of detail that you only need to see if you suspect that there is a bug in the macro provided by your implementation. So I decided to try and write my own version (How hard could it be?) that would special-case the COMMON-LISP macros, and call (MACROEXPAND-1 ...) only for unknown macros.
After quite a bit more effort than I expected (symbol macros interact with every form that binds variables, and I still need some kind of test suite to be sure that I've got it right for all of them) I've now got it working "good enough for me", and my next step is to figure out how to get it hooked up to C-c Ret in slime (my first attempt produced only errors).
I'm wondering whether this would be useful to others?
There are some caveats: some macros I wrote expanders for purely from my (mis?)understanding of the hyperspec (most of the condition handling stuff and PROGV spring to mind here), there may easily be some bugs in the ones that I *have* used regularly, and I've not even attempted expanders for DEFCLASS, DEFINE-COMPILER-MACRO, DEFINE-METHOD-COMBINATION, DEFINE-MODIFY-MACRO, DEFINE-SETF-EXPANDER, DEFSETF, DEFSTRUCT, DEFTYPE and (probably most important for people that choose to use it) LOOP.