From: Michael Bohn
Subject: macro/call order [particularly in SBCL]
Date: 
Message-ID: <46a8c116$0$3828$9b4e6d93@newsspool4.arcor-online.net>
Hi,

im currently porting a Lisp program from CLISP to SBCL and found this 
'strange' behaviour in SBCL.

I'm defining this macro in a file:
(defmacro in-read-write-environment (reader writer io &body body)
   `(let ((*reader* ,reader) (*writer* ,writer) (*io* ,io))
     ,@body))

(I know I'm not using the variable writer, but that's not the point here)

BEFORE im defining the macro im calling it like this:

(in-user-environment package writer
      (setf form (read-from-string (replace-return form) nil nil))
      (progn (report-package-not-found writer package)
             (return-from handle-eval-request)))

And thats what strange here, 'calling' the macro before defining it (not 
god style I presume now) works perfectly in CLISP. But in SBCL its
treated like a function which led to strange behaviours during run-time.

What I learned now is:
Always define macros before you use them, otherwise it's not portable :)

From: Pascal Costanza
Subject: Re: macro/call order [particularly in SBCL]
Date: 
Message-ID: <5grv2lF3i3sgeU1@mid.individual.net>
Michael Bohn wrote:
> Hi,
> 
> im currently porting a Lisp program from CLISP to SBCL and found this 
> 'strange' behaviour in SBCL.
> 
> I'm defining this macro in a file:
> (defmacro in-read-write-environment (reader writer io &body body)
>   `(let ((*reader* ,reader) (*writer* ,writer) (*io* ,io))
>     ,@body))
> 
> (I know I'm not using the variable writer, but that's not the point here)
> 
> BEFORE im defining the macro im calling it like this:
> 
> (in-user-environment package writer
>      (setf form (read-from-string (replace-return form) nil nil))
>      (progn (report-package-not-found writer package)
>             (return-from handle-eval-request)))
> 
> And thats what strange here, 'calling' the macro before defining it (not 
> god style I presume now) works perfectly in CLISP. But in SBCL its
> treated like a function which led to strange behaviours during run-time.
> 
> What I learned now is:
> Always define macros before you use them, otherwise it's not portable :)

Not quite, but close.

The real issue is that there is a difference between interpreted and 
compiled code. ANSI Common Lisp specifies a few minimal requirements on 
compilation, and one of them is that all macro invocations are fully 
expanded and that the resulting code doesn't contain any macro 
invocations anymore. For that to work, all macros have to be defined 
upfront, of course, or to be more precise, they have to be available in 
the compilation environment.

ANSI Common Lisp doesn't pose such requirements on interpreted code. An 
implementation is allowed to expand macros lazily on each invocation, 
and it is even allowed to reexpand them over and over again. This is 
actually quite useful during development, because you can immediately 
see changes in macro definitions without recompilation.

