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.