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


    Date: 22 Mar 1985 1032-CST
    From: David Bartley <Bartley%ti-csl.csnet at csnet-relay.arpa>

    3. I hate NIL.  However, I have a problem of great practical significance
    to our work that I'd like help with.  As much as I abhor it personally,
    Common Lisp equates the empty list, the logical <false> value, and the
    symbol NIL.  Here at TI's Computer Science Lab, we are building
    experimental multi-lingual program development environments for various
    machines (including our Explorer Lisp machine) in which Scheme, Common
    Lisp, Prolog, and other languages need to co-exist.  I see no practical way
    to avoid defining our Scheme's #!NULL and #!FALSE as anything other than
    the symbol NIL.  Otherwise the two languages cannot share list data.  If
    anyone has a good general solution to this problem, I'd like to hear of it.
    If not, I ask that this interpretation be permitted by the revised report.
    Surely we aren't the only ones interested in multi-lingual issues?

I don't think we need to or should allow either false or the empty list
to be a symbol.  In our PDP-10 Maclisp prototype of T, we solved the
inconsistency by doing (REMOB 'NIL).  Maclisp had a symbol NIL, which
was the same as false and the empty list, and T had a symbol NIL
(created, after the REMOB happened, the first time that READ encountered
the sequence "NIL"), which was different from the Maclisp symbol NIL.  T
and Maclisp coexisted happily.  Then we did:

(defun symbol? (x)
  (and x (symbolp x)))

Similarly, in the Common Lisp emulation package in T, we created a
parameter to READ which caused the atom NIL to read in as the empty
list, using the same framework that allows atoms like 1E3 and 5/8 to be
read as numbers instead of symbols.  Then, we emulated Common Lisp
symbols as the union of T symbols and the empty list:

(define (symbolp x)
  (or (symbol? x) (null? x)))

(define (intern x)
  (if (string-equal? x "NIL")				;(no packages)
      (string->symbol x)))

(define (symbol-name x)
  (xcond ((symbol? x) (symbol->string x))
	 ((null? x) "NIL")))

and so on.

So Common Lisp (with its own environment, syntax table, and read table
distinct from T's) coexisted happily with T.

The much harder problem is emulating the status quo when false and the
empty list are distinguished, but let's not talk about that.