[Q] mixin pattern - how to use an alternate Behavior for Cl ass

Withers, Robert rwithers at quallaby.com
Mon Jan 28 16:40:36 UTC 2002


Hi Nathanael,

That was a very cogent description of the Metaclass-Class structure for
Classes in Squeak.  It _is_ a parallel inheritance hierarchy on both the
class side and the metaclass side.  This is very hard to discuss, because
there are so many design vs implementation details that use the term class.

When you reached my example, however, I believe there is some
misunderstanding.  I will try to explain.  All classes each have a
metaclass, which is the class' class.  The _implementation_ of the class
structure, is that classes are instances of the class, Class.  The
_implementation_ of the metaclass structure, is that metaclasses are
instances of the class, Metaclass.  I am trying to use a different Behavior
class (not Class) to represent classes.  This drives me to consider the
implementation for creating new classes.  

Before diving into all of that, let me mention that what you are trying to
accomplish sounds very interesting.  It is like the previous Protocol work,
but you are carrying the implementation around as well.  

I am also against multiple inheritence.  What I am doing is creating an
orthogonal vector of method activation.  I have redirected the lookup into
the image, within a RedirectionContext.  The mixin classes have their
methods compiled within the scope of the context and get activated by this
orthogonal message redirection.   I am basically hand building the point at
which context, lookup and activate occur, so I want to use an orthogonal
Behavior to represent methods to be executed when redirection occurs.
Normal message sending to the context use the RedirectionContext class
methodDict for behavior.

you said:
> In case (1a) you break this parallel inheritance hierarchy because
> 'MixinClass' is a subclass of 
> 'ClassDescription' but 'MixinClass class' is no subclass of
> 'ClassDescription class' (in fact, 

this is not true, 'MixinClass class' is a subclass of 'ClassDescription
class'.

> 'MixinClass class' == 'MixinClass'). In your concerte 
> example, this means
> that 'MixinClass' inherits 
> from:
> 
> ClassDescription
> Behavior
> Object
> ProtoObject
> 
> but 'MixinClass class' (== 'MixinClass') does not inherit from
> 'ClassDescription class', 'Behavior 
> class', etc.

again this is not true.

Here is my option (1b)
> > 1a) meta _ Metaclass new.
> > meta
> > superclass: MixinClass
> > methodDictionary: MethodDictionary new
> > format: MixinClass format.
> > newClass _ meta new. 

I am in the midst of defining a new class, (not defining MixinClass), that I
want to represent as an instance of MixinClass, and not as an instance of
Class.  The porblem lies with the mechanism for creating an instance of
Class for this class.  It is occurring right here, with meta new.  The
implementation of this method, looks to the class you are instatiating to
get the instSpec and format of the instance.  This relies on the superclass
chain, of the class.  In this case the instance we are creating is a class,
therefor we need to know the instSpec of the metaclass.  This instSpec
depends on the inheritence structure and thus, we inherit the Class
instSpec, when we reach the ProtoObject class superclass (I will describe
below).  I want to substitute the class MixinClass instead of Class.  I
tried to do this by forcing the superclass of my metaclass to be MixinClass.
This works for the instSpec of the class, but, as you point out, it breaks
the parallel inheritence of the metaclass.


The inheritance hierarchy, of these two layers, must be parallel, as you
point out.  I am not sure if parallel is the right term, but idempotent
perhaps?  For instance:

class level inheritence
  Object superclass == Object class superclass soleInstance
  Morph superclass == Morph class superclass soleInstance
likewise, in metaclass level inheritence,
  Object superclass class == Object class superclass
  Morph superclass class == Morph class superclass

we can verify that these definition objects are instances of the correct
class with:
  Morph class isKindOf: Metaclass
  Morph isKindOf: Class
  Object class isKindOf: Metaclass
  Object isKindOf: Class
and even:
  ProtoObject class isKindOf: Metaclass
  ProtoObject isKindOf: Class

when we look at the inheritence structure of ProtoObject, this parallel
hierarchy, as well as the implementation classes, breaks down.
  ProtoObject superclass ~~ ProtoObject class superclass soleInstance
