From: Coby Beck
Subject: hanging macros
Date: 
Message-ID: <AVCsc.9012$L.2007@news-server.bigpond.net.au>
Dear Group,

I have delibrately ignored eval-when but I have a feeling it may actually be
there for a reason and one I now need to understand.

I have macros that expand into macros that expand into macros and have
thought myself very clever at times.  Now I have a problem...

I don't know if code samples would mean much so I will describe the symptoms
and hope it will be enough for a diagnosis.

I load a file that loads a slew of other files that are a database
specification in lisp-macro-speak.  They are not compiled since they are not
for running but for reading.  They are full of many similar forms and I have
been doing it for months.  Now I have a file that hangs on loading.  This
happened before in a different file but only on clisp not LW and some
seemingly irrelevant modification made it go away so I happily blamed other
people.  Now its back, and apparently my fault and reproducible in an
environment I'm more comfortable in.  I can't however get anything more
informative than hanging with no response to ctrl-breaks.

I can grab the offending form and macroexpand it at the top level -
sometimes.  I can eval the expansion in two halves.  I can not just eval the
form itself.  I put a break in the file but could not macroexpand the form
in the debugger.  I am confident it is hanging during macroexpansion.  These
macros are all defined in other files compiled and loaded before hand.

Is that enough to get some help?  Am I breaking some basic rules?

TIA for attention and responses.

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")

NB after my recent scolding for not RTFMing I did do that but by the fifth
reading of (defmacro loser ...) I felt sure that was meant as a personal
attack...)

From: Kenny Tilton
Subject: Re: hanging macros
Date: 
Message-ID: <zHFsc.60046$mX.20142432@twister.nyc.rr.com>
Coby Beck wrote:
> Dear Group,
> 
> I have delibrately ignored eval-when but I have a feeling it may actually be
> there for a reason and one I now need to understand.
> 
> I have macros that expand into macros that expand into macros and have
> thought myself very clever at times.  Now I have a problem...
> 
> I don't know if code samples would mean much so I will describe the symptoms
> and hope it will be enough for a diagnosis.
> 
> I load a file that loads a slew of other files that are a database
> specification in lisp-macro-speak.  They are not compiled since they are not
> for running but for reading.

This gave me pause. You are simply processing the macro-expansion?

   They are full of many similar forms and I have
> been doing it for months.  Now I have a file that hangs on loading.  This
> happened before in a different file but only on clisp not LW and some
> seemingly irrelevant modification made it go away so I happily blamed other
> people.  Now its back, and apparently my fault and reproducible in an
> environment I'm more comfortable in.  I can't however get anything more
> informative than hanging with no response to ctrl-breaks.
> 
> I can grab the offending form and macroexpand it at the top level -
> sometimes.  I can eval the expansion in two halves.  I can not just eval the
> form itself.  I put a break in the file but could not macroexpand the form
> in the debugger.  I am confident it is hanging during macroexpansion.  These
> macros are all defined in other files compiled and loaded before hand.
> 
> Is that enough to get some help?  Am I breaking some basic rules?

How about sprinkling some print statements around?

(defmacro print-on-lines (tag &rest stuff)
   `(progn
      ,@(prog2
          (format t "~&print-on-lines> begin ~a" tag)
            (mapcar (lambda (s)
                      (format t "~&print-on-lines> stuff ~a" s)
                      `(print (list ,tag ,s)))
              stuff)
          (format t "~&print-on-lines> end ~a" tag))))

