[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Functions for special operators



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

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
a macro
  (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.