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

NIL, again



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

    Let me walk through an instance of the problem.  Assume an existing Lisp in
    which ()==NIL.  In Lisp, generate a list; the list will be "terminated"
    with the symbol NIL in the last CDR.  Pass the list to a Scheme routine,
    which cdr's down it until it reaches -- what?  Unless #!NULL==NIL, Scheme
    can't detect the end of the list with a simple EQ? test.  Sharing of list
    data between the two languages is effectively ruled out.

I don't agree that things are hopeless.  I will risk repetition in hope
of promoting understanding; my apologies if this message adds nothing to
what I've already said.  To implement Scheme on top of a Lisp which
identifies #!NULL (i.e. (), false) with Lisp's symbol NIL, create a new,
unique object; call it SCHEME:NIL.  Use this object to implement "the"
symbol NIL for Scheme.  Use the object #!NULL, which in Lisp is a symbol
and in Scheme is not, to represent both the empty list and false in
Scheme.

So you have the following equations:

	Lisp:		     Scheme:
	Symbol		<=>  Symbol-but-not-#!NULL
	SCHEME:NIL	<=>  The symbol NIL
	NIL, ()		<=>  (), #!NULL, #!FALSE

The phrase "the symbol NIL" is confusing.  You need to say either "the
Scheme symbol NIL" or "the Lisp symbol NIL".  Lisp and Scheme may agree
on what the empty list and false are, without agreeing on what "the
symbol NIL" is.

(define (symbol? x)
  (and x
       (or (eq? x 'nil)		;This code is read using the Scheme reader!
	   (lisp:symbolp x))))

(define (symbol->string x)
  (cond ((eq? x 'nil) "NIL")
	((not x) (error ...))
	(else (lisp:symbol-name x))))

(define (string->symbol x)
  (cond ((string-equal? x "NIL") 'nil)
	(else (lisp:intern x *scheme-package*))))

(define (null? x) (lisp:null x))

In Common Lisp, these definitions need not be quite so verbose, if you
arrange for the object SCHEME:NIL to be a Common Lisp symbol whose print
name is "NIL" (not EQ to () !).

I do not believe that you will run into trouble if you take this
approach.  Since the list terminator is the same between Lisp and
Scheme, there is no problem sharing list structure.

If you plan to use the Common Lisp reader to read Scheme expressions,
then you are in a bit of trouble; Common Lisp allows some way to define
octathorp read macros (so you can implement Scheme #!..., #I, etc.), but
no way to influence the atom reader.  But won't you have all sorts of
trouble with numbers if you don't change the atom reader?

I find it hard to believe that you would not be able to make the trivial
required change (the addition of a single COND clause, no more than two
lines of code!).  If this patch is really impossible, and you cannot use
a different reader (another tractable solution), then indeed I agree you
will be forced to equate Scheme's NIL with ().  I'm sure that would be
fine as an interim solution.  The symbol/false distinction is too
useful, and likely to be too ingrained in programs, to permit deviation
from it in the R.R. (although I agree that legalities are not at issue
here).

Jonathan