[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Functions for special operators
- To: navajo!common-lisp@su-ai
- Subject: Functions for special operators
- From: email@example.com (Jon L White)
- Date: Tue, 17 Dec 85 10:51:50 pst
[Following what appeared to be the majority opinion of some time ago, I'm
refering to "special forms" as "special operators"]
It's certainly consistent with the rest of Common Lisp for symbol-function
of a special operator to be "is an error" -- early versions of VAX/NIL put
a "trap" function there, with the interpreter dispatching through a table
which was completely independent of the symbol's function cell. Putting
any old random value [like, NIL] in the symbol-function cell would be also
But this does beg a question of implementation technology. Background on
this "question" is the following assertion, rooted in antiquity:
''The only "special operators" needed by Lisp are Lambda and Quote''
[sure, the lambda calculus reduced it to only one -- lambda -- but before
extending the discussion on this point, try to remember that Lisp isn't
exactly the lambda calculus]. For example, COND could be implemented as
(defmacro COND (&rest clauses)
`(COND-SUBR (QUOTE ,clauses)))
and then COND-SUBR would be written in the typical way that parts of an
interpreter are written. So it may appear that putting the code for
COND-SUBR directly into the symbol-function cell of COND is perfectly fine,
and maybe even a good way to distribute the code of the interpreter. After
all, it is only *how* the interpreter goes about fetching an argument for
COND that is somewhat odd; after the fetch has been completed, it doesn't
matter whether it dispatches through the symbol-function cell of COND, or
to another function obtained in another manner.
The three implementation technologies I've seen over the years are:
1) essentially nothing in the symbol-function cell of special operators;
the interpreter "discerns" and dispatches all special operators through
some other mechanism such as the table mentioned above; the compiler
also has a lot of special cases in it for them. Although this may be
closer to the spirit of CLtL, section 5.1.3, it is less commonly used.
2) extend the set of applicable, function-like objects to include FSUBRs
and MSUBRs; the former, when found in a symbol's function cell, makes
it a special operator, and the latter, when found in a symbol's function
cell, makes it a macro. The beauty of this approach is that it
disconnects the macro/special-operator question from any property of
the particular symbol which holds it; this is generally good since it
supports renaming easily, but it really isn't feasible for a Common Lisp
implementation -- as page 57 of CLtL says "... the predicates
'macro-function' and 'special-form-p' may both be true of the same
symbol". Nevertheless, it has been used in other Lisp implementations.
3) a variant of (2) -- only true functions are put into the symbol-function
cell, but some other property of the symbol [like, a bit in a "header"
word?] determines whether the meaning of that function is FSUBR of MSUBR.
There seems to be some good advantage to upgrading the macro-function idea
into an MSUBR, for it would simplify code which moves definitions around.
The mark against upgrading special operators into FSUBRs, however, is the
explicit desire of CLtL *not* to facilitate "moving special operators around"
except where there is also a macro definition (which would, of course, occupy
the symbol-function cell).
-- JonL --
P.S. Nit-picking addenda:
(i) "symbol-function cell" merely means a certain data abstraction, and
doesn't constrain the implementational technology.
(ii) the above macro definition for COND won't really work -- it would
at least have to have an &environment argument -- but it is only
a simplification for purposes of illustration.