[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Lexical references in DEFMACRO
- To: edsel!sunvalleymall!eb@su-navajo.arpa (Eric Benson)
- Subject: Lexical references in DEFMACRO
- From: Rob MacLachlan <RAM@C.CS.CMU.EDU>
- Date: Sat, 03 May 1986 14:11:00 -0000
- Cc: Common-Lisp@SU-AI.ARPA
- In-reply-to: Msg of 2 May 1986 19:27-EDT from edsel!sunvalleymall!eb at su-navajo.arpa (Eric Benson)
Date: Friday, 2 May 1986 19:27-EDT
From: edsel!sunvalleymall!eb at su-navajo.arpa (Eric Benson)
Re: Lexical references in DEFMACRO
The Common Lisp definition continues to surprise me. I had not
noticed that DEFMACRO is not allowed to let its body refer to any
lexically visible entities outside the DEFMACRO form. On the other
hand, DEFUN is specifically allowed to refer to lexically visible
entities. This deserves some explanation. It seems I am allowed to
do this:
(LET ((SOME-DATA-STRUCTURE (MAKE-SOME-DATA-STRUCTURE)))
(DEFUN SOME-FUNCTION ()
(DO-SOMETHING-WITH SOME-DATA-STRUCTURE)))
but not this:
(LET ((SOME-DATA-STRUCTURE (MAKE-SOME-DATA-STRUCTURE)))
(DEFMACRO SOME-MACRO ()
(MAKE-A-FORM-WITH SOME-DATA-STRUCTURE)))
To do what I want in the second case I must do this:
(LET ((SOME-DATA-STRUCTURE (MAKE-SOME-DATA-STRUCTURE)))
(SETF (MACRO-FUNCTION 'SOME-MACRO)
#'(LAMBDA (FORM ENVIRONMENT
(DECLARE (IGNORE FORM ENVIRONMENT))
(MAKE-A-FORM-WITH SOME-DATA-STRUCTURE)))))
Furthermore, in order to implement this restriction I must introduce a
new special form, such as that used in Spice Lisp, to force a form to
be evaluated in the null lexical environment. Thus it is impossible
to live up to the suggestion in the implementation note on p.58, that
macros should not expand into implementation-dependent special forms.
This is a good point which I overlooked. It looks like this special
form must become a part of the language, not because users need to use
it directly, but becuase some macros must expand into it.
It is obvious to me why the expansion functions defined by MACROLET
must have this restriction; there is no environment at macroexpansion
time to which they can refer. The expansion functions created by
DEFMACRO, on the other hand, are not really very different from
ordinary functions created by DEFUN.
There is one difference, but it is outside the scope of the Common
Lisp definition. Most (i.e. all) implementations of Common Lisp cause
macros defined by DEFMACRO to be available for use while compiling the
file in which they are defined. This is not required by the Common
Lisp definition, but is part of the Lisp tradition.
This is not true, see the bottom of p146 "If the compiler encounters a
DEFMACRO..." It seems pretty clear that this *must* be part of the
definition, since the programmer must make sure that her macros are
defined before she uses them. If you require an explicit EVAL-WHEN,
then nearly every program I have ever written would have to be changed.
It should be obvious that this is only possible for macro
definitions which occur at "top level." For example, it would be
incorrect in this example to define THIS-MACRO at compile time:
(WHEN SOME-CONDITION
(DEFMACRO THIS-MACRO ()
(EXPAND-INTO-SOMETHING)))
In my previous discussion of "top level forms", I explained why I also
don't agree with this. The notion of a "top level form" just doesn't
belong in a lexical Lisp. Implicit compiler evaluation such as
putting DEFMACRO definitions in the compiler environment should happen
no matter where the form appears.
Similarly, any macro definition which refers to a lexically visible
entity cannot be defined at compile time, since it cannot be a "top
level" form.
It seems to me that you are arguing much more effectively for the null
DEFMACRO environment than you are arguing against the implicit
evaluation. It is clear that they are mutually exclusive.
Rob