Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

symbolp and nil

22 views
Skip to first unread message

Christian Lynbech

unread,
Apr 17, 2001, 3:17:15 PM4/17/01
to
I was quite surprised to learn that NIL and () both makes `symbolp'
return true. This is no accident or bug, the symbolp section in the
hyperspec has it as one of the examples.

Could someone enlighten me to the wisdom of this feature?


------------------------+-----------------------------------------------------
Christian Lynbech | Ericsson Telebit, Skanderborgvej 232, DK-8260 Viby J
Phone: +45 8938 5244 | email: christia...@ted.ericsson.dk
Fax: +45 8938 5101 | web: www.ericsson.com
------------------------+-----------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
- pet...@hal.com (Michael A. Petonic)

Barry Margolin

unread,
Apr 17, 2001, 3:49:43 PM4/17/01
to
In article <ofae5fz...@chl.ted.dk.eu.ericsson.se>,

Christian Lynbech <christia...@ted.ericsson.dk> wrote:
>I was quite surprised to learn that NIL and () both makes `symbolp'
>return true. This is no accident or bug, the symbolp section in the
>hyperspec has it as one of the examples.
>
>Could someone enlighten me to the wisdom of this feature?

NIL is a very special symbol. It serves the role of the empty list, and
it's also a constant that's bound to itself so you can say NIL instead of
'NIL.

Whether this is "wise" is certainly up for debate; I think the Scheme folks
successfully did without nil and also now distinguish between #f
(falsehood) and the empty list, but it took them a while to get to this
point. Common Lisp has been less willing to make drastic breaks from
Maclisp tradition like this (we still have other vestigial features like
(car nil) => nil, which some probably consider ugly). I.e. if it ain't
broke, we don't fix it, and (symbolp nil) is not considered "broken".

--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Pierre R. Mai

unread,
Apr 17, 2001, 4:04:54 PM4/17/01
to
Christian Lynbech <christia...@ted.ericsson.dk> writes:

> I was quite surprised to learn that NIL and () both makes `symbolp'
> return true. This is no accident or bug, the symbolp section in the
> hyperspec has it as one of the examples.
>
> Could someone enlighten me to the wisdom of this feature?

This isn't a feature, it is a consequence of the fact that () _is_
NIL, i.e. () is read by the reader as the symbol NIL, which represents
the empty list.

Hence symbolp doesn't return T for both NIL and (), it returns T for
NIL, which can also be written as (). There is no way that symbolp
could discern () from NIL, because they are one and the same thing.

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Kent M Pitman

unread,
Apr 17, 2001, 5:16:15 PM4/17/01
to
"Pierre R. Mai" <pm...@acm.org> writes:

> Christian Lynbech <christia...@ted.ericsson.dk> writes:
>
> > I was quite surprised to learn that NIL and () both makes `symbolp'
> > return true. This is no accident or bug, the symbolp section in the
> > hyperspec has it as one of the examples.
> >
> > Could someone enlighten me to the wisdom of this feature?
>
> This isn't a feature, it is a consequence of the fact that () _is_
> NIL, i.e. () is read by the reader as the symbol NIL, which represents
> the empty list.
>
> Hence symbolp doesn't return T for both NIL and (), it returns T for
> NIL, which can also be written as (). There is no way that symbolp
> could discern () from NIL, because they are one and the same thing.

[This looks like a reply to Pierre, but is mostly to Christian.]

Well, these could have been designed as separate objects. But traditionally
they were not. The whole symbol/nonsymbol distinction is a more recent
issue, too. A long time ago, there were only atoms and the symbolness was
a less important aspect of this particular kind of atom than it is now.
We could change it; but in our community we decided to value stability
more than aesthetics. We don't make hugely expensive, disruptive changes
just because it improves aesthetics.

This is an extremely pervasive fature of the language. When Symbolics made
the changeover from arrays of integers to arrays of characters as the way
of representing strings (in order to accomodate CL), that was a much more
technically motivated change, and yet consultant reports pegged the cost
per customer of accepting this change at between $10K and $100K per customer.
Technically desirable or not, this was a big cost for customers to accept.

Any change at all to the language, no matter how minor, probably costs the
community as a whole in the millions of dollars to accept, so has to be
very well motivated in terms of its long term benefit not just aesthetically
but in terms of improving the commercial bottom line. People have worked
with the traditional NIL = () in Lisp for now about 4 decades and while it's
a curiosity to new users, it has very little if any practical impact on
correct code. Adopting the change to make these objects distinct, by
contrast, would require very detailed code analysis to find affected programs,
probably costing in the same ballpark as that array switchover. Maybe worse.
In other words, I'd bet the cost to the Lisp community would be in the tens
of millions of dollars in lost revenue due to programmers merely trying to
change code to still compute the status quo using the new, so-called
"more aesthetic" language definition.

