[slime-devel] suggested macroexpansion feature (and volunteer)

Helmut Eller heller at common-lisp.net
Wed Apr 13 10:42:09 UTC 2005


Chris Capel <pdf23ds at gmail.com> writes:

> I've been thinking about a neat feature I think could be implemented in a
> pretty straightforward way to help with the debugging of macros. There
> would be a new minor mode for a buffer containing some random form.
> Selecting any given subform of the buffer's form would macroexpand that
> one form, in place. Of course, it would have to respect macrolet's and
> symbol-macrolet's (which isn't that hard, really).

Suppose you have:

  (defmacro bar (x) `(1+ ,x))
  (defmacro foo (&rest body) '())
  (defun baz (y) (foo (bar y)))

and now you select (bar y) and let it expand.  What's the result?

> I already have the code written (included below) to expand such forms
> (perhaps buggy, perhaps incomplete). (One thing I know it doesn't do
> is find and respect macrolets that aren't present in the form until after
> some expansion. I don't know that this is a big deal.)

I suspect that your code doesn't pass down the environment correctly.
Every macro can potentially call macroexpand itself and I think you
have to expand every macro and pass the proper environemnt.  I think
in the general case you need a full codewalker.  Of course, a lot of
useful stuff can be done with something much simpler.  

[Isn't it shame that there's no portable codewalker for Common Lisp?]

> What's missing is the hooks into slime and Emacs. I don't want to bother
> with these (because they'd be a lot more effort for me) until I find
> whether there are any similar features currently available for SLIME. So
> has anyone done anything like this yet?

Not that I know of.  There are only the macroexpand{-1,-all} commands.

> If not, I suppose SLIME would need
> another minor mode with some cool keybindings and code to figure out what
> to pass as the list-indexes variable based on the position in the buffer
> (perhaps the hardest part?).

I have the impression that your list-indexes are similar to what CMUCL
calls "source-path".  You could use the code in SLIME's
source-path-parser.  Basically you can pass in a string (or stream)
and you get the corresponding sexp and a table which maps each
(sub)form to the start and the end position in the string.  So you
could give it the toplevel expression from the buffer as a string,
search the interval in the table which matches the buffer position
best and you know which subform to expand.  If you know the subform
(comparable with eq) you can compute the source-path.  But you
probably don't need that, since you already have the subform.

Hm... sounds like a lot of work.  Maybe there's something simpler.

Helmut.



More information about the slime-devel mailing list