common-lisppredicatesbcl

Why does listp in SBCL Common Lisp return T for a non-list cons cell?


Global variable a is a cons cell, but NOT a list. Why does LISTP return T for it?

* (defvar a (cons 1 2))
A
* a
(1 . 2)
* (listp a)
T

Edit: Thanks to Gwang-Jin Kim for a function to substitute for what I wanted:

(defun proper-list-p (lst)
  (or (null lst)                           ; either a `'()` or:
      (and (and (consp lst)                ; a cons
                (listp (cdr lst)))         ; a cons that has a cons cell or null as CDR
           (null (cdr (last lst)))         ; not a dotted list
           (not (tailp lst (cdr lst))))))  ; not circular

Solution

  • From CLHS

    Returns true if object is of type list; otherwise, returns false.

    and the definition of the type list is:

    The types cons and null form an exhaustive partition of the type list.

    Since (1 . 2) is a cons, it's also a list.

    (listp object) == (typep object 'list) == (typep object '(or cons null))
    

    For efficiency, listp doesn't try to determine if it's a proper list, which ends with NIL. There's no standard function that does this. See Check for proper list in Common Lisp