From: Blake McBride
Subject: Contradiction in separation of NIL and #f
Date: 
Message-ID: <138gqtotbfr8k20@news.supernews.com>
Contradiction in separation of NIL and #f

Lisp has long used NIL as "false" or #f.  This was very convenient
since lisp is a list processing language, traversing through a list is
very often done.  Having NIL and #f equal means one could use:

	(while  lst   ...
		or
	(if  lst  ...

With the separation of NIL and #f in scheme one is forced into:

	(while  (not (null? lst))   ...
		or
	(if (not (null? lst))   ...

The argument for separating NIL and false was in the name of clarity
as opposed to depending on a coincidence.  It would be much more clear
(to a beginner?) what was going on.  (Although, if you really want to
be clear, perhaps we should all program in ADA.  ADA is a language in
which virtually every line of code has to do with clarity and
virtually none has to do with solving the problem at hand!)

The problem is that scheme has eliminated, rather arbitrarily, one
instance of dependence on a trick but left so many others that it
renders the NIL / false separation no more than a constant annoyance.
For example, if NIL and #f are kept apart, why allow anything except
#f equal true?  Yes, I know it is very convenient (just like #f and
NIL being equal), but it is also "unclear".  Having:

	(if  "abc"  6  7)

return 6 is absolute nonsense.  Scheme has chosen clarity and
correctness in one instance and convenience in another.  It is very
inconsistent.  If you wanted to be truly consistent:

	(+  "abc"  6)

returns a type error.  So:

	(if  "abc"  6  7)

should also return a type error.  The same is true for scheme's:

	and
	or
	not
	cond
	etc.

Look, ADA already has the market on clarity and correctness.  Lisp and
scheme have the elegant, expressiveness, and power market.  Why
arbitrarily go down the clarity path with the separation of NIL and #f
- it is a mistake.  The only other "consistent" choice is to separate
#t from all else, make all logic operations require #t or #f, and make
scheme the ADA of lisp.

Blake McBride
·····@mcbride.name

From: Mark Tarver
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <1183370185.605865.138080@k79g2000hse.googlegroups.com>
On 2 Jul, 04:06, "Blake McBride" <····@mcbride.name> wrote:
> Contradiction in separation of NIL and #f
>
> Lisp has long used NIL as "false" or #f.  This was very convenient
> since lisp is a list processing language, traversing through a list is
> very often done.  Having NIL and #f equal means one could use:
>
>         (while  lst   ...
>                 or
>         (if  lst  ...
>
> With the separation of NIL and #f in scheme one is forced into:
>
>         (while  (not (null? lst))   ...
>                 or
>         (if (not (null? lst))   ...
>
> The argument for separating NIL and false was in the name of clarity
> as opposed to depending on a coincidence.  It would be much more clear
> (to a beginner?) what was going on.  (Although, if you really want to
> be clear, perhaps we should all program in ADA.  ADA is a language in
> which virtually every line of code has to do with clarity and
> virtually none has to do with solving the problem at hand!)
>
> The problem is that scheme has eliminated, rather arbitrarily, one
> instance of dependence on a trick but left so many others that it
> renders the NIL / false separation no more than a constant annoyance.
> For example, if NIL and #f are kept apart, why allow anything except
> #f equal true?  Yes, I know it is very convenient (just like #f and
> NIL being equal), but it is also "unclear".  Having:
>
>         (if  "abc"  6  7)
>
> return 6 is absolute nonsense.  Scheme has chosen clarity and
> correctness in one instance and convenience in another.  It is very
> inconsistent.  If you wanted to be truly consistent:
>
>         (+  "abc"  6)
>
> returns a type error.  So:
>
>         (if  "abc"  6  7)
>
> should also return a type error.  The same is true for scheme's:
>
>         and
>         or
>         not
>         cond
>         etc.
>
> Look, ADA already has the market on clarity and correctness.  Lisp and
> scheme have the elegant, expressiveness, and power market.  Why
> arbitrarily go down the clarity path with the separation of NIL and #f
> - it is a mistake.  The only other "consistent" choice is to separate
> #t from all else, make all logic operations require #t or #f, and make
> scheme the ADA of lisp.
>
> Blake McBride
> ····@mcbride.name

Yes, you're right.  If you go for the #f / NIL separation you really
should carry it through the standard boolean operations.  In Qi that's
what happened.

If you're writing in CL, a nice trick is to define the globals true
and false to T and NIL.   In that way your code becomes clearer
without losing the (alleged) benefits of identifying false with NIL.

Mark
From: Tamas Papp
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <87k5tjpds8.fsf@pu100877.student.princeton.edu>
"Blake McBride" <·····@mcbride.name> writes:

> Look, ADA already has the market on clarity and correctness.  Lisp and
> scheme have the elegant, expressiveness, and power market.  Why
> arbitrarily go down the clarity path with the separation of NIL and #f
> - it is a mistake.  The only other "consistent" choice is to separate
> #t from all else, make all logic operations require #t or #f, and make
> scheme the ADA of lisp.

Both choices are "consistent" in the sense of formal logic.  What you
mean is that having seen Scheme's #f, you had expectations about what
forms should evaluate as true, and the language didn't conform to
these expectations.  Tough luck.  If you really hate that in Scheme,
you can always write the macros my-if, my-while etc.

Tamas
From: Dan Bensen
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <f6adkq$mka$1@wildfire.prairienet.org>
 > "Blake McBride" <·····@mcbride.name> writes:
 >> Why arbitrarily go down the clarity path with the separation of
 >> NIL and #f ...  The only other "consistent" choice is to separate
 >> #t from all else, make all logic operations require #t or #f

Tamas Papp wrote:
 > Both choices are "consistent" in the sense of formal logic.  What you
 > mean is that having seen Scheme's #f, you had expectations about what
 > forms should evaluate as true, and the language didn't conform to
 > these expectations.

What he means is that the two decisions are stylistically inconsistent
with each other.  Hi Schemers! :)

-- 
Dan
www.prairienet.org/~dsb/
From: Pillsy
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <1183397256.013757.38680@o61g2000hsh.googlegroups.com>
On Jul 1, 11:06 pm, "Blake McBride" <····@mcbride.name> wrote:
[...]
> The argument for separating NIL and false was in the name of clarity
> as opposed to depending on a coincidence.  It would be much more clear
> (to a beginner?) what was going on.

I think there's another argument for the separation that's somewhat
more compelling: it distinguishes between nothing being there and the
boolean value False being there. If you  have that separation, you can
(probably?) do without things like the second return value of GETHASH.
Since CL already has things like that second return value, it's not a
huge deal for us, but the functions that don't return that second
value can be really irritating.

Does Scheme even have multiple return values?

Cheers, Pillsy

[...]
From: Pascal Costanza
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <5esrsnF38oa7rU1@mid.individual.net>
Pillsy wrote:
> On Jul 1, 11:06 pm, "Blake McBride" <····@mcbride.name> wrote:
> [...]
>> The argument for separating NIL and false was in the name of clarity
>> as opposed to depending on a coincidence.  It would be much more clear
>> (to a beginner?) what was going on.
> 
> I think there's another argument for the separation that's somewhat
> more compelling: it distinguishes between nothing being there and the
> boolean value False being there. If you  have that separation, you can
> (probably?) do without things like the second return value of GETHASH.
> Since CL already has things like that second return value, it's not a
> huge deal for us, but the functions that don't return that second
> value can be really irritating.
> 
> Does Scheme even have multiple return values?

Yes.

The most compelling argument I have heard so far is that type-of can be 
more informative when the concepts of NIL as a symbol, as an empty list 
and as a boolean value are strictly separated.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Chris Russell
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <1183412958.128616.23700@w5g2000hsg.googlegroups.com>
On 2 Jul, 18:27, Pillsy <·········@gmail.com> wrote:
 If you  have that separation, you can
> (probably?) do without things like the second return value of GETHASH.
> Since CL already has things like that second return value, it's not a
> huge deal for us, but the functions that don't return that second
> value can be really irritating.

I don't see how.
You still won't be able to distinguish between #f that was set inside
the hash table or a failure to return.

Of course you could wrap up a successful return as (list value) if
gethash succeeds and return nil or #f otherwise.
From: Pillsy
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <1183420061.627875.37690@57g2000hsv.googlegroups.com>
On Jul 2, 5:49 pm, Chris Russell <·····················@gmail.com>
wrote:
[...]
> You still won't be able to distinguish between #f that was set inside
> the hash table or a failure to return.

I was thinking you'd return NIL if the hash table doesn't contain a
relevant entry, actually. Just like you return NIL for a list that
contains no elements.

Cheers,
Pillsy

[...]
From: Chris Russell
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <1183452143.632824.96300@n2g2000hse.googlegroups.com>
On 3 Jul, 00:47, Pillsy <·········@gmail.com> wrote:
> On Jul 2, 5:49 pm, Chris Russell <·····················@gmail.com>
> wrote:
> [...]
>
> > You still won't be able to distinguish between #f that was set inside
> > the hash table or a failure to return.
>
> I was thinking you'd return NIL if the hash table doesn't contain a
> relevant entry, actually. Just like you return NIL for a list that
> contains no elements.

But assuming you can set an entry in the hash table to NIL this still
doesn't help.
From: David Rush
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <1183452941.567712.9180@n60g2000hse.googlegroups.com>
On Jul 3, 9:42 am, Chris Russell <·····················@gmail.com>
wrote:
> On 3 Jul, 00:47, Pillsy <·········@gmail.com> wrote:
>
> > On Jul 2, 5:49 pm, Chris Russell <·····················@gmail.com>
> > wrote:
> > [...]
>
> > > You still won't be able to distinguish between #f that was set inside
> > > the hash table or a failure to return.
>
> > I was thinking you'd return NIL if the hash table doesn't contain a
> > relevant entry, actually. Just like you return NIL for a list that
> > contains no elements.
>
> But assuming you can set an entry in the hash table to NIL this still
> doesn't help.

yep. It's a problem in any associative data structure. Personally, I
have switched over almost entirely to CPS for any kind of type
inconsistency in function return types. In Scheme it's so easy to do,
why wouldn't you? And then you get additional compiler optimizations
from Sufficiently Smart Compilers, too :)

(define (assoc-k s alist k-success k-failure)
  (let find ((as alist))
    (if (null? as)
      (k-failure s alist)
      (if (equal? s (caar as))
        (k-success (cdar as))
        (find (cdr as))
        ))))

Note to the R6RS Committee: this is the function that *ought* to be in
the standard library. You can keep the broken one of course if you
want to :)

david
--
http://cyber-rush.org/drr <- a very messy construction^Wweb site
From: =?utf-8?b?R2lzbGUgU8ODwqZsZW5zbWk=?= =?utf-8?b?bmRl?=
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <0n7ipfujn9.fsf@apal.ii.uib.no>
Chris Russell <·····················@gmail.com> writes:

> On 3 Jul, 00:47, Pillsy <·········@gmail.com> wrote:
> > On Jul 2, 5:49 pm, Chris Russell <·····················@gmail.com>
> > wrote:
> > [...]
> >
> > > You still won't be able to distinguish between #f that was set inside
> > > the hash table or a failure to return.
> >
> > I was thinking you'd return NIL if the hash table doesn't contain a
> > relevant entry, actually. Just like you return NIL for a list that
> > contains no elements.
> 
> But assuming you can set an entry in the hash table to NIL this still
> doesn't help.
> 

Actually gethash return two values, the first value is the return value, the
second value is the success of the call. For example:

[1]> (defparameter *hash* (make-hash-table))
*HASH*
[2]> (setf (gethash 'key1 *hash*) NIL)
NIL
[3]> (gethash 'key1 *hash*)
NIL ;
T
[4]> (gethash 'key2 *hash*)
NIL ;
NIL

This means that you can use multiple-value-bind or similar to check whether
the NIL was intentional or not:

(multiple-value-bind (value status) (gethash 'key1 *hash*)
  (if (null status)
    (format t "The value was to set")
    (format t "The key was set with the value NIL")))

I'm sure it is possible to argue whether this is elegant or not, but at least it
is possible to distinguish the two.

-- 
Gisle Sælensminde, Phd student, Scientific programmer
Computational biology unit, BCCS, University of Bergen, Norway, 
Email: ·····@cbu.uib.no
The best way to travel is by means of imagination
From: Bruce Lewis
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <nm9r6nqg08r.fsf@mint-square.mit.edu>
"Blake McBride" <·····@mcbride.name> writes:

> Contradiction in separation of NIL and #f

This topic posted to c.l.l and c.l.s should be guaranteed to start a
major flame war, but so far you've only managed to reel in a few polite
replies.  I think you need to go back to troll school.  Or were you
serious?

-- 

http://ourdoings.com/
Amazingly simple photo sharing
From: Aaron Hsu
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <2007070213561775249-aaronhsu@sacrificumdeonet>
On 2007-07-02 12:54:12 -0500, Bruce Lewis <·······@yahoo.com> said:

> "Blake McBride" <·····@mcbride.name> writes:
> 
>> Contradiction in separation of NIL and #f
> 
> This topic posted to c.l.l and c.l.s should be guaranteed to start a
> major flame war, but so far you've only managed to reel in a few polite
> replies.  I think you need to go back to troll school.  Or were you
> serious?

I was amazed at the somewhat mundane response too! :-/

Heh, isn't this particular subject an old standby for people to start 
when they are bored and what to yell and argue?
-- 
Aaron Hsu <·········@sacrificumdeo.net>

"No one could make a greater mistake than he who did nothing because he 
could do only a little." - Edmund Burke
From: Pascal Costanza
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <5et2liF39jpv2U3@mid.individual.net>
Aaron Hsu wrote:
> On 2007-07-02 12:54:12 -0500, Bruce Lewis <·······@yahoo.com> said:
> 
>> "Blake McBride" <·····@mcbride.name> writes:
>>
>>> Contradiction in separation of NIL and #f
>>
>> This topic posted to c.l.l and c.l.s should be guaranteed to start a
>> major flame war, but so far you've only managed to reel in a few polite
>> replies.  I think you need to go back to troll school.  Or were you
>> serious?
> 
> I was amazed at the somewhat mundane response too! :-/
> 
> Heh, isn't this particular subject an old standby for people to start 
> when they are bored and what to yell and argue?

Lispers and Schemers got a lot nicer recently.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Barry Margolin
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <barmar-B40E47.20213802072007@comcast.dca.giganews.com>
In article <···············@news.supernews.com>,
 "Blake McBride" <·····@mcbride.name> wrote:

> For example, if NIL and #f are kept apart, why allow anything except
> #f equal true?  Yes, I know it is very convenient (just like #f and
> NIL being equal), but it is also "unclear".

I suspect it's mostly for the benefit of the short-circuiting boolean 
operators, OR and AND.  OR will return the first non-false parameter, 
and this allows it to be used for value.  Without this convenience, 
you'd have to write some convoluted code to save the value and compare 
it against #f.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Jens Axel Søgaard
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <46895618$0$36545$edfadb0f@dread12.news.tele.dk>
Blake McBride wrote:

> The problem is that scheme has eliminated, rather arbitrarily, one
> instance of dependence on a trick but left so many others that it
> renders the NIL / false separation no more than a constant annoyance.

I am slightly amused that you wonder why something characterized
as a "trick" wasn't kept in Scheme.

I in turn wonder what an ML'er would answer you.

-- 
Jens Axel S�gaard
From: Neelakantan Krishnaswami
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <slrnf8o8as.31h.neelk@gs3106.sp.cs.cmu.edu>
In article <<·························@dread12.news.tele.dk>>,
Jens Axel S�gaard <······@soegaard.net> wrote:
>Blake McBride wrote:
>>
>> The problem is that scheme has eliminated, rather arbitrarily, one
>> instance of dependence on a trick but left so many others that it
>> renders the NIL / false separation no more than a constant annoyance.
> 
> I am slightly amused that you wonder why something characterized
> as a "trick" wasn't kept in Scheme.
> 
> I in turn wonder what an ML'er would answer you.

I guess I'm officially an ML'er now, so I can give an answer. 

So, I think #t and #f should be considered their own type, and that
they should have a primitive elimination form, like (if e1 e2 e3),
and it should be an error if e1 returns anything other than #t or #f.

Then, because you're in Lisp, rather than ML, introduce a generic
function (is-true? e), which takes an object and tells you whether to
regard it as true or false. Next, introduce a macro -- call it cond --
like this:

 (cond 
   (e1  e1')
   ...
   (en  en'))

The semantics of cond are that it evaluates e1, calls is-true? on it,
and then executes e1' if it's true. If it's false, it'll try e2 in 
the same way, and so on. Finally, define the short-circuiting logical 
operators in terms of cond.

Now, you a) have a consistent separation between booleans and
everything else, and b) you can treat empty lists as false, by 
defining:

 (define-method is-true? ((x <nil>))   #f)
 (define-method is-true? ((<x <cons>)) #t)

Likewise, you can make empty hashtables, vectors, binary trees, and
streams false as well, and users can extend this to their own data
types in a completely systematic way.


-- 
Neel R. Krishnaswami
·····@cs.cmu.edu
From: Stefan Scholl
Subject: Re: Contradiction in separation of NIL and #f
Date: 
Message-ID: <0T47kpq5Ih1sNv8%stesch@parsec.no-spoon.de>
In comp.lang.lisp Blake McBride <·····@mcbride.name> wrote:
> Contradiction in separation of NIL and #f

This is very new and there were never any flame wars because of
it.