From: Christian Lynbech
Subject: symbolp and nil
Date: 
Message-ID: <ofae5fz684.fsf@chl.ted.dk.eu.ericsson.se>
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: ·················@ted.ericsson.dk
Fax:   +45 8938 5101    | web:   www.ericsson.com
------------------------+-----------------------------------------------------
Hit the philistines three times over the head with the Elisp reference manual.
                                        - ·······@hal.com (Michael A. Petonic)

From: Barry Margolin
Subject: Re: symbolp and nil
Date: 
Message-ID: <r71D6.7$IL1.550@burlma1-snr2>
In article <··············@chl.ted.dk.eu.ericsson.se>,
Christian Lynbech  <·················@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, ······@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.
From: Lieven Marchand
Subject: Re: symbolp and nil
Date: 
Message-ID: <m366g2t8wp.fsf@localhost.localdomain>
Barry Margolin <······@genuity.net> writes:

> In article <··············@chl.ted.dk.eu.ericsson.se>,
> Christian Lynbech  <·················@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 <···@wyrd.be>
Gla�r ok reifr skyli gumna hverr, unz sinn b��r bana.
From: Pierre R. Mai
Subject: Re: symbolp and nil
Date: 
Message-ID: <87r8yrl2c9.fsf@orion.bln.pmsf.de>
Christian Lynbech <·················@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 <····@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
From: Kent M Pitman
Subject: Re: symbolp and nil
Date: 
Message-ID: <sfwelur2pnk.fsf@world.std.com>
"Pierre R. Mai" <····@acm.org> writes:

> Christian Lynbech <·················@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.
From: Erik Naggum
Subject: Re: symbolp and nil
Date: 
Message-ID: <3196799095379608@naggum.net>
* 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:
From: romeo bernardi
Subject: Re: symbolp and nil
Date: 
Message-ID: <lL6E6.3042$o3.75064@news2.tin.it>
>     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.
From: Nathan Froyd
Subject: Re: symbolp and nil
Date: 
Message-ID: <slrn9e27l2.6pf.froydnj@froyd3.laptop.rose-hulman.edu>
In article <···················@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>  ·······@rose-hulman.edu  |  http://www.rose-hulman.edu/~froydnj/

Yes, God had a deadline.  So He wrote it all in Lisp.
From: romeo bernardi
Subject: Re: symbolp and nil
Date: 
Message-ID: <WnaE6.2134$2l.77988@news1.tin.it>
"Nathan Froyd" <·······@rose-hulman.edu> ha scritto nel messaggio
···························@froyd3.laptop.rose-hulman.edu...
> In article <···················@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.
From: Marco Antoniotti
Subject: Re: symbolp and nil
Date: 
Message-ID: <y6cd7a6jhu6.fsf@octagon.mrl.nyu.edu>
"romeo bernardi" <········@tin.it> writes:

> "Nathan Froyd" <·······@rose-hulman.edu> ha scritto nel messaggio
> ···························@froyd3.laptop.rose-hulman.edu...
> > In article <···················@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.
> 

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'.
From: Christophe Rhodes
Subject: Re: symbolp and nil
Date: 
Message-ID: <sq4rvi3cth.fsf@lambda.jesus.cam.ac.uk>
Erik Naggum <····@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 ········@{~w~^ ~})" 'FORMAT T "(·@{~w ········@{~w~^ ~})")
From: Kent M Pitman
Subject: Re: symbolp and nil
Date: 
Message-ID: <sfwu23itt4n.fsf@world.std.com>
Christophe Rhodes <·····@cam.ac.uk> writes:

> Erik Naggum <····@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.
From: Christophe Rhodes
Subject: Re: symbolp and nil
Date: 
Message-ID: <sqr8yl6gpi.fsf@lambda.jesus.cam.ac.uk>
Kent M Pitman <······@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. :-)

Christophe
-- 
Jesus College, Cambridge, CB5 8BL                           +44 1223 524 842
(FORMAT T "(·@{~w ········@{~w~^ ~})" 'FORMAT T "(·@{~w ········@{~w~^ ~})")
From: Erik Naggum
Subject: Re: symbolp and nil
Date: 
Message-ID: <3196844462300865@naggum.net>
* 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?

#;Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Christophe Rhodes
Subject: Re: symbolp and nil
Date: 
Message-ID: <sqvgnx6gze.fsf@lambda.jesus.cam.ac.uk>
Erik Naggum <····@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
-- 
Jesus College, Cambridge, CB5 8BL                           +44 1223 524 842
(FORMAT T "(·@{~w ········@{~w~^ ~})" 'FORMAT T "(·@{~w ········@{~w~^ ~})")
From: Ray Blaak
Subject: Re: symbolp and nil
Date: 
Message-ID: <m3bsplwoik.fsf@blight.transcend.org>
Christophe Rhodes <·····@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,
·····@infomatch.com                            The Rhythm has my soul.