(macroexpand-1 '(print-on-lines :hi-mom 1 2 3 a b c))
=>
print-on-lines> begin HI-MOM
print-on-lines> stuff 1
print-on-lines> stuff 2
print-on-lines> stuff 3
print-on-lines> stuff A
print-on-lines> stuff B
print-on-lines> stuff C
print-on-lines> end HI-MOM
(PROGN (PRINT (LIST :HI-MOM 1)) (PRINT (LIST :HI-MOM 2))
        (PRINT (LIST :HI-MOM 3)) (PRINT (LIST :HI-MOM A))
        (PRINT (LIST :HI-MOM B)) (PRINT (LIST :HI-MOM C)))
T

kenny

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Coby Beck
Subject: Re: hanging macros
Date: 
Message-ID: <k7Ssc.11005$L.2622@news-server.bigpond.net.au>
"Kenny Tilton" <·······@nyc.rr.com> wrote in message
····························@twister.nyc.rr.com...
> Coby Beck wrote:
> > I load a file that loads a slew of other files that are a database
> > specification in lisp-macro-speak.  They are not compiled since they are
not
> > for running but for reading.
>
> This gave me pause. You are simply processing the macro-expansion?

Ultimately the bottom layer of macros expand into function calls that use
the results of processing data that was handed to the top levels.  Like
reading a config file.

Thanks, all, for the suggestions, I found the problem and it was not an
eval-when issue at all, it was a question of data-ownership and destructive
list processing.

One of the side effects of one kind of form is the storing of list structure
in a hash-table (store-field-group name entity fields).  Later
macro-expansions retrieve that data (get-field-group name entity).  I found
a use of MAPCAN on data retrieved this way.  So I made get-field-group more
defensive and returned a copied list and the problem vanished.  Gotta love
"undefined consequences".

In terms of The Right Thing the fault is really in the caller for destroying
data it did not own, I will visit that.  But what do people think about
using the defensive approach as well?  Is that in the lisp spirit or should
I just rely on proper usage and leave this data unprotected in case there is
an unforseen but legitimate need to do something destructive?

Seeing as my current user base (me) is not trustworthy I'll leave the
defenses in place to avoid future bug reports and rethink it all when I do
that major refactoring which should be Real Soon Now.

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Thomas A. Russ
Subject: Re: hanging macros
Date: 
Message-ID: <ymivfihrf9x.fsf@sevak.isi.edu>
"Coby Beck" <·····@mercury.bc.ca> writes:

> In terms of The Right Thing the fault is really in the caller for destroying
> data it did not own, I will visit that.  But what do people think about
> using the defensive approach as well?  Is that in the lisp spirit or should
> I just rely on proper usage and leave this data unprotected in case there is
> an unforseen but legitimate need to do something destructive?

I suppose you can do that, but I would tend to rely on proper usage so
that I don't needlessly cons in the case where nothing destructive
happens to the result.  Building consing in at a low level just seems
like a bad idea.  I'd rather have the consumer do the consing where it
is needed.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Alain Picard
Subject: Re: hanging macros
Date: 
Message-ID: <87ekp895ft.fsf@memetrics.com>
"Coby Beck" <·····@mercury.bc.ca> writes:

> I have delibrately ignored eval-when but I have a feeling it may actually be
> there for a reason and one I now need to understand.

> I have macros that expand into macros that expand into macros and have
> thought myself very clever at times.  Now I have a problem...

You probably already know this, but sometimes it's saying the
same thing in many different ways which finally brings it home, so:

  The basic way to think about this is: if you have 2 macros
  in a file, say A and B, and the compiler needs to invoke
  A to compile the macroexpansion code of B, A should be
  surrounded in an eval-when.

Right?  So it's OK if the body of B has calls to A inside the
backquote, because that's just a text form.  But the following:

(defmacro b (.....)
  (let ((A (...)))
       ...
      `(foo ...))))  <== the form which is finally returned

won't work unless the compiler knows the definition of A at the
time it's trying to compile (DEFMACRO B ...).  

Help any?


p.s. I have no idea why/how your loading could be "hanging".  Could
it be misinterpreting something which sends it into an infinite loop?
Is it chewing CPU while it's hung?  Or worse, do the macroexpansions
perform i/o at compile time?!  
From: Duane Rettig
Subject: Re: hanging macros
Date: 
Message-ID: <4smdowaki.fsf@franz.com>
Alain Picard <············@memetrics.com> writes:

> "Coby Beck" <·····@mercury.bc.ca> writes:
> 
> > I have delibrately ignored eval-when but I have a feeling it may actually be
> > there for a reason and one I now need to understand.
> 
> > I have macros that expand into macros that expand into macros and have
> > thought myself very clever at times.  Now I have a problem...
> 
> You probably already know this, but sometimes it's saying the
> same thing in many different ways which finally brings it home, so:
> 
>   The basic way to think about this is: if you have 2 macros
>   in a file, say A and B, and the compiler needs to invoke
>   A to compile the macroexpansion code of B, A should be
>   surrounded in an eval-when.
> 
> Right?

No, that's not right.  See 3.2.3.1.1 (or see it online at):
http://www.franz.com/support/documentation/6.2/ansicl/subsubsu/processi.htm

You can also find clues that support this in whatever implementation
you are using, by macroexpanding the defmacro form.  For example,
in Allegro CL:

CL-USER(1): (pprint (macroexpand '(defmacro A (x) `(foo ,x))))