My guess is that you haven't noticed a difference between CLISP and 
SBCL, but rather a difference between an interpreter and a compiler.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Michael Bohn
Subject: Re: macro/call order [particularly in SBCL]
Date: 
Message-ID: <46a8cab5$0$3833$9b4e6d93@newsspool4.arcor-online.net>
Pascal Costanza wrote:
> Michael Bohn wrote:
>> Hi,
>>
>> im currently porting a Lisp program from CLISP to SBCL and found this 
>> 'strange' behaviour in SBCL.
>>
>> I'm defining this macro in a file:
>> (defmacro in-read-write-environment (reader writer io &body body)
>>   `(let ((*reader* ,reader) (*writer* ,writer) (*io* ,io))
>>     ,@body))
>>
>> (I know I'm not using the variable writer, but that's not the point here)
>>
>> BEFORE im defining the macro im calling it like this:
>>
>> (in-user-environment package writer
>>      (setf form (read-from-string (replace-return form) nil nil))
>>      (progn (report-package-not-found writer package)
>>             (return-from handle-eval-request)))
>>
>> And thats what strange here, 'calling' the macro before defining it 
>> (not god style I presume now) works perfectly in CLISP. But in SBCL its
>> treated like a function which led to strange behaviours during run-time.
>>
>> What I learned now is:
>> Always define macros before you use them, otherwise it's not portable :)
> 
> Not quite, but close.
> 
> The real issue is that there is a difference between interpreted and 
> compiled code. ANSI Common Lisp specifies a few minimal requirements on 
> compilation, and one of them is that all macro invocations are fully 
> expanded and that the resulting code doesn't contain any macro 
> invocations anymore. For that to work, all macros have to be defined 
> upfront, of course, or to be more precise, they have to be available in 
> the compilation environment.
> 
> ANSI Common Lisp doesn't pose such requirements on interpreted code. An 
> implementation is allowed to expand macros lazily on each invocation, 
> and it is even allowed to reexpand them over and over again. This is 
> actually quite useful during development, because you can immediately 
> see changes in macro definitions without recompilation.
> 
> My guess is that you haven't noticed a difference between CLISP and 
> SBCL, but rather a difference between an interpreter and a compiler.
> 
> 
> Pascal
> 

The programs are both compiled to executables.
From: Pascal Bourguignon
Subject: Re: macro/call order [particularly in SBCL]
Date: 
Message-ID: <87y7h35cvx.fsf@voyager.informatimago.com>
Michael Bohn <············@gmx.de> writes:
> The programs are both compiled to executables.

Nonetheless, you MUST define your macros before using it.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

ATTENTION: Despite any other listing of product contents found
herein, the consumer is advised that, in actuality, this product
consists of 99.9999999999% empty space.
From: Duane Rettig
Subject: Re: macro/call order [particularly in SBCL]
Date: 
Message-ID: <o0k5sn2gip.fsf@gemini.franz.com>
Pascal Bourguignon <···@informatimago.com> writes:

> Michael Bohn <············@gmx.de> writes:
>> The programs are both compiled to executables.
>
> Nonetheless, you MUST define your macros before using it.

This tends to be a good rule-of-thumb, but it may be more restrictive
than necessary (where "it" is ambiguous).  A more specific way of
stating the more accurate truism (which does not conflict with any of
the observations of previous posters) is that you must define a
macro before macroexpand-time tries to macroexpand the putative macro
form (and if the form doesn't represent a macro at macroexpand time,
it is then that it is assumed to be a function call).  The confusing
thing might be that macroexpand-time is different for different
situations, and there are enough implementation-dependent behaviors
that two fully-compliant Common Lisps will then macroexpand at
different times.  For example, if there is any compile-time-too
behavior [i.e. something was specified within an
 (eval-when (compile ...) ...) form] then whether that compile-time
operation is itself pre-compiled (and when the pre-compilation
actually occurs) may be changed, so that the macroexpansion occurs
before the macro is defined.

-- 
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: Rob Warnock
Subject: Re: macro/call order [particularly in SBCL]
Date: 
Message-ID: <bt2dnQA0U_yPDjTbnZ2dnUVZ_rKtnZ2d@speakeasy.net>
Pascal Costanza  <··@p-cos.net> wrote:
+---------------
| ANSI Common Lisp doesn't pose such requirements on interpreted code. An 
| implementation is allowed to expand macros lazily on each invocation, 
| and it is even allowed to reexpand them over and over again. This is 
| actually quite useful during development, because you can immediately 
| see changes in macro definitions without recompilation.
+---------------

Actually, unless an "interpreter" *does* some sort of preprocessing
to expand macros [whether or not that's 100% equivalent to ANSI CL's
"minimal compilation"] once & only once, then it is *required* to
reexpand them over and over again... since "displacing" expansion
[a.k.a. self-modifying code a.k.a. overwriting the macro call with
its expansion] is expressly forbidden, see:

    http://www.alu.org/HyperSpec/Body/sec_3-1-2-1-2-2.html
    3.1.2.1.2.2 Macro Forms

    http://www.alu.org/HyperSpec/Issues/iss301-writeup.html
    Issue SELF-MODIFYING-CODE Writeup

Many implementations (CMUCL, CLISP, most others) get around that for
performance reasons by actually doing at least Minimal Compilation
of even "interpreted" code [REPL & LOADed source], so even there
changing the function behind a macro will require re-evaluating any
defining forms [DEFUN, DEFVAR, etc.] whose values contained a call
of that macro.

+---------------
| My guess is that you haven't noticed a difference between CLISP and 
| SBCL, but rather a difference between an interpreter and a compiler.
+---------------

No, the CLISP interpreter preprocesses at least the macros, too.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607