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

Re: Random metaclasses for CL types



> I see BUILT-IN-CLASS as a series of "fronts" for objects that exist
> in a Common Lisp implementation's extended type hiearchy.
...
> Viewed in this light, there is no reason at all why the flavor-implemented
> types shouldn't simply be represented by a place-holder class that is either
> an instance of BUILT-IN-CLASS, or some implementation-dependent subclass
> thereof.
> 
> The question should arise: Why not require all "holy" types to be of
> metaclass BUILT-IN-CLASS (or implementation-dependent subclass thereof)?
> The answer comes from the fact that CLOS _does not_ provide for true
> information/structure hiding such as, say, Common Objects has.  Thus if 
> some implementation should support a "holy" type by using a STANDARD-CLASS,
> this would be visible to the end user.  Furthermore, any attempt to apply 
> some restrictions to such a metaclass (such as by providing overrides for 
> SLOT-VALUE-ABUSING-CLASS to make it look to the user like these classes 
> don't have slots) would also apply to the implementor, thereby totally 
> nullifying the advantage or using a STANDARD-CLASS in the first place.
> 
> Thus, because of the openess of CLOS, STRUCTURE-CLASS and STANDARD-CLASS
> must be allowed explicitly; but _any_ other implementational technique
> needs only BUILT-IN-CLASS as a "front", regardless of whether it is by
> microcode, by flavors classes, or by YetAnotherObjectSystem.

I don't see why flavor classes are any different from standard classes
in this regard.  Our implementation provides for writing CLOS methods
that specialize on flavors and use SLOT-VALUE to access their instance
variables.  True, flavors does have another way of writing methods that
can be used instead, but that wouldn't necessarily be true of all
implementation-defined metaclasses.

If you want to expose the slots as an implementation extension, fine, I
think that should be permitted.  If you want to hide them, I think that
can still be done with a standard class.  (Remember, we're talking about
an implementation here, not portable CLOS code.)  For example:

(defclass hidden-class (standard-class) 
   ((visible-class :accessor visible-class)))

(defmethod validate-superclass ((class hidden-class) (super standard-class)) t)

(defclass internal-pathname (standard-object) ( ... )
  (:metaclass hidden-class))

; [implementation magic equivalent to:]
(defclass pathname (internal-pathname) () (:metaclass built-in-class))

(setf (visible-class (find-class 'internal-pathname))
      (find-class 'pathname))

(defmethod initialize-instance :after ((instance hidden-class) &rest ignore)
  ; [implementation magic equivalent to:]
  (setf (class-of instance)
	(visible-class (class-of instance))))

Then the class PATHNAME appears opaque to users, but the system can use
methods on INTERNAL-PATHNAME.  SLOT-VALUE would work in those methods
because they expect an INTERNAL-PATHNAME, which is a STANDARD-CLASS.
There would be an inconsistency in that a non-optimized call to
SLOT-VALUE would not work, but the system programmers who would be
affected by that should be able to understand that and work around it.
I don't think that this technique is much different from what would be
needed to create a built-in "front class" for an internal flavor class.