[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Category Errors



From Gabriel:
     
     One minor point that came up at the Symbolics meeting last Thursday
     was category errors and whether we should try to outlaw them somehow.
     Here is an example of a category error:
     
     Suppose that MAKE-INSTANCE is a generic function. Its definition
     might look like this:
     
     	(defmethod make-instance ((class standard-class) &rest args)...)
     
     Notice that the class of the argument CLASS is STANDARD-CLASS, which
     indicates that the operation of MAKE-INSTANCE is controlled at the
     meta-object level. Suppose someone were to write:
     
     	(defmethod make-instance ((class apple-pie) &rest args)...)
     
     	(make-instance (class-prototype (class-named 'apple-pie)) ...)
     
     Here someone would be making a category error by defining a method on
     MAKE-INSTANCE at the wrong level - the class level. What makes this easy
     for a programmer to do this is the availability of CLASS-PROTOTYPE.
     However, it is never hard to do because the programmer can write:
     
     	(defvar *apple-pie-prototype* (make-instance 'apple-pie))
     
     to get his class prototype. 
     
     We have two alternatives:
     
     	1. Let sea of classes/metaclasses remain a miasma and inform
     	   programmer that he ought not mix things up.
     
     	2. Define a notion of class category or classs level and have a
     	   category of generic function for each class category.
     

From Ken Kahn:

      I think it would be a mistake to build barriers between class and
      metaclass protocols.  One of the strong appeals of CLOS is that one can
      experiment within its framework.  We once worked out how Object Lisp's
      view that classes and instances are pretty much the same could be
      implemented in PCL.  A good fraction of the OOP community believes in
      these "prototypes" which unify classes and instances.  We should be
      careful not to prohibit CLOS from evolving in that direction if people
      come to believe its a win.

I kind of agree with both Dick's and ken's concerns.  The user should be
able to do metaclass programming if he wants to but this should be an
intent, not an accident.  CLASS-PROTOTYPE working for standard-classes
is a good example of something intended to be used for metaclass
programming but works also for non metaclass classes.

I propose the following in order to categorize metaclass programming and
class programming:


                      CLASS

                        |

                  STANDARD-CLASS

                        |

                  METACLASS-CLASS


Now, all metaclass objects are instances of METACLASS-CLASS instead of
STANDARD-CLASS. This is to say that standard-class can be defined like:

(defclass STANDARD-CLASS (CLASS) 
   <slots>
   (:metaclass METACLASS-CLASS))

STANDARD-CLASS does not support metclass specific methods like 
CLASS-PROTOTYPE, METACLASS-CLASS does.

Somebody defining a new metaclass (or wanting to do metaclass
programming with his objects) will use METACLASS-CLASS as metaclass. It
will be a conscious decision.

The make-instance problem still exists but will not arise by accident,
somebody will have to do a trick like:
(defvar *apple-pie-prototype* (make-instance 'apple-pie))
and will probably get what he deserves. 

Patrick.