Page 13

The comment that not and null do exactly the same thing is correct but this does not make the two functions interchangable.

Use not on values that are conceptually true or false, i.e., calls to predicate such as atom or some, or variables that hold flag values.

Use null on variables and function calls that contain or return lists. (Actually, in many cases you should use endp.)

Some examples:

Code

Good Style?

Why

(null l)

Yes

tests a list variable for emptiness

(not l)

No

tests a list variable for falseness

(not (null l))

Yes

tests a list variable for non-emptiness

(null (> x 2))

No

tests a predicate for emptiness

Final note: even though (not (null l)) is technically equivalent to just l, use the former not the latter, if l is a variable containing a list, as its name implies.

Page 16

The definition of our-member is a good example of Graham's preference for if over cond. The cond version is more standard Common Lisp, because it avoids the nested conditional:

(defun our-member (obj lst)
  (cond ((null lst) nil)
        ((eql obj (car lst)) lst)
        (t (our-member obj (cdr lst)))))
 

Page 24

show-squares is another example where cond is more appropriate. In this case, it avoids the need for a nested progn.

(defun show-squares (i end)
  (cond ((> i end) 'done)
        (t (format t "~A ~A~%" i (* i i))
           (show-squares (+ i 1) end))))

Comments? Send mail to Chris Riesbeck.