because the superclass of ProtoObject is nil, while the superclass of
ProtoObject class is Class, and doesn't understand soleInstance.
  ProtoObject superclass class ~~ ProtoObject class superclass
because the class of the superclass of ProtoObject is UndefinedObjecct,
while the superclass of ProtoObject class is Class.
Furthermore,
  (ProtoObject superclass class isKindOf: Metaclass) not
  (ProtoObject superclass isKindOf: Class) not

Typically the class side inheritance are instances of Class and the
metaclass side inheritence are instances of Metaclass.  This is changed at
ProtoObject class.  It's superclass is the class, Class. (we are in the
metaclass inheritance layer).

Ok, I'll stop here until I can determine a good way to graph this using
ascii.  Here's a try:  (paranthesis is the class of the metaobject)

class inheritence
 nil (UndefinedObject)
   -> ProtoObject (Class)
     -> Object (Class)
       -> Morph  (Class)

metaclass inheritence
 Class (Class) 
   -> ProtoObject class (Metaclass) 
     -> Object class (Metaclass) 
       -> Morph class (Metaclass) 

I want the following
class inheritence
 nil (UndefinedObject)
   -> ProtoObject (Class)
     -> Object (Class)
       -> MyMixin  (MixinClass)

metaclass inheritence
 Class (Class) 
   -> ProtoObject class (Metaclass) 
     -> Object class (Metaclass) 
       -> MyMixin class (Metaclass) 

but I think I have to have:
class inheritence
 nil (UndefinedObject)
   -> MixinProtoObject (MixinClass)
     -> MixinObject (MixinClass)
       -> MyMixin  (MixinClass)

metaclass inheritence
 MixinClass (Class) 
   -> MixinProtoObject class (Metaclass) 
     -> MixinObject class (Metaclass) 
       -> MyMixin class (Metaclass) 


I hope this helps the discussion!!!!!!!  ;-)

cheers,
Rob


> -----Original Message-----
> From: Nathanael Schärli [mailto:n.schaerli at gmx.net]
> Sent: Monday, January 28, 2002 9:52 AM
> To: squeak-dev at lists.squeakfoundation.org
> Subject: Re: [Q] mixin pattern - how to use an alternate Behavior for
> Class
> 
> 
> Hi Rob,
> 

<snip>

