[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Macros -> declarations
Date: Tue, 7 May 1985 10:18 EDT
From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>
Date: Tue, 7 May 85 08:51 EDT
From: Bernard S. Greenberg <BSG@STONY-BROOK.SCRC.Symbolics.COM>
I don't buy this as a counterargument to what KMP said. Subsitute "DEFUN"
for "DECLARE" in the above paragraph. You can only define functions with
DEFUN -- (generic)Lisp provides no other way. Yet, we have the whole
top-level macro mechanism to allow you to define application-language-embedded
function-definers, calls to whom are expanded at top-level to ultimately
produce DEFUNs. DECLARE is the only way to declare things lexically.
The same arguments apply.
I guess I didn't make myself clear. I understand that macros are able
to provide suitable disguises for anything that takes the form of a list
to be evaluated, such as DEFUN, and that this is useful in creating
embedded sublanguages with a LIsp-like syntax. My point was that we do not
have anything like macros for disguising "structural" items that are not
in the form of lists to be evaluated: argument lists, things like
&optional, T and NIL, certain keywords, declarations, components of
declarations, doc strings, and so on. Various parts of the interpreter
look for such things verbatim, without doing any macro-expansion of
objects or structures that might turn into the item being sought.
I guess the issue is whether you think of DECLARE as "structural". Consider:
(DEFMACRO FROB (WIDGET)
(COND ((> MOST-NEGATIVE-FIXNUM something)
...expansion that assumes WIDGET was represented as a fixnum...)
...expansion that assumes WIDGET was represented as a list...)))
(DEFMACRO DECLARE-WIDGET (&REST NAMES)
`(DECLARE (TYPE ,(IF (> MOST-NEGATIVE-FIXNUM something) 'FIXNUM 'LIST) ,@NAMES)))
(DEFUN FOO (X)
... (FROB X) ...)
Certainly I need as a minimum the ability to do this. It is not reasonable
(as you seem to be proposing) that I should have to do:
(DEFMACRO DEFINE-WIDGET-OPERATION (NAME BVL &BODY FORMS)
`(DEFUN FOO ,BVL
(DECLARE ...hair to parse &WIDGET keywords in BVL
or DECLARE-WIDGET magic at head of FORMS...)
since it is not compositional -- ie, if I have a similar DEFINE-GIZMO-OPERATION
macro, I cannot easily define something which frobs both gizmos and widgets.
Hence, I claim the declaration is not structural in the sense that, for example,
a COND clause is.
By the way, Macsyma does this sort of thing with read-conditionals because
languages don't allow it the flexibility to do it any other way. I hope I don't
have to explain to you how and why this offends me.
By the way, Skef's proposal (for "declaration macros") handles this problem, too.
I'm just a little skeptical about a special-purpose declaration macro just
for this context. Certainly it is the minimum potentially acceptable position,
since it at least tries to address the issues I'm raising rather than sweeping
them under the rug. I'm a little afriad that next people will want COND macros
and LAMBDA macros (oops, the LispM has them already) and ... but I might yet be
willing to yield to the suggestion of these declaration macros -- I'm still
thinking about it in light of some of the problems I mentioned in my last message.
That's good for efficiency, particularly in the presence of MACROLET,
and gives the human reader of Lisp code at least a few stable landmarks
to hold on to. The price is that if you really want to monkey around
with these structural things in an embedded language, you have to
transform the whole surrounding form and not just the item itself. To
me that seems like a reasonable price for those people who want an
embedded language that departs from Lisp syntax in such a deep way. If
you get rid of parentheses or prefix notation or argument lists, you'll
have to do a transformation on the whole form anyway; I'm just saying
that we could reasonably consider declarations to be something basic to
the syntax of the language, like argument lists, rather than thinking
of them as a funny kind of body form. Just because (DECLARE ...) looks
like any old lisp form, that doesn't mean we have to treat it as one.
I just don't buy this claim that it's an efficiency issue. Moon's recent
messages claims this was done efficiently on the Lisp Machine.
Experience with Scheme likewise suggests this can be done efficiently.
You only have to do it once when the form is first seen by the
interpreter and never again. There's no loss of efficiency there. In
fact (leaving aside the question of macrofied declares for the context
of this sentence), if you are lazily or repeatedly expanding macros,
you're risking having a function change its behavior in midstream on any
expression involving macros, which I'd claim is a violation of the maxim
that interpreted and compiled code should execute the same for legal