| The former is somewhat reasonable for having pi denote 3.14159... and such. It brings in its own difficulties. If nil is a variable/constant which evaluates to some nil object, then to talk about nil itself, we have to quote it. The object which it denotes doesn't print as nil; it has its own printed rep like () and we will end up seeing that printed rep and using it. So then we have two nil representations to deal with: the nil variable which we can use in evaluated contexts, and the literal nil like () that we use elsewhere. If () isn't self-evaluating (like the criminally stupid design in Scheme), we have to quote it: '(). If we have additional semantic roles for () like it being Boolean false and the bottom of the type spindle, those uses are not nicely served by the () notation, from an esthetic point of view. The list terminator is de facto a symbol because it's exploited for its identity: we care whether the cdr of a cons is or is not nil, and that's all. That's a symbolic behavior; we might as well complete things so that the symbol functions work with nil; it can have a property list, name and so on. |
So? That's no different than if you want to talk about 'pi rather than pi a.k.a. 3.14159...
> So then we have two nil representations to deal with
No different than "pi" and "3.14159".
> If () isn't self-evaluating (like the criminally stupid design in Scheme), we have to quote it: '().
I agree, () should be self-evaluating just like numbers and vectors. The behavior of () should be analogous to the behavior of 0 or 0.0 or #() or "".
> If we have additional semantic roles for () like it being Boolean false
And why would you want to do a stupid thing like that?
> The list terminator is de facto a symbol because it's exploited for its identity
First, the list terminator need not be the same thing as the empty list. The list terminator is an implementation thing. The empty list is a language-semantics thing. These need not be the same.
Second, neither of these need to be unique. There can be multiple list terminators, and there can be multiple empty lists, just as there can be multiple empty vectors and multiple empty strings and even multiple instances of the same number (which actually happens with bignums).
> we care whether the cdr of a cons is or is not nil
No, what we care about -- or at least what we should care about -- is whether the CDR of a cons is an (n.b. not the) empty list. (eq #() #()) need not be true (in fact, generally isn't). Why should (eq () ()) be any different?
And BTW under no circumstances should taking the CAR or CDR of an empty list do anything other than signal an error.