In the CL community, the way we decide if a change is warranted is to
weigh the importance--by looking at cost of present situation (ongoing
cost of aesthetic drain = tiny) against cost of making the change
(large) against gain due to making change (also relatively tiny).
There are a lot more pressing things than this which have not been
judged to be worth the commercial cost to fix. This would be outright
irresponsible for us to fix, if it is even broken.

Lieven Marchand

unread,
Apr 18, 2001, 1:28:06 PM4/18/01
to
Barry Margolin <bar...@genuity.net> writes:

> In article <ofae5fz...@chl.ted.dk.eu.ericsson.se>,
> Christian Lynbech <christia...@ted.ericsson.dk> wrote:
> >I was quite surprised to learn that NIL and () both makes `symbolp'
> >return true. This is no accident or bug, the symbolp section in the
> >hyperspec has it as one of the examples.
> >
> >Could someone enlighten me to the wisdom of this feature?
>
> NIL is a very special symbol. It serves the role of the empty list, and
> it's also a constant that's bound to itself so you can say NIL instead of
> 'NIL.
>
> Whether this is "wise" is certainly up for debate; I think the Scheme folks
> successfully did without nil and also now distinguish between #f
> (falsehood) and the empty list, but it took them a while to get to this
> point. Common Lisp has been less willing to make drastic breaks from
> Maclisp tradition like this (we still have other vestigial features like
> (car nil) => nil, which some probably consider ugly). I.e. if it ain't
> broke, we don't fix it, and (symbolp nil) is not considered "broken".

For a different perspective on the wisdom of the scheme folks, see
http://www.lisp.org/humor/large-programs.html

It's not worth a major battle, but I find the both the punning of nil
and the empty list, and (car nil) = (cdr nil) = nil occasionally
useful.

--
Lieven Marchand <m...@wyrd.be>
Glaðr ok reifr skyli gumna hverr, unz sinn bíðr bana.

Erik Naggum

unread,
Apr 20, 2001, 7:44:55 PM4/20/01
to
* Christian Lynbech

> I was quite surprised to learn that NIL and () both makes `symbolp'
> return true. This is no accident or bug, the symbolp section in the
> hyperspec has it as one of the examples.

