Page 146

The claim that = is less strict than eql is not strictly true, strictly speaking. = requires numeric arguments, eql doesn't.

This finickiness though means that you should always use = if you're dealing with numbers. If you use eql or equal, you'll let bad non-numeric values propagate longer. Catch bad values as early as possible.

Page 153

The application is really neat and the code is mostly excellent, except for the abundance of anonymous constants.

Page 156

defsphere is a poor name. defxxxx names are usually for macros, but this is a normal function. create-sphere or new-sphere would be better.

intersect is a poor name because it's very similar to intersection, a Common Lisp function for intersecting sets.

More importantly, this is a good example of code that should be either data-driven or object-oriented. Consider what would happen if we wanted to define a new kind of object, say a cube. We would have to change the definition of intersect to

(defun intersect (s pt xr yr zr)
      (funcall (typecase s
                  (sphere #'sphere-intersect)
                  (cube #'cube-intersect))
              s pt xr yr zr))

That's easy. But where does this definition belong? It clearly doesn't belong in the sphere definition file any more, nor does it belong in the cube file. We need a new file where intersect is defined. That file depends on each of the object definition files. And every time we define a new kind of object, we will have to redefine intersect in this file.

The data-driven and object-oriented versions turn this dependency around. In both versions, each object file depends on the file that defines the intersect method. New object files can be created freely, without ever changing the intersect file.