From: Andreas Eder
Subject: macros and eval-when
Date: 
Message-ID: <m3pt23qn1n.fsf@banff.eder.de>
Hi, 

I have a question concerning the use macros and eval-when situations.

Suppose I have a file in which a define some macros and want to use
them in the same file afterwards.
Then, I have to wrap the definition of the macros with 
(eval-when (:compile-toplevel) (defmacro ... ))
Is that right?

But in a lot of code that I've seen, the defmacros are wrapped with
 (eval-when (:compile-toplevel :load-toplevel :execute) ... )

Is there any reason to use :load-toplevel and :execute here ?

Macroexpansion happens before loading and executing, doesn't it?
Where is the fault in my reasoning?

Thanks

Andreas

-- 
Wherever I lay my .emacs, there's my $HOME.

From: Tim Bradshaw
Subject: Re: macros and eval-when
Date: 
Message-ID: <1101319915.580358.36000@c13g2000cwb.googlegroups.com>
Andreas Eder wrote:
> Hi,
>
> I have a question concerning the use macros and eval-when situations.
>
> Suppose I have a file in which a define some macros and want to use
> them in the same file afterwards.
> Then, I have to wrap the definition of the macros with
> (eval-when (:compile-toplevel) (defmacro ... ))
> Is that right?

No.  The compiler is required to keep the definitions of the macros
around during the processing of the file, so you don't need EVAL-WHEN
tricks.  You *do* need EVAL-WHEN in more complex situations, for
instance if the expansion of the macro involves calling a function
defined in the file.

>
> But in a lot of code that I've seen, the defmacros are wrapped with
>  (eval-when (:compile-toplevel :load-toplevel :execute) ... )
>
> Is there any reason to use :load-toplevel and :execute here ?
>

Well, you probably want the macros to be available after the file is
loaded as well, so you want :LOAD-TOPLEVEL.  You also want it to work
when the file is interpreted, hence :EXECUTE.

--tim
From: Peter Seibel
Subject: Re: macros and eval-when
Date: 
Message-ID: <m3is7vgi8n.fsf@javamonkey.com>
"Tim Bradshaw" <··········@tfeb.org> writes:

> Andreas Eder wrote:
>> Hi,
>>
>> I have a question concerning the use macros and eval-when situations.
>>
>> Suppose I have a file in which a define some macros and want to use
>> them in the same file afterwards.
>> Then, I have to wrap the definition of the macros with
>> (eval-when (:compile-toplevel) (defmacro ... ))
>> Is that right?
>
> No.  The compiler is required to keep the definitions of the macros
> around during the processing of the file, so you don't need EVAL-WHEN
> tricks.  You *do* need EVAL-WHEN in more complex situations, for
> instance if the expansion of the macro involves calling a function
> defined in the file.
>
>>
>> But in a lot of code that I've seen, the defmacros are wrapped with
>>  (eval-when (:compile-toplevel :load-toplevel :execute) ... )
>>
>> Is there any reason to use :load-toplevel and :execute here ?
>>
>
> Well, you probably want the macros to be available after the file is
> loaded as well, so you want :LOAD-TOPLEVEL.  You also want it to work
> when the file is interpreted, hence :EXECUTE.

I thought :EXECUTE was in case someone used your macro in a
non-top-level position. E.g.

  (let ((some-thing (foo)))
    (define-my-thing-with-my-macro bar ...))

If DEFINE-MY-THING-WITH-MY-MACRO expands into an EVAL-WHEN without
:EXECUTE then the code in the EVAL-WHEN won't be executed.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Chris Capel
Subject: Re: macros and eval-when
Date: 
Message-ID: <10qb4upo4f2kn10@corp.supernews.com>
Peter Seibel wrote:

> "Tim Bradshaw" <··········@tfeb.org> writes:
> 
>> Well, you probably want the macros to be available after the file is
>> loaded as well, so you want :LOAD-TOPLEVEL.  You also want it to work
>> when the file is interpreted, hence :EXECUTE.
> 
> I thought :EXECUTE was in case someone used your macro in a
> non-top-level position. E.g.
> 
>   (let ((some-thing (foo)))
>     (define-my-thing-with-my-macro bar ...))
> 
> If DEFINE-MY-THING-WITH-MY-MACRO expands into an EVAL-WHEN without
> :EXECUTE then the code in the EVAL-WHEN won't be executed.

But the macroexpansion shouldn't include the eval-when, unless the eval-when
was part of the macro body. I wouldn't think that an external eval-when
would affect any use of the macro after it's defined.

Chris Capel
From: Peter Seibel
Subject: Re: macros and eval-when
Date: 
Message-ID: <m3hdndg9uf.fsf@javamonkey.com>
Chris Capel <······@iba.nktech.net> writes:

> Peter Seibel wrote:
>
>> "Tim Bradshaw" <··········@tfeb.org> writes:
>> 
>>> Well, you probably want the macros to be available after the file is
>>> loaded as well, so you want :LOAD-TOPLEVEL.  You also want it to work
>>> when the file is interpreted, hence :EXECUTE.
>> 
>> I thought :EXECUTE was in case someone used your macro in a
>> non-top-level position. E.g.
>> 
>>   (let ((some-thing (foo)))
>>     (define-my-thing-with-my-macro bar ...))
>> 
>> If DEFINE-MY-THING-WITH-MY-MACRO expands into an EVAL-WHEN without
>> :EXECUTE then the code in the EVAL-WHEN won't be executed.
>
> But the macroexpansion shouldn't include the eval-when, unless the
> eval-when was part of the macro body.

But that's one typical use of EVAL-WHEN--you want to write a macro
that needs to do some bookkeeping at compile time (to squirrel away
some information that may be needed by other macros used in the same
file while computing their expansions) so you write the macro to
expand into a EVAL-WHEN with :COMPILE-TOPLEVEL. Since you'll probably
also want that same information available after you load the compiled
file you also include :LOAD-TOPLEVEL. And if you want your macro to be
usable in non-top-level-contexts you also include :EXCECUTE.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Wade Humeniuk
Subject: Re: macros and eval-when
Date: 
Message-ID: <or2pd.271$VL6.258@clgrps13>
Andreas Eder wrote:
> Hi, 
> 
> I have a question concerning the use macros and eval-when situations.
> 
> Suppose I have a file in which a define some macros and want to use
> them in the same file afterwards.
> Then, I have to wrap the definition of the macros with 
> (eval-when (:compile-toplevel) (defmacro ... ))
> Is that right?

That is not correct.  From the Hyperspec:

<quote>
If a defmacro form appears as a top level form, the compiler must store the macro
definition at compile time, so that occurrences of the macro later on in the file can be
expanded correctly. Users must ensure that the body of the macro can be evaluated at
compile time if it is referenced within the file being compiled.
</quote>

http://www.lispworks.com/reference/HyperSpec/Body/m_defmac.htm#defmacro

Wade