`nil' and () are identical. This is a tremendous feature. Without it,
you would have to convert all expressions to explicit boolean values to
test their value, because only #false would be false and probably also
only #true would be true. Scheme suffers greatly from having dispensed
with this "polymorphic" design in their misguided zeal for an utterly
impractical "purity". When (if () :true :false) yields :true, you know
you have experienced bad language design.

> Could someone enlighten me to the wisdom of this feature?

It means that nothing is a thing, instead of not a thing, which would
have made everyone test for thingness before they could use a thing.

That the empty list has a "virtual" car and cdr slot which are also nil
is such an elegant pun that it should be rewarded. Scheme freaks will
never understand this, but the ability to refer to such a special value
as "false" in more than one way is tremendously useful and makes for very
elegant and compact code. There's a very nice poem about this that has
probably been posted several times, but it bears repeating:

A SHORT BALLAD DEDICATED TO THE GROWTH OF PROGRAMS
==================================================
by
Ashwin Ram

This is a tale of a sorry quest
To master pure code at the T guru's behest
I enrolled in a class that appealing did seem
For it promised to teach fine things like T3 and Scheme

The first day went fine; we learned of cells
And symbols and lists and functions as well
Lisp I had mastered and excited was I
For to master T3 my hackstincts did cry

I sailed through the first week with no problems at all
And I even said "closure" instead of "function call"
Then said the master that ready were we
To start real hacking instead of simple theory

Will you, said he, write me a function please
That in lists would associate values with keys
I went home and turned on my trusty Apollo
And wrote a function whose definition follows:

(cdr (assq key a-list))

A one-liner I thought, fool that I was
Just two simple calls without a COND clause
But when I tried this function to run
CDR didn't think that NIL was much fun

So I tried again like the good King of yore
And of code I easily generated some more:

(cond ((assq key a-list) => cdr))

It got longer but purer, and it wasn't too bad
But then COND ran out and that was quite sad

Well, that isn't hard to fix, I was told
Just write some more code, my son, be bold
Being young, not even a moment did I pause
I stifled my instincts and added a clause

(cond ((assq key a-list) => cdr)
(else nil))

Sometimes this worked and sometimes it broke
I debugged and prayed and even had a stroke
Many a guru tried valiantly to help
But undefined datums their efforts did squelch.

I returneth once more to the great sage of T
For no way out of the dilemma I could see
He said it was easy -- more lines must I fill
with code, for FALSE was no longer NIL.

(let ((val (assq key a-list)))
(cond (val (cdr val))
(else nil)))

You'd think by now I might be nearing the end
Of my ballad which seems bad things to portend
You'd think that we could all go home scot-free
But COND eschewed VAL; it wanted #T

So I went back to the master and appealed once again
I said, pardon me, but now I'm really insane
He said, no you're not really going out of your head
Instead of just VAL, you must use NOT NULL instead

(let ((val (assq key a-list)))
(cond ((not (null? val)) (cdr val))
(else nil)))

My song is over and I'm going home to bed
With this ineffable feeling that I've been misled
And just in case my point you have missed
Somehow I preferred (CDR (ASSQ KEY A-LIST))

#:Erik
--
I found no peace in solitude.
I found no chaos in catastrophe.
-- :wumpscut:

romeo bernardi

unread,
Apr 20, 2001, 11:02:41 PM4/20/01
to

> Well, that isn't hard to fix, I was told
> Just write some more code, my son, be bold
> Being young, not even a moment did I pause
> I stifled my instincts and added a clause
>
> (cond ((assq key a-list) => cdr)
> (else nil))
>
> Sometimes this worked and sometimes it broke
> I debugged and prayed and even had a stroke
> Many a guru tried valiantly to help
> But undefined datums their efforts did squelch.

(cond ((assq key a-list) => cdr))

would have been a correct answer to his assignment, if he was using Scheme.
Interested parties can check the definition of ASSQ.

P.

Nathan Froyd

unread,
Apr 21, 2001, 1:49:33 AM4/21/01
to
In article <lL6E6.3042$o3.7...@news2.tin.it>, romeo bernardi wrote:
>> (cond ((assq key a-list) => cdr)
>> (else nil))
>>
>> Sometimes this worked and sometimes it broke
>> I debugged and prayed and even had a stroke
>> Many a guru tried valiantly to help
>> But undefined datums their efforts did squelch.
>
>(cond ((assq key a-list) => cdr))
>
>would have been a correct answer to his assignment, if he was using Scheme.
>Interested parties can check the definition of ASSQ.

Chez Scheme Version 6.0a
Copyright (c) 1998 Cadence Research Systems

> (define al '((1 . 2) (3 . 4) (5 . 6)))
> (cond ((assq 1 al) => cdr))
2
> (cond ((assq 10 al) => cdr))
>

The reason nothing was printed was because the return result was the
"undefined result" -- like what one would get from SET!.

Looks like it's not nearly as easy as one might think.
--
</nathan> fro...@rose-hulman.edu | http://www.rose-hulman.edu/~froydnj/

Yes, God had a deadline. So He wrote it all in Lisp.

romeo bernardi

unread,
Apr 21, 2001, 3:10:46 AM4/21/01
to

"Nathan Froyd" <fro...@rose-hulman.edu> ha scritto nel messaggio
news:slrn9e27l2....@froyd3.laptop.rose-hulman.edu...

> In article <lL6E6.3042$o3.7...@news2.tin.it>, romeo bernardi wrote:
> >> (cond ((assq key a-list) => cdr)
> >> (else nil))
> >>
> >> Sometimes this worked and sometimes it broke
> >> I debugged and prayed and even had a stroke
> >> Many a guru tried valiantly to help
> >> But undefined datums their efforts did squelch.
> >
> >(cond ((assq key a-list) => cdr))
> >
> >would have been a correct answer to his assignment, if he was using
Scheme.
> >Interested parties can check the definition of ASSQ.
>
> Chez Scheme Version 6.0a
> Copyright (c) 1998 Cadence Research Systems
>
> > (define al '((1 . 2) (3 . 4) (5 . 6)))
> > (cond ((assq 1 al) => cdr))
> 2
> > (cond ((assq 10 al) => cdr))
> >
>
> The reason nothing was printed was because the return result was the
> "undefined result" -- like what one would get from SET!.
>
> Looks like it's not nearly as easy as one might think.

The assignment said nothing about what should happen if the symbol is not
present in the alist.
Returning an unspecified value is as good as returning NIL.

P.

Christophe Rhodes

unread,
Apr 21, 2001, 3:57:14 AM4/21/01
to
Erik Naggum <er...@naggum.net> writes:

> Scheme suffers greatly from having dispensed
> with this "polymorphic" design in their misguided zeal for an utterly
> impractical "purity". When (if () :true :false) yields :true, you know
> you have experienced bad language design.

What about (if #() :true :false)? (if 0 :true :false)?
(if (make-hash-table) :true :false)?

What, apart from Lisp's history, makes the empty list special? I'll
buy the argument that it's great for rapid prototyping in some
circumstances, but so could my three examples above be.

> That the empty list has a "virtual" car and cdr slot which are also nil
> is such an elegant pun that it should be rewarded. Scheme freaks will
> never understand this, but the ability to refer to such a special value
> as "false" in more than one way is tremendously useful and makes for very
> elegant and compact code. There's a very nice poem about this that has
> probably been posted several times, but it bears repeating:

> [ ... ]


> Somehow I preferred (CDR (ASSQ KEY A-LIST))

(defvar *a-list* '((1 . 2) (2 . 3) (3 . nil)))
(cdr (assq 3 *a-list*))

Christophe
--
Jesus College, Cambridge, CB5 8BL +44 1223 524 842
(FORMAT T "(~@{~w ~}~3:*'~@{~w~^ ~})" 'FORMAT T "(~@{~w ~}~3:*'~@{~w~^ ~})")

Kent M Pitman

unread,
Apr 21, 2001, 7:00:24 AM4/21/01
to
Christophe Rhodes <cs...@cam.ac.uk> writes:

> Erik Naggum <er...@naggum.net> writes:
>
> > Scheme suffers greatly from having dispensed
> > with this "polymorphic" design in their misguided zeal for an utterly
> > impractical "purity". When (if () :true :false) yields :true, you know
> > you have experienced bad language design.
>
> What about (if #() :true :false)? (if 0 :true :false)?
> (if (make-hash-table) :true :false)?

I would have no problem with a language defined this way.
The MOO language has such false values and works fine that way.



> What, apart from Lisp's history, makes the empty list special?

Nothing that I know of.

However, if your question is, why don't we change it, I've remarked in
another post, I think, that I estimate the cost to the community of changing
this to be somewhere in the tens of millions of dollars or higher, while
the benefit of the change to be, in dollars, about zero in the sense that
the language is not unpredictable in its behavior now, so programs written
by competent programmers do not err substantially more often due to the
current design than they would if the design were changed. For all anyone
knows, they presently err less than they would if the design were changed,
but more probably it's a wash.

The difference between the CL and Scheme communities is that in the CL
community, we don't change the language when the cost/benefit works out
this way.

> I'll buy the argument that it's great for rapid prototyping in some
> circumstances,

It might be, but I won't even bother worrying about this. My argument does
not rest on the feature's utility--only on the cost of change.

> but so could my three examples above be.

The cost of those changes would be about the same, each in the tens of
millions of dollars, and the utility gain would be negligible again. So I
wouldn't make those changes either. (Though personallyI would prefer those
changes, since I have found personally that I prefer MOO's design with
more false values rather than Scheme's with fewer. This isn't a scientific
observeration, just a personal preference. Others might disagree. But it is
a reasoned choice based on actual use, not a theoretical one based on counting
the possibilities and preferring 1 to "more than 1" or some such tommyrot.)

> > That the empty list has a "virtual" car and cdr slot which are also nil
> > is such an elegant pun that it should be rewarded. Scheme freaks will
> > never understand this, but the ability to refer to such a special value
> > as "false" in more than one way is tremendously useful and makes for very
> > elegant and compact code. There's a very nice poem about this that has
> > probably been posted several times, but it bears repeating:
>
> > [ ... ]
> > Somehow I preferred (CDR (ASSQ KEY A-LIST))
>
> (defvar *a-list* '((1 . 2) (2 . 3) (3 . nil)))
> (cdr (assq 3 *a-list*))

"Doctor it hurts when I do this."
"Then don't do that."

Btw, whether that's a "bug" depends on whether you intended the nil to make
that entry invisible. I've seen programs where such an alist entry is used
to good advantage.

Seriously, computer science is full of "cheats" that trade felicity for
computational advantage. There is no moralizing to be had about this--
speed invariably comes from such observations, and slowness from ignoring
them. And that's true both of coding speed and of execution speed. We
learn to use what we are given; goodness of a style is a DEPENDENT effect
of design, NOT an independent effect. Good CL programmers know about the
alist issue and use it to their advantage.

GETHASH has a better design by allowing you to get a second return value and
to pass a suitable default. If you don't trust cdr, you could make a GETCDR
with a design like GETHASH.

(defun getcdr (purported-cons &optional (default nil))
(etypecase purported-cons
(cons (values (cdr purported-cons) t))
(null (values default nil))))

It's already entirely within your design control to make and use such a better
primitive, and even to make it inline, so you can rewrite:

(+ (or (cdr (assoc x *alist*))
*default-value*)
4)

as

(+ (getcdr (assoc x *alist*) *default-value*) 4)

but you know what you're going to find? Now you have to write:

(+ (or (getcdr (assoc x *alist*) *default-value*)
*default-value*)
4)

because the alist might contain (3 . nil). Fine, you say, let's fix the
language to not make NIL false. Ok, then you'll have to write:

(+ (let ((val (getcdr (assoc x *alist*) *default-value*)))
(if (numberp val) val *default-value*))
4)

And then some manager is going to come along and say "How come you're doing
all those tests on the result there? Can't you just make sure *alist*
always contains numbers?"

The point? That there are myriad right and wrong ways to write this, and
what makes them right or wrong depends on how carefully you program.
Putting (3 . t) in the alist isn't going to help either, after all. But
hopefully no one's going to do that.

Shrug.

MEANWHILE, C code is just taking the value of some pointer location and using
it, valid or not, and it's too hard for anyone to prove whether it's right
or wrong, so no manager flags that. And geez, it's so fast when you do it
in C compared to Lisp, right? Well, maybe not that particular thing. But
the coding style in general. ("reach in and grab something, assume it's
the thing you want and of the type you want, then move along.") That's
the industry standard.

What Lisp does is predictable, possible to make efficient, and would be
expensive to change. Even just talking about this is expensive to the
community because it is not going to change. One of the only things that
has kept Lisp alive over the years, I think, is its refusal to seriously
entertain design-by-alleged-aesthetics issues like this and its steadfast
insistance on moving forward after a competent design rather than, as in
Scheme, circling until you can prove not only a competent design but a
uniquely competent one. It's that fact that makes good use of the many
talented people in the Lisp community--not wasting them on solved problems
but keeping their eyes on new problems. It's shameful the number of man
years wasted by allowing the many intelligent people in the Scheme community
to indulge the mass illusion that a better design of the language could come
at the level of DEFINE, such as in the multi-year war over whether
(define (foo x) x) should be allowed as a synonym for
(define foo (lambda (x) x)) or a host of other trivial issues. Meanwhile
the world passes these people by. Fine to have aestetics, but not to allow
them to dominate the activity.

Java learned what Lisp learned. Package up a functionality, nail it shut,
move on. It won't be perfect, but it will be so often good enough just to
have anything at all standard, that the ability to keep climbing the food
chain will dominate virtually all else. Java is outpacing Lisp on this
score, and any discussion the Lisp community wastes on whether NIL and ()
being the same item is "morally right" or "morally wrong" drains the
lifeblood of our community by keeping it from focusing on issues that
matter.

The language will not and need not change on this point.
Learn to enjoy what it does.
Move along.

Erik Naggum

unread,
Apr 21, 2001, 8:21:02 AM4/21/01
to
* Christophe Rhodes

> What, apart from Lisp's history, makes the empty list special?

The technical qualities of the thee objects you used make it hard to use
them as false values. Programming languages are not developed in void,
so there are essential differences at a level where bad theory sees none.
Theory as abstraction is great, as long as we remember that what it has
ignored in the process of abstraction must be put back in to realize it.

The empty list is a building block for the list made of conses. I guess
that's "Lisp's history", too, and that you could use that "argument"
forever, but building lists from conses is a good decision. It needs an
"end of list" marker that takes no space. It must be unique. This means
that the empty vector is a useless suggestion, because it is not unique.
If it were attempted made unique, there would be a very different way to
represent the empty vector from other vectors. Like nil, it would have
to have special code in accessors of its constituents, but what you do
with a unique empty vector? It has no purpose. The empty hash-table is
even less useful. To make the empty hash-table "false" would require a
fast and efficient means to decide whether a hash-table is empty. This
is not the case. It is impossible to make as efficient as the test for
object identity that nil does. To use 0 as the false value would make
sense if we didn't want a boolean type. It is useful in C and the like
because of the pun on NULL pointers, 0 used in a pointer context.

> I'll buy the argument that it's great for rapid prototyping in some
> circumstances, but so could my three examples above be.

"Great for rapid prototyping" is an insult to the work of a large number
of people and especially to their intelligence. It's a rush to judgment
by an ignorant, which is the one thing I really loathe.

> > Somehow I preferred (CDR (ASSQ KEY A-LIST))
>
> (defvar *a-list* '((1 . 2) (2 . 3) (3 . nil)))
> (cdr (assq 3 *a-list*))

Huh? What was your argument?

Marco Antoniotti

unread,
Apr 21, 2001, 1:14:25 PM4/21/01
to

"romeo bernardi" <bern...@tin.it> writes:

Fine, but the bottom line is: why use Scheme `assq' when you can use
Common Lisp ASSOC?

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Christophe Rhodes

