From: Sam Steingold
Subject: (when nil (defmacro ...))
Date: 
Message-ID: <uya8rjxhz.fsf@ksp.com>
It appears that both CLISP and CMUCL define the macro z when they
compile this:

(when nil (defmacro z () (print "z")))

is this the correct behavior?
Thanks.

[thanks to Eric for the read/*package* hint!]

-- 
Sam Steingold (http://www.podval.org/~sds)
Micros**t is not the answer.  Micros**t is a question, and the answer is Linux,
(http://www.linux.org) the choice of the GNU (http://www.gnu.org) generation.
There are two kinds of egotists: 1) Those who admit it  2) The rest of us
From: Robert Monfera
Subject: Re: (when nil (defmacro ...))
Date: 
Message-ID: <38A47953.F201839A@fisec.com>
Sam Steingold wrote:
>
> It appears that both CLISP and CMUCL define the macro z when they
> compile this:
>
> (when nil (defmacro z () (print "z")))
>
> is this the correct behavior?

From the Hyperspec:

"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."

1. Why is the macro defined if it does not occur as a top-level form?

It is not required by the spec, but I didn't see a clause that would
prohibit an implementation from doing so.

2. Why is the macro defined even though the condition is NIL?

The WHEN statement gets evaluated upon execution, so the compiler
officially does not know that the condition can never evaluate to T.

---

In addition to its official duties, ACL is clever enough to warn you if
it finds a possible bug - in this case, a never-executed branch that has
the only reference to a parameter (works also with COMPILE-FILE):

> (defun a (x) (when nil (defmacro z () (print x))))   ; note X
A
> (compile 'a)
; While compiling A:
Warning: Variable X is never used.
A
T
NIL

But ACL only defines the macro if A is invoked and NIL is replaced with
T.

Robert