🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.clos
Article #416

accessing clos objects

#416
From: Jon L White
Date: Tue, 12 Feb 1991 22:48
129 lines
6602 bytes
I would think that whether you "record" the instances in a global
list or in a shared slot is independent of whether you use the
:metaclass/MAKE-INSTANCE approach, or the more plain
mixin-class/INITIALIZE-INSTANCE approach.   For example, the
the :metaclass approach could provide the "class" slot simply by
having a "maximal"class in that particular metaclass (just as
STANDARD-OBJECT is the "maximal" class in STANDARD-CLASS) and this
class has the direct "class" slot; but the vanilla mixin-class
approach would just have the inherited mixin provide the class slot.

On the other hand, with many implementations, there may be a
performance penalty to pay if you use the approach that overrides
the MAKE-INSTANCE method on STANDARD-CLASS.  In your example, you
have a method on INSTANCE-RECORDING-CLASS that "overrides" the
one on STANDARD-CLASS. [Note: recent metaboject proposals define
"extends" and "overrides" in more technical terms, and in that
terminology, "extends" is the corect word; but without requiring
every reader of this list to read these documents, I think "overrides"
is more intuitively clear.  As the distinction between "extends" and
"overrides" becomes generally known, I believe it will be a better
set of terms; but for right now . . . ]

I will now provide examples of doing it both ways; partly to show
how simple the "vanilla" approach is, and partly to show how to
create metaclasses with "maximal" elements (at least in Lucid's 4.0
release).  The first approach is pure, standard CLOS; the second, of
course, touches on the not-yet-standard metaobject protocols, and
parts will no doubt change as time goes by.


Here is an an example of the more vanilla approach, putting the
enumeration listing in *two* places:

> (defclass enumeration-mixin ()
    ((instances :initform nil :allocation :class :accessor class-instances)))
#<Standard-Class ENUMERATION-MIXIN>
> (setq *enumerations-map* nil)
NIL
> (defmethod initialize-instance :after ((x enumeration-mixin) &rest w)
    (declare (ignore w))
    (let* ((direct-class (class-of x))
           (entry (or (assq direct-class *enumerations-map*)
                      (car (push (cons direct-class nil)
                                 *enumerations-map*)))))
      (push x (cdr entry))				;in global place
      (push x (class-instances x))			;in shared slot
      ))
#<Init-Method INITIALIZE-INSTANCE :AFTER (ENUMERATION-MIXIN)>
> (defclass enumerated-class-1 (enumeration-mixin	;could have many more
							; superclasses here.
                                )
     ((z-axis :initform nil :accessor z :documentation "What the Z?")))
#<Standard-Class ENUMERATED-CLASS-1>
> (make-instance 'enumerated-class-1)
#<Enumerated-Class-1 #X937083>
> (setq x (make-instance 'enumerated-class-1))
#<Enumerated-Class-1 #X93A19B>
> *enumerations-map*
((#<Standard-Class ENUMERATED-CLASS-1> #<Enumerated-Class-1 #X93A19B> #<Enumerated-Class-1 #X937083>))
> (class-instances x)
(#<Enumerated-Class-1 #X93A19B> #<Enumerated-Class-1 #X937083>)
>



Now, here's an example of the metaclass approach.  Note the use of
CLOS-SYSTEM:VALIDATE-SUPERCLASS instead of PCL's
CHECK-SUPERCLASS-COMPATIBILITY.  Likely the VALIDATE-SUPERCLASS
terminology will become a standard.  However, I'm not sure whether or
not a technique for the creation of a "maximal" element of a metaclass
is part of the emerging proposals.  In the code below, this his how
you would do it in the patched Lucid 4.0 release; in particular, note
the circular dependencies between this "maximal" element and the
metaclass, and how the use of CHANGE-CLASS fixes up the problem.  In
the current Symbolics release, it might be that a maximal element is
supported by some additional metaobject generic function; but in Lucid's
release, it is determined by the default value form for the class slot
CLOS::DIRECT-SUPERCLASSES [note well,  this is an instance slot in class
objects, and not a shared slot; it is accessed by the function from the
"de-facto" standards proposal CLOS:CLASS-DIRECT-SUPERCLASSES.]

In the code below, all use of CLOS::... symbols is Lucid-speicifc; and
all uses of CLOS-SYSTEM:... symbols is Lucid specific *except* for the
one CLOS-SYSTEM:VALIDATE-SUPERCLASS -- I believe this one will be in
the standards proposals, although at the time of Lucid's release, it was
still being debated.  All uses of CLOS:... symbols are from the set of
three or four dozen functions that Symbolics and Lucid (and possibly
others?) subscribed to last year as a "de-facto metaobject standard",
meaning that any future standard would surely include these functions
(which were almost entirely "introspective")


;;; First, start this guy out as a plain old 'standard-class' class.
> (defclass enumerated-object ()
    ((instances :initform nil :allocation :class :accessor class-instances)))
#<Standard-Class ENUMERATED-OBJECT>
> (defclass enumerated-class (standard-class)
    ((clos::direct-superclasses
      :initform (list (find-class 'enumerated-object))  ;overrides value in
							; STANDARD-CLASS
	 )))
#<Standard-Class ENUMERATED-CLASS>
> (defmethod clos-system:validate-superclass ((class enumerated-class)
                                              (super standard-class))
    t)
#<Standard-Method VALIDATE-SUPERCLASS (ENUMERATED-CLASS STANDARD-CLASS)>
> (change-class (find-class 'enumerated-object) (find-class 'enumerated-class))
#<Enumerated-Class ENUMERATED-OBJECT>
> (defclass frob ()
    ((z :initform nil :documentation "Zome Zlot"))
    (:metaclass enumerated-class))
#<Enumerated-Class FROB>
> (clos:class-direct-superclasses (find-class 'frob))
(#<Enumerated-Class ENUMERATED-OBJECT>)
> (defmethod initialize-instance :after ((x enumerated-object) &rest w)
    (declare (ignore w))
    (push x (class-instances x)))
#<Init-Method INITIALIZE-INSTANCE :AFTER (ENUMERATED-OBJECT)>
> (setq x (make-instance 'frob))
#<Frob #X95698B>
> (setq y (make-instance 'frob))
#<Frob #X959EAB>
> (class-instances x)
(#<Frob #X959EAB> #<Frob #X95698B>)
>



-- JonL --
Technical Details
Message-ID: <9102122248.AA22313@kolyma>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!bcm!dimacs.rutgers.edu!seismo!uunet!tut.cis.ohio-state.edu!LUCID.COM!jonl
References: <9102121807.AA16036@cheops.cis.ohio-state.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!bcm!dimacs.rutgers.edu!seismo!uunet!tut.cis.ohio-state.edu!LUCID.COM!jonl
From: jonl@LUCID.COM (Jon L White)
Newsgroups: comp.lang.clos
Subject: accessing clos objects
Message-ID: <9102122248.AA22313@kolyma>
Date: 12 Feb 91 22:48:41 GMT
References: <9102121807.AA16036@cheops.cis.ohio-state.edu>
Sender: welch@tut.cis.ohio-state.edu
Distribution: inet
Organization: CommonLoops
Lines: 129