Subject: Re: On nil qua false [was: Re: On conditionals]
From: Erik Naggum <erik@naggum.net>
Date: Thu, 22 Nov 2001 01:55:15 GMT
Newsgroups: comp.lang.lisp
Message-ID: <3215382911849059@naggum.net>

* Thomas F. Burdick
| Do you consider (not (zerop ...)) to be a double negative?

  That depends on how you use it.  I prefer (/= 0 ...) to duoble predicates.

| But, yes, my first reaction to your code above is that FIND returns a
| boolean.  Really, it returns a list.

  But find _does_ return nil or the object you asked it to find.  It does
  _not_ return a list, because it _cannot_ return a cons unless you have
  asked it to find a cons, which is a statement about the specific call,
  not about the function in general.  (Functions like this that return nil
  or cons are member and assoc.)  The function position also returns nil or
  the position where it found something, not a cons, so its notion of true
  is simply "non-nil".

  I maintain that it would not make sense to make nil or () not be false
  without making every other object also not be true.  If punning on false
  is bad, punning on true is also bad.  If we have a pure boolean type, we
  would need to rethink this whole return value business and consider pure
  predicates, not just for things like null to see if a list is empty, but
  it would also be wrong to give it a non-list.  So this is not a question
  just of (not (null ...)), but of (and (listp ...) (not (null ...))),
  which is again what (consp ...) does more efficiently, so the whole (not
  (null ...)) thing is kind of moot.  It works today _because_ of the pun
  on true and false.  It would not make sense to use null on non-lists in a
  strict boolean-type universe, because boolean would not be the only type
  to be treated anal-retentively.

| So the body of your WHEN is being run when FIND returns a non-empty list,
| not when it returns true.

  I think you should look up what find does and returns, now...

| Imagine recasting it numerically:
| 
|   (when (not (zerop (count long-sought-thing input-stuff)))
|      (do-stuff))
| 
| if that had been:
| 
|   (when (count long-sought-thing input-stuff)
|      (do-stuff))
| 
| you would assume that COUNT was a predicate.

  But this carefully elides the context in which nil = () = false makes
  sense.  In a language where you return pointers or indices into vectors,
  0 = NULL = false makes sense.  In such a language, you could not have a
  function position that returned the position where it found something,
  because 0 would 

| No, my position is that there's a conceptual difference between the empty
| list (), and the boolean false NIL.  And that it's kinda weird that false
| is a symbol.

  Since there _is_ no "false" concept as such, but rather "nothing" vs
  "thing" that supports a _generalized false_, I think the conclusion only
  follows because you think the type boolean is defined differently than it
  is.  In fact, the boolean type is defined as the symbols t and nil.
  (Please look it up in the standard.)

| None of this causes me much of a headache, though, and it's usually a
| difference of a half a second or less to figure out that someone meant
| false, not ().

  I think this betrays a conceptual confusion.  If you realized that they
  are in fact exactly the same thing, you would not need to think about it,
  but since you think they are something they are not, it takes think time
  to undo the confusion.  It is much smarter to fix the confusion at its
  core and realize that you you cannot get what you want because what you
  want is not within the tradition that produced Common Lisp.

///
-- 
  Norway is now run by a priest from the fundamentalist Christian People's
  Party, the fifth largest party representing one eighth of the electorate.
-- 
  Carrying a Swiss Army pocket knife in Oslo, Norway, is a criminal offense.