[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Macros -> declarations
- To: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>
- Subject: Macros -> declarations
- From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
- Date: Fri, 10 May 1985 14:18:00 -0000
- Cc: common-lisp@SU-AI.ARPA
- In-reply-to: Msg of 10 May 1985 01:51-EDT from Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
- Sender: FAHLMAN@CMU-CS-C.ARPA
I agree with KMP's critique of RWK's proposal to just use normal macros
inside the declaration forms. Too many problems.
As for KMP's comments...
On the other hand, I'm really bothered by the fact that one can write:
(DEFMACRO DECLARE-FOO (&REST X) `(DECLARE (FOO ,@X)))
and use (DECLARE-FOO ...) at toplevel but not inside a DEFUN. I think people
will find this an ugly inconsistency.
But you CAN'T use DECLARE-FOO at top-level, since the DECLARE form
produced will not be legal there. In general, macros only work in place
of forms that you are going to evaluate. In quoted contexts, or other
non-evaluated places like arglists, a macro would never expand. DECLARE
is one of those, since you never evaluate the DECLARE, but just look at
it while deciding how to set up the arguments. The ugly inconsistency
here is allowing macros in this place.
I am also bothered by the idea of checking explicitly for DECLARE because
it means that the thing would not really be an operator at all. It would
essentially be just a part of the syntax of some other form (eg, DEFUN or
LAMBDA) -- yet another odd kind of keyword (like OTHERWISE in SELECTQ).
That's right, DECLARE is not an opertor in Common Lisp, just a piece of
syntax that happens to take the form of an operator. The form is
probably a hold-over from Maclisp, where DECLARE was an operator. If we
had chosen a different syntax for this, such as always having the first
list of the body be a declaration without any DECLARE marker in front of
it, or hiding the declarations in the arglist after an &declare marker,
we would not have made the mistake of treating this as a funny kind of
operator when it's really structural.
(DEFMACRO DEF-MY-MACRO (NAME BVL &BODY FORMS)
`(DEFMACRO ,NAME ,BVL
(MAKE-MY-ENCAPSULATION (PROGN ,@FORMS))))
must be rewritten as
(DEFMACRO DEF-MY-MACRO (NAME BVL &BODY FORMS &ENVIRONMENT ENV)
(MULTIPLE-VALUE-BIND (BODY DECLARATIONS DOCUMENTATION)
`(DEFMACRO ,NAME ,BVL
(MAKE-MY-ENCAPSULATION (PROGN ,@BODY)))))
I just don't see this as a big deal.
It may not be a big deal, but you DID get it wrong. Parse-Body has to
receive the appropriate ENV as an argument in order to do its work,
unless your version of Parse-Body is somehow getting this as a special.
That, basically, is the mistake that people keep making.
Well, it looks like we're going to lose this battle. Too many people on
this list are fascinated by the alleged flexibility that the macro ->
declaration misfeature gives them, and too few are bothered by the
errors, confusion, and inefficiency that this causes. Since the
misfeature is already in the manual, it would require a clear consensus
to remove it, and I don't see that emerging.
The fallback position is to add a reasonable PARSE-BODY form to the
language, with a required environment argument as well as the forms
argument. We should probably do that in any event, since each and every
implementation seems to have invented this and few people can write a
correct macro without this. The manual will need to be extended, in the
section on Macros, I guess, to explain what this is about and give an
example or two.
I am also very interested in KMP's suggestion for an extenstion to the
&body syntax, but need to study this a bit to make sure that there are
not hidden problems. The big advantage of this, of course, is that it
allows the casual macro-writer to avoid dealing explicitly with
environments and hairy M-V uses of Parse-body for most simple things. I
grant that people who can't hack these things shouldn't be writing
macros, but they will be, and life will be easier all around if we can
make this process less error-prone.