From: Thomas A. Russ
Subject: Macros, macroexpansion & the compile-time environment.
Date: 
Message-ID: <22303@venera.isi.edu>
While doing some portability checks for our system, I ran into a
problem in Allegro V4.1 (Sun Sparc).  What happens is the following:

We have a package which shadows IF.  It is defined in a file loaded
before we load or compile any of our system:

(defpackage "OURS" (:use "COMMON-LISP")
  (:shadow "IF") ...)

In another file, we define our own variant of IF:

  (in-package "OURS")

  (defmacro if (test then &rest else-list)
     (when (null else-list)
       (warn "IF statements should have an else clause"))
     `(COMMON-LISP:if ,test ,then ,@else-list))

  ;; Later in the same file, we use if in a different macro, which has
  ;; been abstracted here:

  (defmacro other-macro (&rest body-of-macro)
    ;; We do some processing of the body, gory details omitted.
    (dolist (form body-of-macro)
      (if (test-form form)        ;; <==== NOTE the "IF" here
	  (do-this form)
          (do-that form)))
    `(some-function ,@args))


In Allegro v4.1, this second macro will not compile correctly.
Apparently the macro definition of "IF" is not available for use in
the expansion generation code for "OTHER-MACRO", since and undefined
function error occurs.  Since this does not happen in TI Common Lisp,
Macintosh MCL or Lucid v4, I think that this may be a bug in Allegro.
Since it involves what is available in the compile time environment as
well as the environment in which macro expansion and macro expansion
function definition occurs, I thought I would seek advice:

    Does the CommonLisp standard require the shadowed definition of
    "IF" to be used in "OTHER-MACRO"?  Or is the standard mute?


- Tom.


P.S.:  I know how to fix the problem for Allegro (use
       "common-lisp:if"), I was just curious about the environment issue).
--

Thomas A. Russ                                             ···@isi.edu    
USC/ISI, 4676 Admiralty Way, Marina del Rey, CA 90292      (310) 822-1511
From: Barry Margolin
Subject: Re: Macros, macroexpansion & the compile-time environment.
Date: 
Message-ID: <182sg5INN3sc@early-bird.think.com>
In article <·····@venera.isi.edu> ···@isi.edu writes:
>  (defmacro if (test then &rest else-list)
>     (when (null else-list)
>       (warn "IF statements should have an else clause"))
>     `(COMMON-LISP:if ,test ,then ,@else-list))

Shouldn't that be

  `(COMMON-LISP:if ,test ,then (progn ,@else-list))

>  (defmacro other-macro (&rest body-of-macro)
>    ;; We do some processing of the body, gory details omitted.
>    (dolist (form body-of-macro)
>      (if (test-form form)        ;; <==== NOTE the "IF" here
>	  (do-this form)
>          (do-that form)))
>    `(some-function ,@args))

>    Does the CommonLisp standard require the shadowed definition of
>    "IF" to be used in "OTHER-MACRO"?  Or is the standard mute?

The dpANS makes it explicitly unspecified.  The dpANS defines two relevant
environments in sec.3.2.1: The "compilation environment", which is where
the compiler temporarily remembers things that it needs to know to compile
later forms in the same file; and the "evaluation environment", which is
where macro expanders and (eval-when (compile) ...) code are executed.  It
then says, "It is unspecified whehter a definition available in the
compilation environment can be used in an evaluation initiated in the
startup environment or evaluation environment."  (The reference to the
startup environment doesn't affect the above case.)  A similar statement
appears in sec.3.2.3.1.1 "Processing of Defining Macros".  This makes both
implementations valid, and the above program non-conforming because it
depends on unspecified behavior.

>P.S.:  I know how to fix the problem for Allegro (use
>       "common-lisp:if"), I was just curious about the environment issue).

Actually, you just need to put an (EVAL-WHEN (COMPILE LOAD EVAL) ...)
around the IF macro definition.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar