Subject: Re: (endp lst) or (null lst)
From: Erik Naggum <erik@naggum.no>
Date: 04 Jan 2003 09:45:17 +0000
Newsgroups: comp.lang.lisp
Message-ID: <3250662317762335@naggum.no>

* Chris Gehlker <gehlker@fastq.com>
| Comes Stephen Slade to say that the canonical way to test for the
| end of proper list lst is (endp lst) rather than (null lst).  The
| HyperSpec seems to agree.  And yet I have the impression that
| almost no one uses endp.

  Almost nobody uses dotted lists to begin with, so why should they
  think of using `endp´?

  Give a function that traverses a list naïvely and tests with `null´
  a dotted lists and it will most probably stumble on the `cdr´ that
  gets a non-cons argument at the end of the list.  In all likelihood
  the program will enter the debugger or terminate ungracefully.

  A much more robust way is not to test for the end of the list at
  all, but to test for a cons cell that would require more traversal.

  Take the infinitely silly Scheme-like example of computing `length´
  with a maximum of gratuitous overhead:

(defun length (list)
  (if (cons list)
    (1+ (length (cdr list)))
    0))

  compared to the seemingly very similar:

(defun length (list)
  (if (null list)
    0
    (1+ (length (cdr list)))))

  The cdr chain of a proper list is certainly terminated by an atom
  that is `nil´, but unless you explicitly attach significance to the
  specific atom that is the cdr of the last cons, should you care so
  much as to signal an error if it is not the canonical `nil´ or are
  you no worse off if you simply ignore it?  It is sloppy to pass
  anything non-`nil´ to `cdr´; careful programming demands that you
  know that you pass `cdr´ a cons cell.

-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.