> Now, to my work on mixins. Whenever I was designing and 
> implementing an
> application in 
> Squeak (or Smalltalks), I have felt very limited by the fact 
> that there is
> only single inheritance. As 
> soon as there are classes with responsibilities that fulfill 
> more than just
> one single aspect, this 
> urges the programmer to duplicate code. On the other hand, I 
> have never been
> happy with the 
> rather complex multiple inheritance algorithms where the 
> programmer easily
> looses track of 
> what actually happens and which method is finally invoked 
> (such as in C++).
> Java's interfaces 
> are actually very nice (simple), but they also don't solve to code
> duplication problem. So, why not 
> using a simple concept that is similar to interfaces, but 
> actually allows
> implementations (but no 
> state)?
> 
> --> Idea of stateless mixins with the features such as:
> 
> - Mixins are first class entities (obvious in Squeak)
> - Mixins have reflective aspects such as 'provided' and 
> 'required' methods.
> - The required methods are basically the glue that is 
> necessary to use a
> mixin in another class or 
> another mixin.
> - If a class implements several mixins, they are not ordered. 
> This means
> that the programmer 
> has to resolve all the conflicts manually.
> - An extension of the browser allows to see which mixins are 
> implemented by
> a class, how the 
> glue methods are defined and how the conflicting methods are defined.
> - Mixins can be automatically derived from existing classes. 
> Thereby, access
> to instance variable 
> and the class is automatically replaced by methods that have 
> to be defined
> when the mixin is 
> used (required methods). A class and the derived mixin are 
> (per default)
> related. This means 
> that when a method of a class gets changed, the corresponding 
> mixin gets
> also adjusted.
> 
> I am just about to implement a first version of these 
> "Stateless Mixins" 
> with features as 
> mentioned above (and some more). The main goal is to be able 
> to group a
> "(partially) 
> independent set of related methods" as a first class entity 
> and to reause
> them in a very simple 
> way (therefore no state). I think that one of the keys for 
> that is a good UI
> that allows the 
> programmer to see what is actually going on.
> 
> Cheers,
> Nathanael
> 
> > Hi Stef,
> > 
> > Actually, mine is much more special case than MixinClass.  
> It is called 
> > RedirectorMixin.  I intercept method lookup, in the vm, and 
> redirect into 
> > the image so I can manipulate this lookup.  I am writing 
> the Mixin in
> > order 
> > to have class-based methods to dispatch through.  The 
> reason for creating
> > a 
> > special class was to allow this class to be manipulated in 
> the browsing
> > tools.
> > 
> > I'm quite sure there are other aspects of mixin that I am 
> not addressing
> > in 
> > my special case.  ;)    I look forward to hearing about 
> them and from 
> > Nathanael.
> > 
> > Cheers,
> > Rob
> > 
> > At 02:06 AM 1/28/2002, you wrote:
> > >Hi Rob
> > >
> > >we are working on mixin (not like yours in fact) mixin are 
> not only about
> > >compiling in a different scope ;)
> > >
> > >I think that we have kind of similar questions ;)
> > >Nathanael will certainly get ion contact with you.
> > >
> > >Stef
> > >
> > > > I am trying to create a mixin class which compiles it's 
> methods 'in'
> > the
> > > > scope of a different class.  One way to go would be to 
> have class side
> > > > #compile methods which switches the class used to 
> compile the method
> > in.  I
> > > > would need a classVariable to hold this contextClass 
> and off we go.
> > > >
> > > > An alternative mechanism that I am exploring, is to 
> have a different
> > > > subclass of ClassDescription (or Class), which has an 
> instance method
> > > > contextClass, and the compile methods are overridden on 
> the instance
> > side
> > > > of this MixinClass.
> > > >
> > > > So I have a MixinClass, which has roughly identical 
> protocol to Class
> > and I
> > > > am now adding a set of methods to ClassBuilder to 
> create this class
> > > > (instance of MixinClass).  The problem is that I am not 
> sure what to
> > set
> > > > the superclass of the Metaclass instance too.  (1b) If 
> I leave it
> > alone, my
> > > > class is an instance of Class.  (1a) If I force it to 
> MixinClass, then
> > my
> > > > class is an instance of MixinClass and my instance 
> methods are ok, but
> > the
> > > > class-side confuses me a little - I have broken the metaclass
> > superclass
> > > > inheritence.  Do I really need to have a 
> MixinProtoObject to root
> > > > everything with MixinClass class as the first metaclass 
> superclass, or
> > can
> > > > I stitch myself into a different point in the hierarchy 
> and still have
> > my
> > > > class be an instance of MixinClass, rather than Class, 
> but maintain
> > the
> > > > correct metaclass inheritence?  I believe it all relies on the
> > > > implementation of 'meta new', especially with
> > Interpreter>>formatOfClass:
> > > > aClass, where aClass is a metaclass instance.
> > > >
> > > > Cheers,
> > > > Rob
> > > >
> > > >
> > > >
> > > > 1a) meta _ Metaclass new.
> > > > meta
> > > > superclass: MixinClass
> > > > methodDictionary: MethodDictionary new
> > > > format: MixinClass format.
> > > > newClass _ meta new.
> > > >
> > > >
> > > > 1b) meta _ Metaclass new.
> > > > meta
> > > > superclass: newSuper class
> > > > methodDictionary: MethodDictionary new
> > > > format: MixinClass format.
> > > > newClass _ meta new.
> > > >
> > > >
> > > >
> > > > 2) newClass
> > > > superclass: newSuper
> > > > methodDictionary: MethodDictionary new
> > > > format: newFormat;
> > > > contextClass: aContextClass;
> > > > setInstVarNames: instVars;
> > > > organization: nil.
> > > > ^newClass
> > > >
> > > >
> > 
> > 
> 
> -- 
> /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
>   Nathanael Schärli
>   Rüttenenstrasse 41
>   CH-4515 Oberdorf, Switzerland
>     Phone: +41 32 622 89 03
>     Fax:   +41 32 621 78 50
>     Email: n.schaerli at gmx.net
> /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
>  
> 
> 



More information about the Squeak-dev mailing list