unread,
Apr 21, 2001, 6:11:17 PM4/21/01
to
Erik Naggum <er...@naggum.net> writes:

> * Christophe Rhodes
> > [ from the poem posted by Erik ]

> > > Somehow I preferred (CDR (ASSQ KEY A-LIST))
> >
> > (defvar *a-list* '((1 . 2) (2 . 3) (3 . nil)))
> > (cdr (assq 3 *a-list*))
>
> Huh? What was your argument?

The argument was that I would worry if I saw (cdr (assq key a-list))
in code, because I would be asking myself if the programmer knew the
possible pitfalls. As Kent says in his followup to my post, it's
perfectly possible to set the cdr to nil to hide the entry, and other
such programming niceties, but seeing the above in code doesn't
automatically give the warm fuzzies like

(multiple-value-bind (value found)
(gethash key *hash-table*)
(when found
(do-stuff-with value)))

does.

Christophe Rhodes

unread,
Apr 21, 2001, 6:17:13 PM4/21/01
to
Kent M Pitman <pit...@world.std.com> writes:

> > but so could my three examples above be.
>
> The cost of those changes would be about the same, each in the tens of
> millions of dollars, and the utility gain would be negligible again. So I
> wouldn't make those changes either. (Though personallyI would prefer those
> changes, since I have found personally that I prefer MOO's design with
> more false values rather than Scheme's with fewer. This isn't a scientific
> observeration, just a personal preference. Others might disagree. But it is
> a reasoned choice based on actual use, not a theoretical one based on counting
> the possibilities and preferring 1 to "more than 1" or some such tommyrot.)

