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:

CodeGood 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 18

The first example of using format

(format t "~A plus ~A equals ~A.~%" 2 3 (+2 3))

should be written

(format t "~S plus ~S equals ~S.~%" 2 3 (+2 3))

The difference is not described until Section 7.3, but the rule of thumb is to use ~S to show data accurately. Only use ~A to avoid string quotes and escape characters, e.g., when printing strings and characters as labels.

Page 24

show-squares is another example where cond is more appropriate. In this case, it avoids the need for a nested progn. Also, ~S should be used, like this

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

The use of dolist in our-length is needlessly imperative. There's no need to invoke explicit assignment. The better iterative form is do, covered in Chapter 5. Save dolist and dotimes for functions that have to be imperative, e.g., functions that print or store data in an array.