I am using SBCL, Emacs, and Slime. According to the book Symbolic Computation: A gentle introduction to Common Lisp, the definition of atom
is:
The ATOM predicate returns T if its input is anything other than a cons cell.
On the other hand:
The NULL predicate returns T if its input is NIL. Its behavior is the same as the NOT predicate.
Using the REPL and taking only lists as arguments, I can only think of examples in which they retrieve the same results:
CL-USER> (atom (cons 1 nil))
NIL
CL-USER> (null (cons 1 nil))
NIL
CL-USER> (atom (cons 1 (cons 2 nil)))
NIL
CL-USER> (null (cons 1 (cons 2 nil)))
NIL
CL-USER> (atom (cons 1 2))
NIL
CL-USER> (null (cons 1 2))
NIL
CL-USER> (atom '())
T
CL-USER> (null '())
T
CL-USER> (null nil) ;; just changing notation from previous
T
CL-USER> (atom nil) ;; just changing notation from previous
T
CL-USER> (atom '(1 . 2)) ;; just changing notation from previous
NIL
CL-USER> (null '(1 . 2)) ;; just changing notation from previous
NIL
CL-USER> (atom '(1 2)) ;; just changing notation from previous
NIL
CL-USER> (null '(1 2)) ;; just changing notation from previous
NIL
CL-USER> (atom '(1)) ;; just changing notation from previous
NIL
CL-USER> (null '(1)) ;; just changing notation from previous
NIL
Based on the definitions, the examples above, and considering that non-empty lists are cons cells, I am concluding that:
if the argument is a list,
null
andatom
do have the same behavior as predicates.
Is there any counter-example for this statement? Did I miss something? Is it correct?
A list is either:
()
aka nil
, which is not a cons;null
returns true only for nil
; atom
returns true for any object which is not a cons.
Therefore, when restricted to lists, null
and atom
return true only for nil
, being the only object which is both a list and not a cons, and are, for lists, equivalent predicates.