In common lisp, is it possible to take a form and macroexpand all the
macros inside a form (once) even when the form itself is not a macro
call? I assumed (wrongly) that macroexpand-1 would do this, but it
doesn't:
[1]> (defmacro square (x) `(* ,x ,x))
SQUARE
[2]> (macroexpand-1 '(square 10))
(* 10 10) ;
T
[3]> (macroexpand-1 '(+ (square 10) (square 10)))
(+ (SQUARE 10) (SQUARE 10)) ;
T
What I want is a macroexpander which will do this:
> (macroexpand*-1 '(+ (square 10) (square 10)))
(+ (* 10 10) (* 10 10))
T
In this case I can get the effect I want by mapcar'ing macroexpand-1
over the form, but if the macros were more deeply nested it wouldn't
work. It seems to me that this is a common enough thing to want that
I'm surprised if there isn't a built-in function to do this. Is
there?
Mike
Michael C. Vanier wrote:
> In common lisp, is it possible to take a form and macroexpand all the
> macros inside a form (once) even when the form itself is not a macro
> call? I assumed (wrongly) that macroexpand-1 would do this, but it
> doesn't:
>
> [1]> (defmacro square (x) `(* ,x ,x))
> SQUARE
> [2]> (macroexpand-1 '(square 10))
> (* 10 10) ;
> T
> [3]> (macroexpand-1 '(+ (square 10) (square 10)))
> (+ (SQUARE 10) (SQUARE 10)) ;
> T
>
> What I want is a macroexpander which will do this:
>
> > (macroexpand*-1 '(+ (square 10) (square 10)))
> (+ (* 10 10) (* 10 10))
> T
>
> In this case I can get the effect I want by mapcar'ing macroexpand-1
> over the form, but if the macros were more deeply nested it wouldn't
> work. It seems to me that this is a common enough thing to want that
> I'm surprised if there isn't a built-in function to do this. Is
> there?
No, there's "code walkers" or "macroexand-all" functions likely lying
around in your implementation for this.
I believe Dirk Gerrit explained this in:
http://alu.cliki.net/lisp-user-meeting-amsterdam-april-2004#code-walkers
[note: link seems down]
And Dick Waters:
http://www.merl.com/papers/TR93-17/
Random kvetching due to its absence, and yet another plug for the Lisp
Machine.
http://groups.google.com/groups?hl=en&lr=&safe=off&threadm=51emfpa15p.fsf%40corkie.nrl.navy.mil&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26safe%3Doff%26q%3Dmacroexpand-all%2Bstandard%26btnG%3DSearch%26meta%3Dgroup%253Dcomp.lang.lisp.*
In CLisp for example, it's called EXT:EXPAND-FORM:
CL-USER> (expand-form '(+ (square 10) (square 10)))
(+ (* 10 10) (* 10 10))
t
Incidentally that macro SQUARE could be subject to multiple expansion.
;) But I'm sure you don't care.
MfG,
Tayssir
Tayssir John Gabbour wrote:
> I believe Dirk Gerrit explained this in:
>
http://alu.cliki.net/lisp-user-meeting-amsterdam-april-2004#code-walkers
> [note: link seems down]
Sorry Dirk for misspelling your last name. (Gerrits) I'm really tired.
Can't even blame googlegroups's post-mangling.
MfG,
Tayssir
Excellent! Since I'm in fact using clisp, this is most useful ;-)
Also thanks for the other people who sent pointers to similar
solutions in different implementations.
Thanks also for the point about multiple expansion. My inexperience
is showing ;-)
Mike
"Tayssir John Gabbour" <···········@yahoo.com> wrote in message news:<························@c13g2000cwb.googlegroups.com>...
> Michael C. Vanier wrote:
> > In common lisp, is it possible to take a form and macroexpand all the
> > macros inside a form (once) even when the form itself is not a macro
> > call? I assumed (wrongly) that macroexpand-1 would do this, but it
> > doesn't:
> >
> > [1]> (defmacro square (x) `(* ,x ,x))
> > SQUARE
> > [2]> (macroexpand-1 '(square 10))
> > (* 10 10) ;
> > T
> > [3]> (macroexpand-1 '(+ (square 10) (square 10)))
> > (+ (SQUARE 10) (SQUARE 10)) ;
> > T
> >
> > What I want is a macroexpander which will do this:
> >
> > > (macroexpand*-1 '(+ (square 10) (square 10)))
> > (+ (* 10 10) (* 10 10))
> > T
> >
> > In this case I can get the effect I want by mapcar'ing macroexpand-1
> > over the form, but if the macros were more deeply nested it wouldn't
> > work. It seems to me that this is a common enough thing to want that
> > I'm surprised if there isn't a built-in function to do this. Is
> > there?
>
> No, there's "code walkers" or "macroexand-all" functions likely lying
> around in your implementation for this.
>
> I believe Dirk Gerrit explained this in:
> http://alu.cliki.net/lisp-user-meeting-amsterdam-april-2004#code-walkers
> [note: link seems down]
>
> And Dick Waters:
> http://www.merl.com/papers/TR93-17/
>
> Random kvetching due to its absence, and yet another plug for the Lisp
> Machine.
> http://groups.google.com/groups?hl=en&lr=&safe=off&threadm=51emfpa15p.fsf%40corkie.nrl.navy.mil&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26safe%3Doff%26q%3Dmacroexpand-all%2Bstandard%26btnG%3DSearch%26meta%3Dgroup%253Dcomp.lang.lisp.*
>
>
> In CLisp for example, it's called EXT:EXPAND-FORM:
>
> CL-USER> (expand-form '(+ (square 10) (square 10)))
> (+ (* 10 10) (* 10 10))
> t
>
> Incidentally that macro SQUARE could be subject to multiple expansion.
> ;) But I'm sure you don't care.
>
>
> MfG,
> Tayssir
Michael C. Vanier wrote:
> In common lisp, is it possible to take a form and macroexpand all the
> macros inside a form (once) even when the form itself is not a macro
> call? I assumed (wrongly) that macroexpand-1 would do this, but it
> doesn't:
>
> [1]> (defmacro square (x) `(* ,x ,x))
> SQUARE
> [2]> (macroexpand-1 '(square 10))
> (* 10 10) ;
> T
> [3]> (macroexpand-1 '(+ (square 10) (square 10)))
> (+ (SQUARE 10) (SQUARE 10)) ;
> T
>
> What I want is a macroexpander which will do this:
>
>
>>(macroexpand*-1 '(+ (square 10) (square 10)))
>
> (+ (* 10 10) (* 10 10))
> T
>
> In this case I can get the effect I want by mapcar'ing macroexpand-1
> over the form, but if the macros were more deeply nested it wouldn't
> work. It seems to me that this is a common enough thing to want that
> I'm surprised if there isn't a built-in function to do this.
I would say it would be an insanely uncommon thing. A minor point is
that an inscrutable explosion of code could result because of lisp
built-in macros. A bigger point is that I macroexpand when I want to
test/debug a macro. So (a) I would just aim it at (square 10), not:
(allthis (other code) (square 10) (square 20)
and (b) I probably am not debugging two macros at once (perish the
thought, actually) so even if square invoked a second macro I would
never have a need for the second macro to be expanded.
Implicit in this is that, if one practices proper macro hygiene,
including violating it when one knows full well what one is about, it
should never arise that a macro would expand improperly only when
expanded within some other particular macro, such that I would need to
expand nestedly, if you will.
my 2c.
kenny
--
Cells? Cello? Celtik?: http://www.common-lisp.net/project/cells/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
From: Coby Beck
Subject: Re: question about macro expansion
Date:
Message-ID: <_pJ9d.66$qU.4@clgrps13>
"Kenny Tilton" <·······@nyc.rr.com> wrote in message
···························@twister.nyc.rr.com...
> Michael C. Vanier wrote:
>> What I want is a macroexpander which will do this:
>>
>>>(macroexpand*-1 '(+ (square 10) (square 10)))
>>
>> (+ (* 10 10) (* 10 10))
>> T
>>
>> In this case I can get the effect I want by mapcar'ing macroexpand-1
>> over the form, but if the macros were more deeply nested it wouldn't
>> work. It seems to me that this is a common enough thing to want that
>> I'm surprised if there isn't a built-in function to do this.
>
> I would say it would be an insanely uncommon thing.
I have /wanted/ it but only in a nice hand-wavy "just what I want to see"
way. Many of my macros in my current project expand into other macros, and
I need to see what the lower level expand to.
I have to ctrl-M and then pick a piece and ctrl-M again etc...
> A minor point is that an inscrutable explosion of code could result
> because of lisp built-in macros.
This is definitely some nasty collateral damage...
--
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
·······@cs.caltech.edu (Michael C. Vanier) writes:
> What I want is a macroexpander which will [also expand subforms]
There's no such function in standard Common Lisp, but it's not
impossible to write one. It's often called macroexpand-all:
http://www.merl.com/reports/docs/TR93-17.pdf
http://www.pentaside.org/paper/code-walk-slides-gerrits.pdf
I have written a simple function called macroexpand-most, which does
most of the work of a full macroexpand-all:
http://www.hexapodia.net/pipermail/small-cl-src/2004-June/000017.html
--
Lars Brinkhoff, Services for Unix, Linux, GCC, HTTP
Brinkhoff Consulting http://www.brinkhoff.se/
> In common lisp, is it possible to take a form and macroexpand all
> the macros inside a form (once) even when the form itself is not a
> macro call?
If you're using PCL, you have such a thing: pcl::macroexpand-all.
common-lisp-user [1]: (defmacro square (x) `(* ,x ,x))
SQUARE
common-lisp-user [2]: (pcl::macroexpand-all '(+ (square 10) (square 10)))
(+ (* 10 10) (* 10 10))
--
Fred Gilham ······@csl.sri.com | See the lambs and the lions playin?
I join in and I drink the music. Holiness is the air I'm breathin'.
My faithful heroes break the bread and answer all of my questions.
Not to mention what the streets are made of. My heart's held hostage
by this love. -- Chris Rice, DEEP ENOUGH TO DREAM