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