Prev Up Next
It cannot have escaped the astute reader that classes
themselves look like they could be the instances of
some class (a metaclass, if you will). Note that
all classes have some common behavior: each of them has
slots, a superclass, a list of method names, and a
method vector. make-instance looks like it could
be their shared method. This suggests that we could
specify this common behavior by another class (which
itself should, of course, be a class instance too).
In concrete terms, we could rewrite our class
implementation to itself make use of the
object-oriented approach, provided we make sure we
don't run into chicken-and-egg problems. In effect, we
will be getting rid of the class struct and its
attendant procedures and rely on the rest of the
machinery to define classes as objects.
Let us identify standard-class as the class of
which other classes are instances of. In particular,
standard-class must be an instance of itself. What
should standard-class look like?
We know standard-class is an instance, and we are
representing instances by vectors. So it is a
vector whose first element holds its class, ie,
itself, and whose remaining elements are slot values.
We have identified four slots that all classes must
have, so standard-class is a 5-element vector.
(define standard-class
(vector 'value-of-standard-class-goes-here
(list 'slots
'superclass
'method-names
'method-vector)
#t
'(make-instance)
(vector make-instance)))
Note that the standard-class vector is
incompletely filled in: the symbol
value-of-standard-class-goes-here functions as a
placeholder. Now that we have defined a
standard-class value, we can use it to identify its
own class, which is itself:
(vector-set! standard-class 0 standard-class)
Note that we cannot rely on procedures based on the
class struct anymore. We should replace all calls
of the form
(standard-class? x)
(standard-class.slots c)
(standard-class.superclass c)
(standard-class.method-names c)
(standard-class.method-vector c)
(make-standard-class ...)
by
(and (vector? x) (eqv? (vector-ref x 0) standard-class))
(vector-ref c 1)
(vector-ref c 2)
(vector-ref c 3)
(vector-ref c 4)
(send 'make-instance standard-class ...)
Prev Up Next