From: Michael C. Vanier
Subject: question about macro expansion
Date: 
Message-ID: <c5f1726e.0410072132.70aece50@posting.google.com>
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

From: Tayssir John Gabbour
Subject: Re: question about macro expansion
Date: 
Message-ID: <1097216521.223525.230300@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
From: Tayssir John Gabbour
Subject: Re: question about macro expansion
Date: 
Message-ID: <1097216771.236383.235770@c13g2000cwb.googlegroups.com>
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
From: Michael C. Vanier
Subject: Re: question about macro expansion
Date: 
Message-ID: <c5f1726e.0410081648.16e082d5@posting.google.com>
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
From: Kenny Tilton
Subject: Re: question about macro expansion
Date: 
Message-ID: <RXp9d.13197$4C.3015034@twister.nyc.rr.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.

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")
From: Lars Brinkhoff
Subject: Re: question about macro expansion
Date: 
Message-ID: <85r7o9btor.fsf@junk.nocrew.org>
·······@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/
From: Fred Gilham
Subject: Re: question about macro expansion
Date: 
Message-ID: <u7is9lax0q.fsf@snapdragon.csl.sri.com>
> 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