[VI4] Multiple Behaviors/Roles proposal

Andreas Raab Andreas.Raab at gmx.de
Fri Jun 14 18:40:22 UTC 2002


> What do you guys think?

I think it would be a Really Good Idea (tm) to finish the pending stuff
first. If everything we can think of gets into VI4 then we're never
going to get any result out of it.

Cheers,
  - Andreas

> -----Original Message-----
> From: squeak-dev-admin at lists.squeakfoundation.org 
> [mailto:squeak-dev-admin at lists.squeakfoundation.org] On 
> Behalf Of Anthony Hannan
> Sent: Friday, June 14, 2002 6:31 PM
> To: squeak-dev at lists.squeakfoundation.org
> Subject: [VI4] Multiple Behaviors/Roles proposal
> 
> 
> Hello Squeakers,
> 	I've been playing around with this idea for a long 
> time, and I think I
> finally came up with a decent design for allowing multiple
> behaviors/roles per object.  I would like to add this to VI4, what do
> you think?
> 
> Structure:
> 	A protocol is an array of selectors.  A behavior is an 
> implementation
> of a protocol with its own instance variables.  A behavior can inherit
> >from another behavior of the same protocol.  A class is a set of
> behaviors keyed by protocol.  All behavior instance variables 
> are stored
> in sequence in the class's instances, the class knows the offset where
> each behavior's vars start.
> 	A behavior also acts as a pool dictionary where global 
> vars are looked
> up.  A pool dictionary is a environment dictionary that holds named
> objects and inherits from zero or more other pool dictionaries.  The
> super behavior of a behavior is automatically considered an inherited
> pool dictionary of the behavior.  The compiler looks up sent selectors
> in all protocols found in the behavior's extended pool.  If more than
> one protocol contains the same selector name the user chooses 
> which one
> he intends.
> 
> Method Lookup:
> 	The selector's protocol is stored in the literals while 
> the selector's
> index within the protocol is encoded in the send bytecode.  
> The protocol
> is looked up in the hash table of the class to find the corresponding
> behavior.  Then the selector index is used to directly access the
> correct method from the behavior.  Every behavior holds the entire set
> of methods for its protocol.  So a subclass behavior 
> (sub-behavior) will
> shallow copy the method array of its super than override any 
> methods it
> wants.  (The browser tools will be made to update these 
> copies correctly
> when modifying methods).
> 	This lookup mechanism obviates the need for a method 
> cache, at the
> expense of repeating the method array.  I think this is 
> tolerable if our
> protocols are not too big, or if we do not have too many different
> behaviors for a protocol.  Remember many classes can reuse the exact
> same behavior if their behavior for that protocol is the same.  Most
> subclasses today only override methods that are intended to 
> be overriden
> in the super.  To reduce unnecessarily copying method arrays we could
> keep these intended subclass responsibility selectors in a separate
> protocol.  This way when overriding them we don't have to copy the
> method array for all the other selectors as well.  If we create
> protocols along existing method category lines I think we 
> could achieve
> this type of partitioning.
> 	However, if we want to have large protocols along 
> existing class lines,
> then I think we would be better off not copying method arrays for
> sub-behaviors but rather use method dictionaries and explicit super
> behavior chains like we do today and re-introduce the method cache. 
> What do you guys think, small or large protocols (copied method arrays
> or chained method dictionaries with method cache)?
> 	To continue with method lookup: If the selector's 
> protocol is not found
> in the class then the protocol's default behavior is 
> executed.  This way
> every class does not have to hold every default behavior it wants to
> respond to, particularly Object and its many protocols.  Most 
> low-level
> default methods will execute 'self subclassResponsibility', so
> unimplemented methods will still be found (maybe just a few calls
> later).  But having default behavior makes inheritance 
> simpler, you only
> have to implement low-level methods to get full functionality without
> explicitly specifying which functionality you want to allow.  For
> example, all you have to do is implement a method for 
> Collection.do: and
> any other default methods that use Collection.do: will work, 
> without you
> knowing which behaviors they are and explicitly inheriting from them.
> 	Super sends can only be sent to messages in the same 
> protocol.  They
> are implemented by storing the super method at the end of the method
> array and using a normal self message to it.  Additional supers within
> supers must also be appended.
> 
> Method Lookup Optimizations:
> 	The behavior of the current method is stored in the 
> frame, so messages
> of the same protocol sent to self can be immediately looked up in this
> behavior without the need to go through the class hash table.
> 	The offset for instance vars of the current behavior 
> are also stored in
> the frame so the behavior's inst vars can be found immediately.  The
> offset for each behavior in a class is stored next to the behavior in
> the hash table.
> 	To speed up common protocol lookup, each class has a 
> primary protocol. 
> The selector's protocol is first tested against this primary protocol
> and if they match then its behavior is immediately returned 
> and its inst
> var offset is set to 1.  If its not then the normal hash 
> lookup is used.
> 
> What do you guys think?
> 
> Cheers,
> Anthony
> 




More information about the Squeak-dev mailing list