Heh. Just to make my position clear, I wasn't advocating or even
suggesting such a change; call it playing with hypotheticals, if you
will.

> > (defvar *a-list* '((1 . 2) (2 . 3) (3 . nil)))
> > (cdr (assq 3 *a-list*))
>
> "Doctor it hurts when I do this."
> "Then don't do that."

Oh, I know. But unfortunately I don't control all the programmers out
there. I'm working on it, though.

> Java learned what Lisp learned. Package up a functionality, nail it shut,
> move on. It won't be perfect, but it will be so often good enough just to
> have anything at all standard, that the ability to keep climbing the food
> chain will dominate virtually all else. Java is outpacing Lisp on this
> score, and any discussion the Lisp community wastes on whether NIL and ()
> being the same item is "morally right" or "morally wrong" drains the
> lifeblood of our community by keeping it from focusing on issues that
> matter.

Thank you. I think that this is the point.

I shall refrain from further contributions to philosophical
discussions until I've written some more useful code. :-)

Ray Blaak

unread,
Apr 25, 2001, 1:13:07 AM4/25/01
to
Christophe Rhodes <cs...@cam.ac.uk> writes:
> What, apart from Lisp's history, makes the empty list special? I'll
> buy the argument that it's great for rapid prototyping in some
> circumstances, but so could my three examples above be.

nil can be consistently interpreted as "nothing", as in most
languages. E.g. nil is "no list", "no hashtable", "no symbol", etc.

The specialness of the empty list is that the implementation of a list as a
pointer to the next cons cell means that "no list" and the empty list have the
same representation.

For other objects, on the other hand, "empty" and "none" are not the
same. E.g. an empty vector is an array with a length of 0, which is different
from having no vector at all.

--
Cheers, The Rhythm is around me,
The Rhythm has control.
Ray Blaak The Rhythm is inside me,
bl...@infomatch.com The Rhythm has my soul.

0 new messages