[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Macros -> declarations
Date: Mon, 6 May 1985 20:20 EDT
From: Skef Wholey <Wholey@CMU-CS-C.ARPA>
Date: Monday, 6 May 1985 19:39-EDT
From: Kent M Pitman <KMP at SCRC-STONY-BROOK.ARPA>
Re: Macros -> declarations
By the way, abstractions like my DECLARE-BIT-REGISTER do not provide "room
for" other declarations. Eg, consider:
(DEFUN FOO (REG)
(DECLARE-BIT-REGISTER REG)
(DECLARE (SPECIAL *FOO*))
...)
There is no way (without violating the BIT-REGISTER abstraction) to not
write two leading DECLAREs.
So what's really wanted is a DEFDECLARATION or somesuch that works like DEFTYPE
in defining a macro-like thing that expands into a list of declare forms.
Although a scheme like this wouldn't eliminate the need for a body parser to
"macroexpand" stuff at runtime, it would eliminate the screw that was the last
straw to Rob MacLachlan -- the need for all macro writers to do &environment
hacking whenever parsing bodies.
(defdeclaration bit-register (&rest guys)
(mapcan #'(lambda (guy) `((special ,guy) (fixnum ,guy))) guys))
(defun foo (reg)
(declare (bit-register reg) (special *foo*))
...)
Note that there is no way to scope DEFTYPE's. With the above suggestion, there
would be no way to scope DEFDECLARATION's either. An alternate solution, which
requires only a one-word change to the language spec, is to restrict macros
that can expand into declarations to GLOBAL macros. This solution would handle
all of the imaginative uses for this feature that people here have come up
with, while removing the big ball of hair that makes it hard for users to write
correct macros.
This latter suggestion is ugly, I agree. A completely separate macro-like
mechanism is provided for types, and happens to prevent the definition of local
types, so why not have a similar mechanism for declarations?
--Skef
Well, that would certainly help a lot... but I'm not sure it would handle all
the useful cases.
For example, you couldn't use MACROLET to create a local declaration
type. We'd either need a DECLARATION-LET special form or we'd have to
say that all declaration types have to be global. I'm not taking a stand
on that issue; just pointing it out.
Another odd situation to consider is that you might be working in a package on which
it was desirable to shadow the symbol DECLARE for some reason. Rather than have
to write (LISP:DECLARE ...) everywhere, you could imagine wanting to do:
(DEFMACRO MY:DECLARE (&REST DECLS)
`(LISP:DECLARE ,@DECLS))
I don't expect this situation to be common early-on, but if people get into writing
embedded languages as macrofied extensions making heavy use of the package system,
they might well want such a provision ... or possibly something like:
(DEFMACRO MY:DECLARE (&REST DECLS)
`(LISP:DECLARE ,@(MY:TRANSLATE DECLS)))
It turns out that if anyone ever wants to recycle any of the names CL defines as
usable in declarations (like INTEGER, etc) to mean anything else in an embedded language,
they will need this sort of hook in order to avoid having to provide an intermediate
translator from their language to CL.
I could imagine Macsyma possibly wanting to play games like this if it were ever
really made to run "natively" in Common Lisp ... right now it has a lot of
intermediate translators that should not really be needed if the macro facility
of the underlying language is appropriately powerful.
By the way, I don't think that the frequency of parsing bodies (as opposed to
just propagating them) is so high as to make it offensive to have to use
&ENVIRONMENT in those situations.