(PROGN (EVAL-WHEN (:COMPILE-TOPLEVEL)
         (EXCL::CHECK-LOCK-DEFINITIONS-COMPILE-TIME 'A 'FUNCTION
           'DEFMACRO (FBOUNDP 'A)))
       (EVAL-WHEN (:COMPILE-TOPLEVEL)
          [ ... ])
       [ ... ])

Note that the necessary eval-when is _already_ there.

>  So it's OK if the body of B has calls to A inside the
> backquote, because that's just a text form.  But the following:
> 
> (defmacro b (.....)
>   (let ((A (...)))
>        ...
>       `(foo ...))))  <== the form which is finally returned
> 
> won't work unless the compiler knows the definition of A at the
> time it's trying to compile (DEFMACRO B ...).  

But the compiler does know the definition of A if A is defined
earlier in the file than the usage of B (and if it's defined later,
then no amount of eval-when magic is going to allow the macroexpansion
of B to find A anyway ...)

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Barry Margolin
Subject: Re: hanging macros
Date: 
Message-ID: <barmar-42D946.16274425052004@comcast.dca.giganews.com>
In article <·············@franz.com>, Duane Rettig <·····@franz.com> 
wrote:

> But the compiler does know the definition of A if A is defined
> earlier in the file than the usage of B (and if it's defined later,
> then no amount of eval-when magic is going to allow the macroexpansion
> of B to find A anyway ...)

But it's put in the run-time environment, not the compile-time 
environment.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Duane Rettig
Subject: Re: hanging macros
Date: 
Message-ID: <4k6z0f3dt.fsf@franz.com>
Barry Margolin <······@alum.mit.edu> writes:

> In article <·············@franz.com>, Duane Rettig <·····@franz.com> 
> wrote:
> 
> > But the compiler does know the definition of A if A is defined
> > earlier in the file than the usage of B (and if it's defined later,
> > then no amount of eval-when magic is going to allow the macroexpansion
> > of B to find A anyway ...)
> 
> But it's put in the run-time environment, not the compile-time 
> environment.

Um, no - again, in 3.2.3.1.1, this time in the last paragraph:

  "The next figure lists macros that make definitions available both
   in the compilation and run-time environments."
 [the table given includes defmacro, so yes, the definition is indeed
  guaranteed to be in the compile-time and run-time environments]

What is also stated in that paragraph are disclaimers about any
guarantees of survival or cross-talk between various environments,
but that does not change the fact that at compile-file-time, macro
A is available for macroexpansion as referenced in a macroexpansion
of macro B, within that compile-file.

Note that I was not responding to Coby Beck's statement about having
macros survive a compile-file for later usage (one of those
cross-environment questions), but instead to Alain Picard's rather
strong (and incorrect) statement with a description that is
most obviously interpreted as being within the same compile-file
(though he doesn't say so, and of course it is always possible to
ask that question of the implementation).  But I was only responding
to his specific paragraph, rather than to the larger issue of when
definitions are and are not guaranteed to be available to what...

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Svein Ove Aas
Subject: Re: hanging macros
Date: 
Message-ID: <34Psc.3936$eH3.70632@news4.e.nsc.no>
Duane Rettig wrote:

> Alain Picard <············@memetrics.com> writes:
> 
>> "Coby Beck" <·····@mercury.bc.ca> writes:
>> 
>> > I have delibrately ignored eval-when but I have a feeling it may
>> > actually be there for a reason and one I now need to understand.
>> 
>> > I have macros that expand into macros that expand into macros and
>> > have
>> > thought myself very clever at times.  Now I have a problem...
>> 
>> You probably already know this, but sometimes it's saying the
>> same thing in many different ways which finally brings it home, so:
>> 
>>   The basic way to think about this is: if you have 2 macros
>>   in a file, say A and B, and the compiler needs to invoke
>>   A to compile the macroexpansion code of B, A should be
>>   surrounded in an eval-when.
>> 
>> Right?
> 
> No, that's not right.  See 3.2.3.1.1 (or see it online at):
>
http://www.franz.com/support/documentation/6.2/ansicl/subsubsu/processi.htm
> 
> You can also find clues that support this in whatever implementation
> you are using, by macroexpanding the defmacro form.  For example,
> in Allegro CL:
> 
> CL-USER(1): (pprint (macroexpand '(defmacro A (x) `(foo ,x))))
> 
> (PROGN (EVAL-WHEN (:COMPILE-TOPLEVEL)
>          (EXCL::CHECK-LOCK-DEFINITIONS-COMPILE-TIME 'A 'FUNCTION
>            'DEFMACRO (FBOUNDP 'A)))
>        (EVAL-WHEN (:COMPILE-TOPLEVEL)
>           [ ... ])
>        [ ... ])
> 
> Note that the necessary eval-when is _already_ there.
> 
>>  So it's OK if the body of B has calls to A inside the
>> backquote, because that's just a text form.  But the following:
>> 
>> (defmacro b (.....)
>>   (let ((A (...)))
>>        ...
>>       `(foo ...))))  <== the form which is finally returned
>> 
>> won't work unless the compiler knows the definition of A at the
>> time it's trying to compile (DEFMACRO B ...).
> 
> But the compiler does know the definition of A if A is defined
> earlier in the file than the usage of B (and if it's defined later,
> then no amount of eval-when magic is going to allow the macroexpansion
> of B to find A anyway ...)

OK, so how do I define mutually recursive macros?
No, I'm not planning to do it, but it would be nice to know how.

Oh, and another thing: Recently I had occasion to use macros in a loop
form, to make loop terms. It didn't work out too well.

What I wanted was a macro expanding into something like
(unless f(1) collect a
unless f(2) collect b ..and so on, for about a hundred iterations.

I wound up not using loop at all, but what I tried to do was to have the
macro output spliced into an existing loop form. Is there a way to do
this, or do I need to have the macro expand into the entire loop form?
From: Duane Rettig
Subject: Re: hanging macros
Date: 
Message-ID: <4fz9of2wq.fsf@franz.com>
Svein Ove Aas <··············@brage.info> writes:

> > But the compiler does know the definition of A if A is defined
> > earlier in the file than the usage of B (and if it's defined later,
> > then no amount of eval-when magic is going to allow the macroexpansion
> > of B to find A anyway ...)
> 
> OK, so how do I define mutually recursive macros?

Note carefully what I said: "the macroexpansion of B to find A",
and _not_ "B to find A".

Mutually recursive macros are easy enough; as long as you make
sure of your terminations, simply define them, but make sure not
to actually macroexpand any in a cycle within a file before the
point in the file when the whole cycle of macros is defined.

> No, I'm not planning to do it, but it would be nice to know how.
> 
> Oh, and another thing: Recently I had occasion to use macros in a loop
> form, to make loop terms. It didn't work out too well.
> 
> What I wanted was a macro expanding into something like
> (unless f(1) collect a
> unless f(2) collect b ..and so on, for about a hundred iterations.
> 
> I wound up not using loop at all, but what I tried to do was to have the
> macro output spliced into an existing loop form. Is there a way to do
> this, or do I need to have the macro expand into the entire loop form?

I always suggest (pprint (macroexpand '<form>)) whenever the behavior
is unclear; even for putatively simple macros.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Coby Beck
Subject: Re: hanging macros
Date: 
Message-ID: <LcSsc.11010$L.5029@news-server.bigpond.net.au>
"Duane Rettig" <·····@franz.com> wrote in message
··················@franz.com...
> I always suggest (pprint (macroexpand '<form>)) whenever the behavior
> is unclear; even for putatively simple macros.

I like to keep this on hand:

(defmacro pprint-macro (form)
  `(pprint (macroexpand ',form)))

It's in my dev-tools right after:

(define-symbol-macro ?? (pprint *))

:)

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Svein Ove Aas
Subject: Re: hanging macros
Date: 
Message-ID: <9SXsc.3993$eH3.71483@news4.e.nsc.no>
Coby Beck wrote:

> 
> "Duane Rettig" <·····@franz.com> wrote in message
> ··················@franz.com...
>> I always suggest (pprint (macroexpand '<form>)) whenever the behavior
>> is unclear; even for putatively simple macros.
> 
> I like to keep this on hand:
> 
> (defmacro pprint-macro (form)
>   `(pprint (macroexpand ',form)))
> 
> It's in my dev-tools right after:
> 
> (define-symbol-macro ?? (pprint *))
> 
I have the latter, or its equivalent.. that's pretty much all I have,
though.

I don't suppose you could email me a copy?
From: Antony Sequeira
Subject: Re: hanging macros
Date: 
Message-ID: <gdRsc.72930$Gg5.64110@newssvr25.news.prodigy.com>
Duane Rettig wrote:
> Alain Picard <············@memetrics.com> writes:
> 
> 
>>"Coby Beck" <·····@mercury.bc.ca> writes:
>>
>>
>>You probably already know this, but sometimes it's saying the
>>same thing in many different ways which finally brings it home, so:
>>
>>  The basic way to think about this is: if you have 2 macros
>>  in a file, say A and B, and the compiler needs to invoke
>>  A to compile the macroexpansion code of B, A should be
>>  surrounded in an eval-when.
>>
>>Right?
> 
> 
> No, that's not right.  See 3.2.3.1.1 (or see it online at):
> http://www.franz.com/support/documentation/6.2/ansicl/subsubsu/processi.htm
> 
I have posted messges regarding my confusion with similar stuff.
http://groups.google.com/groups?q=Assuming+I+understand+correctly&hl=en&lr=&ie=UTF-8&selm=3QNqc.69121%249d1.52461%40newssvr25.news.prodigy.com&rnum=2
Looking at
http://www.franz.com/support/documentation/6.2/ansicl/subsubsu/processi.htm
  it looks like if I have to write a macro A that uses a macro B in its 
expansion generation, then I have to do
eval-when of both A and B.
Does this imply I need to own the source code for B to write A ?

In general
1. When writing a macro A that uses a macro B in its expansion 
generation, what is the usual way of arranging the code (in terms of 
source files)
2. When writing a macro X that uses a macro Y in its expanded code
what is the usual way of arranging the code

Should I simply ignore this whole stuff, I am not sure how important it 
is to understand this for wrting CL code.

Thanks
-Antony
From: Duane Rettig
Subject: Re: hanging macros
Date: 
Message-ID: <4brkcf1pg.fsf@franz.com>
Antony Sequeira <·············@hotmail.com> writes:

> Duane Rettig wrote:
> > Alain Picard <············@memetrics.com> writes:
> >
> >>  The basic way to think about this is: if you have 2 macros
> >>  in a file, say A and B, and the compiler needs to invoke
> >>  A to compile the macroexpansion code of B, A should be
> >>  surrounded in an eval-when.
> >>
> >>Right?
> > No, that's not right.  See 3.2.3.1.1 (or see it online at):
> 
> > http://www.franz.com/support/documentation/6.2/ansicl/subsubsu/processi.htm
> >
> 
> I have posted messges regarding my confusion with similar stuff.
> http://groups.google.com/groups?q=Assuming+I+understand+correctly&hl=en&lr=&ie=UTF-8&selm=3QNqc.69121%249d1.52461%40newssvr25.news.prodigy.com&rnum=2
> Looking at
> http://www.franz.com/support/documentation/6.2/ansicl/subsubsu/processi.htm
>   it looks like if I have to write a macro A that uses a macro B in
>   its expansion generation, then I have to do
> 
> eval-when of both A and B.

Note, however, that the spec implies the existence of at least one
eval-when form already, so wrapping any other eval-when forms around
the definition may be redundant.

In general, the implication for defining macros listed in 3.2.3.1.1 is
that they might expand to forms that look like this:

(progn
  (eval-when (:compile-toplevel)
    <do compile-time stuff>)
  <do other stuff>)

or like this:

(progn
  (eval-when (:compile-toplevel)
    <do compile-time stuff>)
  (eval-when (:load-toplevel :execute)
    <do other stuff>))

or, finally:

(progn
  (eval-when (:compile-toplevel :load-toplevel :execute)
    <do all stuff>))

There are subtle differences in the above forms, but they should
all perform according to spec.  They all provide the definition at
compile-time, and after the resultant fasl file has been loaded,
but not necessarily after a file has been compiled but not yet
loaded (all within the constraints of the spec).

> Does this imply I need to own the source code for B to write A ?

No, you can load a file with the definition in it and use it for
macroexpansion at any time after that.

> In general
> 1. When writing a macro A that uses a macro B in its expansion
> generation, what is the usual way of arranging the code (in terms of
> source files)

If you want to save as much space as possible, you can keep macros
in separate files that are only required at compile-time.  Or you can
just always define and use the macros for expansion within one file.
Or, you can always load the file with the definitions in it so that
the macros are available as soon as the file is loaded.

> 2. When writing a macro X that uses a macro Y in its expanded code
> what is the usual way of arranging the code

This usually involves macroexpand (either directly, or indirectly via
compile or eval).  At any time code is treated as data, the macro
definition must be available to whatever is doing the macroexpanding,
so you must simply arrange that it be the case.  As another Picard
likes to say: "Make it so, number one."

> Should I simply ignore this whole stuff, I am not sure how important
> it is to understand this for wrting CL code.

Absolutely do _not_ ignore this.  If you throw your hands up into the
air and cry "magic", then you should never be surprised if your
code performs a disappearing act...

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Alain Picard
Subject: Re: hanging macros
Date: 
Message-ID: <87aczw84nt.fsf@memetrics.com>
Duane Rettig <·····@franz.com> writes:


> No, that's not right.  See 3.2.3.1.1 (or see it online at):
> http://www.franz.com/support/documentation/6.2/ansicl/subsubsu/processi.htm
>
> You can also find clues that support this in whatever implementation
> you are using, by macroexpanding the defmacro form.  For example,
> in Allegro CL:
>
> CL-USER(1): (pprint (macroexpand '(defmacro A (x) `(foo ,x))))
>
> (PROGN (EVAL-WHEN (:COMPILE-TOPLEVEL)
>          (EXCL::CHECK-LOCK-DEFINITIONS-COMPILE-TIME 'A 'FUNCTION
>            'DEFMACRO (FBOUNDP 'A)))
>        (EVAL-WHEN (:COMPILE-TOPLEVEL)
>           [ ... ])
>        [ ... ])

You're right.  My implementation does do that.
Now I'm even more confused than before (and probably more than Coby, to boot)

So -- the presense of the macro declaration A at toplevel is sufficient
to get it to properly be used in all subsequent forms.  Now that I think
of it, that's obviously right, otherwise files containing
(defmacro A () ....)

(defun FOO () ... (A ..) ...)

Would never work right.  (Doh!).

Apologies for the noise and confusion.  Now I'll let the heavyweights
sort it all out.  :-)

-- 
It would be difficult to construe        Larry Wall, in  article
this as a feature.			 <·····················@netlabs.com>
From: Rob Warnock
Subject: Re: hanging macros
Date: 
Message-ID: <B_KdnQhzlp2dRy7dRVn-uA@speakeasy.net>
Alain Picard  <············@memetrics.com> wrote:
+---------------
| "Coby Beck" <·····@mercury.bc.ca> writes:
| > I have delibrately ignored eval-when but I have a feeling it may
| > actually be there for a reason and one I now need to understand.
...
| The basic way to think about this is: if you have 2 macros
| in a file, say A and B, and the compiler needs to invoke
| A to compile the macroexpansion code of B, A should be
| surrounded in an eval-when.
+---------------

As Duane and others have said, that's now correct. But where you *do*
need EVAL-WHEN is when macro A is in a *file* that is LOADed (or some
other means, such as REQUIREd) at compile time, e.g.:

	(require :foo)	; "foo.lisp" contains (defmacro A ...)
	...
	(defmacro B ...uses A...)
	...
	(A args...)	; or even just a bare use of A!

These will fail. The following will succeed:

	(eval-when (:compile-toplevel :load-toplevel :execute)
	   (require :foo))	; "foo.lisp" contains (defmacro A ...)
	...
	(defmacro B ...uses A...)
	...
	(A args...)	; or even just a bare use of A!

More commonly, I find myself using this simpleminded pattern in
my ASDF files, for modules that don't have ASDF subsystem names:

	;;; for macros/packages
	(eval-when (:compile-toplevel :load-toplevel :execute)
	  (require :foo)
	  (require :bar)
	  (require :baz))
	  (require :util

	(defpackage :org.rpw3.some-pkg
	  (:use :cl :ext :foo :bar :baz))

	(defpackage #:org.rpw3.some-pkg.system (:use :cl :asdf))
	(in-package #:org.rpw3.some-pkg.system)

	(defsystem some-pkg
	   ...usual ASDF stuff...)


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rob Warnock
Subject: Re: hanging macros
Date: 
Message-ID: <M6qdnaCE3fp1Qy7dRVn-gg@speakeasy.net>
Alain Picard  <············@memetrics.com> wrote:
+---------------
| "Coby Beck" <·····@mercury.bc.ca> writes:
| > I have delibrately ignored eval-when but I have a feeling it may
| > actually be there for a reason and one I now need to understand.
...
| The basic way to think about this is: if you have 2 macros
| in a file, say A and B, and the compiler needs to invoke
| A to compile the macroexpansion code of B, A should be
| surrounded in an eval-when.
+---------------

As Duane and others have said, that's not correct. But where you *do*
need EVAL-WHEN is when macro A is in a *file* that is LOADed (or some
other means, such as REQUIREd) at compile time, e.g.:

	(require :foo)	; "foo.lisp" contains (defmacro A ...)
	...
	(defmacro B ...uses A...)
	...
	(A args...)	; or even just a bare use of A!

These will fail. The following will succeed:

	(eval-when (:compile-toplevel :load-toplevel :execute)
	   (require :foo))	; "foo.lisp" contains (defmacro A ...)
	...
	(defmacro B ...uses A...)
	...
	(A args...)	; or even just a bare use of A!

More commonly, I find myself using this simpleminded pattern in
my ASDF files, for modules that don't have ASDF subsystem names:

	;;; for macros/packages
	(eval-when (:compile-toplevel :load-toplevel :execute)
	  (require :foo)
	  (require :bar)
	  (require :baz))
	  (require :util

	(defpackage :org.rpw3.some-pkg
	  (:use :cl :ext :foo :bar :baz))

	(defpackage #:org.rpw3.some-pkg.system (:use :cl :asdf))
	(in-package #:org.rpw3.some-pkg.system)

	(defsystem some-pkg
	   ...usual ASDF stuff...)


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Coby Beck
Subject: Re: hanging macros
Date: 
Message-ID: <DDRsc.10974$L.4162@news-server.bigpond.net.au>
"Alain Picard" <············@memetrics.com> wrote in message
···················@memetrics.com...
> "Coby Beck" <·····@mercury.bc.ca> writes:
>
> > I have delibrately ignored eval-when but I have a feeling it may
actually be
> > there for a reason and one I now need to understand.
>
> > I have macros that expand into macros that expand into macros and have
> > thought myself very clever at times.  Now I have a problem...
>
[snip]
> So it's OK if the body of B has calls to A inside the
> backquote, because that's just a text form.

So I have had a careful look through, and my higher level macros are
expanding into macro forms (ie inside the backquote) but not trying to
expand any when compiling.  So I should be alright there...

> p.s. I have no idea why/how your loading could be "hanging".  Could
> it be misinterpreting something which sends it into an infinite loop?
> Is it chewing CPU while it's hung?  Or worse, do the macroexpansions
> perform i/o at compile time?!

It takes as much cpu as it can get.  No i/o.

Thanks for the response, I'll keep looking.  Because of the nature of the
problem I'm sure I have trod into "undefined consequences" territory
somewhere...

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")
From: Duane Rettig
Subject: Re: hanging macros
Date: 
Message-ID: <47jv0f1iu.fsf@franz.com>
"Coby Beck" <·····@mercury.bc.ca> writes:

> "Alain Picard" <············@memetrics.com> wrote in message
> ···················@memetrics.com...
> > "Coby Beck" <·····@mercury.bc.ca> writes:
> >
> > > I have delibrately ignored eval-when but I have a feeling it may
> actually be
> > > there for a reason and one I now need to understand.
> >
> > > I have macros that expand into macros that expand into macros and have
> > > thought myself very clever at times.  Now I have a problem...
> >
> [snip]
> > So it's OK if the body of B has calls to A inside the
> > backquote, because that's just a text form.
> 
> So I have had a careful look through, and my higher level macros are
> expanding into macro forms (ie inside the backquote) but not trying to
> expand any when compiling.  So I should be alright there...
> 
> > p.s. I have no idea why/how your loading could be "hanging".  Could
> > it be misinterpreting something which sends it into an infinite loop?
> > Is it chewing CPU while it's hung?  Or worse, do the macroexpansions
> > perform i/o at compile time?!
> 
> It takes as much cpu as it can get.  No i/o.
> 
> Thanks for the response, I'll keep looking.  Because of the nature of the
> problem I'm sure I have trod into "undefined consequences" territory
> somewhere...

Are you making any explicit calls to COMPILE?  Compile does not use the
compile-file environment, so you must be prepared to have your macro
definitions available at the time of your call to compile.  It is
similar to having it available at the time of a macroexpand or eval
call.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Coby Beck
Subject: Re: hanging macros
Date: 
Message-ID: <uHSsc.11041$L.3683@news-server.bigpond.net.au>
"Duane Rettig" <·····@franz.com> wrote in message
··················@franz.com...
> "Coby Beck" <·····@mercury.bc.ca> writes:
> > Thanks for the response, I'll keep looking.  Because of the nature of
the
> > problem I'm sure I have trod into "undefined consequences" territory
> > somewhere...
>
> Are you making any explicit calls to COMPILE?  Compile does not use the
> compile-file environment, so you must be prepared to have your macro
> definitions available at the time of your call to compile.  It is
> similar to having it available at the time of a macroexpand or eval
> call.

As I posted elsewhere I did find the problem, thanks.

I'm happy for the discussions about eval-when but I still have the feeling
that it should not normally be necessary to worry about it, kind of like
eval and compile, heavy hammers for special situations.  So far when I see
it, I always get the feeling that there should be another way, and I even
want to say "better way".

But I'm sure that one day I will be in a situation and bang, it will be
there and exactly the right thing!

-- 
Coby Beck
(remove #\Space "coby 101 @ big pond . com")