Date: 18 May 1985 14:11 edt
From: Kent M Pitman <KMP at SCRC-STONY-BROOK>
Subject: DYNAMIC/LEXICAL, *LEXPR, "Special Operator" vs "Special
Form"
Date: 18 May 85 9:30:27 PDT
From: masinter.PA@Xerox.ARPA
... As long as an incompatible name is being considered, how about changing
the name? While there's some amusement in having SPECIAL a special form,
the novice may well wonder, "well, what's so SPECIAL about them?". Guy
was careful to call them DYNAMIC in the book; it sounds like a more
appropriate name for a (different syntax) declaration.
-- DYNAMIC/LEXICAL --
It would seem reasonable that CL86 should add DYNAMIC as a synonym for SPECIAL
in the declaration world, and LEXICAL for symmetry. Then in CL88 could flush
SPECIAL (or make it mean something incompatible).
Yes.
-- *LEXPR --
Can we get a ruling on whether
(FUNCTION (FOO INTEGER &OPTIONAL INTEGER))
is a valid declaration? p159 is very vague on the subject, giving no syntax
restrictions for the arglist components at all. (Only through the limited
fixed-arg example can you even infer that the arglist given should contain
type names and not be the actual arglist used by the function.)
First, there is an error in the equivalence between the FUNCTION and
FTYPE decl. specifiers. The equivalence should be:
(FUNCTION name arglist result-type-1 result-type-2 ...)
<=> (FTYPE (FUNCTION arglist (VALUES result-type-1 result-type-2 ...)) name)
Secondly, the definition of `arglist' appears on pg. 47 in the def. of
the FUNCTION type specifier.
Two suggestions for the FUNCTION type-specifier definition. (1) Change
the word "markers" to "lambda-list keywords". (2) Define how a keyword
and its type are associated. For example, if I have a function that
takes a keyword argument named FOO of type INTEGER, I assume the type
specifier would look like this: (FUNCTION (&KEY (FOO INTEGER)) ...).
Also, take a look at the VALUES type-specifier on the next page. I was
surprised to see that it also allows lambda-list keywords (albeit for a
reason that confuses me). Could someone give an example of the
usefulness of this?
The compiler should be encouraged to complain if it sees
(PROCLAIM '(FUNCTION FOO INTEGER &OPTIONAL INTEGER))
and later sees
(DEFUN FOO (X)
(DECLARE (SYMBOL X))
...)
but should be discouraged from complaining (or should at least be encouraged
to notice the non-fatal nature of the situation) if it later sees:
(DEFUN FOO (X &OPTIONAL (Y 1) (Z 2))
(DECLARE (INTEGER X Y Z))
...)
since in the latter case, the definition is upward compatible with the
declaration.
Again I am confused. Is the following legal?
(PROCLAIM '(FUNCTION FOO INTEGER &OPTIONAL INTEGER))
(DEFUN FOO (ARG1)
(DECLARE (INTEGER ARG1))
...)
I.E., Is downward compatibility allowed also? If not, then perhaps the
upward compatibility case should not be legal. If downwardly compatible
definitions ARE allowed, then to make a proclamation that allows
upwardly compat. definitions one should proclaim
(PROCLAIM '(FUNCTION FOO INTEGER &OPTIONAL INTEGER &REST LIST))
This would allow any number of additional optional arguments.
My guess is that neither are legal and that the arglist in the FUNCTION
type-specifier must exactly match its corresponding lambda-list.
It occurred to me that without &OPTIONAL working in FUNCTION declarations,
the functionality of Maclisp's *LEXPR declaration is conspicuously absent.
By the way, apropos of Masinter's comments above, and given that it's useful
to declare something like takes-variable-number-of-args in advance to thwart
forward-referencing problems, it might also want to be possible to declare
that some form, WITH-RANDOM-BINDINGS, is a special form so that
forward-references (which will tend to be fatal errors) to it can be
diagnosed immediately rather than having to wait for the definition to roll
by. I assume this is what he was alluding to about it might have been
more appopriate for syntax declarations, as in
(PROCLAIM '(SPECIAL WITH-RANDOM-BINDINGS)).
I guess it's a little late to try to make such a change in CL84, much less
CL86. Maybe CL88...
I agree with Scott's comment. In CL, there's no such thing as a
special-form that the compiler and interpreter don't know about.
-- "Special Operator" vs "Special Form" --
Also, I'd like to replace the term "special form" with "special operator"
when it doesn't apply to the whole form. ie, COND is not a special form,
it is a special operator (properly, it's the name of a special operator
but that's not so critical to me at this point). Certainly,
(COND ((NULL X) T) (T NIL)) is a "special form" and COND is not of the
same type so needs its own name. I would like to see SPECIAL-FORM-P made
obsolete (but retained for a while for compatibility) and SPECIAL-OPERATOR-P
introduced as an alternative. In this way, SPECIAL-FORM-P could eventually
be recycled (or flushed from CL proper and re-invented by private applications
that care) to be (AND (TYPEP x 'CONS) (SPECIAL-OPERATOR-P (CAR x))). Actually,
having the interim compatibility definition be
(OR (SPECIAL-OPERATOR-P x)
(AND (TYPEP x 'CONS) (SPECIAL-OPERATOR-P (CAR x))))
wouldn't be so bad either if we could agree to that. That way, people who
order their COND clauses correctly, could start taking advantage of the
recycled meaning right away. In any case, the important point here is that
the "form" / "operator" distinction needs to be made more clearly than we've
been making it.
Yes. I think its at least worth mentioning in the section on special
forms that calling the symbol COND a `special-form' is a misnomer;
precisely speaking it is the name of a special form. This kind of
clarification is done for other `muddy' terms in CL, e.g., DYNAMIC,
UNBOUND.