Behaviors vs Modules

Nathanael Schärli n.schaerli at gmx.net
Sun Feb 24 21:21:35 UTC 2002


Anthony,

> The prefix does not designate which mixin to use it only designates
> which protocol.  Many mixins can implement the same protocol.  So in
> your example above, LockingPolicy and PessimisticLockingPolicy would
> both implement the same lockingPolicy protocol, so the BankAccount can
> change its mixin without changing its callers.  A protocol is just a set
> of selectors, while a mixin is a set of methods.

Okay, this makes sense. I must have been confused by the default behaviors
that are asscoiated with the selectors of a protocol, but after reading your
initial post again, I understand what you mean. Now I totally agree with
you: Making selectors unique by prefixing a protocol name does not cause
problems with either polymorphism or encapsulation because the protocol is
just a set of selectors (an abstract definition of an interface) and does
not specify a particular implementation. I think that's a great idea!

Being aware of the difference between protocols and mixins, your initial
post does not really unveil so much about the mixins. Since I have been
thinking about them a lot recently, I'm really curious what kind of a mixin
concept you have in mind. So, is it right that:

(Please correct my assumptions)

1) A mixin is an arbitrary set of methods (without state?). This means that
a mixin can implement methods of  many different protocols, but in practice,
a mixin will typically be a particular implementation of one (or more)
protocols.

2) A class can use zero, one or more mixins. This means that a class
specifies what mixins it uses in a similar way as it specifies its
superclass.

3) If a class uses more than one mixin, all the mixins have the same
priority (i.e. the order how the mixin are specified does not matter). Thus,
if two of these mixins specify a method for the same selector, the
programmer has to explicitly specify which one to use. (Usually that is not
going to happen because a class typically uses orthogonal mixins (mixins
implementing different protocols)).

4) When a message x is sent to an object of the class A, the appropriate
method is looked up as follows:

a) If the class A implements x, then this method is invoked.
b) Otherwise, if one (and exactly one) mixin implements x, this method is
invoked.
c) Otherwise, if more than one mixin implements x, the message send is
ambiguous.
d) Otherwise, if neither the class nor a mixin implement x, the defauult
behavior of x is used.

5) A mixin may use several other mixins in the same way as a class may use
mixins (i.e. a mixin can be composed from other mixins)

6) Mixins can not inherit from other mixins (or can they?)

(Please correct and extend)


> You have a point but I think we can figure out which protocols are
> applicable to a class just by seeing which selectors it overrides and
> finding which mixins use those selectors.  If we can do this quick
> enough in a tool, I think its better not to have to explicitly mixin
> behaviors into classes.  When we are programming a message send we are
> targeting a protocol and don't care about the class of the receiver.  It
> would be nice to not have to worry about the possible classes of the
> receiver to make sure they have the mixin.  It will just be automatic if
> the class implements the required methods (usually just the accessors).
> Also, I don't think we have to worry about adding shouldNotImplements.
> subclassResponsibility is already the default behavior which is
> equivalent to shouldNotImplement, and if the default behavior does
> execute real code it won't hurt because eventually it will try to call
> an accessor that is not implemented (subclassResponsibility).

Also here, the situation gets into a different light since I realized that
the concept of protocols (with default behaviors) is essentialy different
from mixins. (In fact, most of the arguments in my previous post are not
really applicable anymore ;-)
If the default behavior of a protocol is only very basic (and is set to
'subclassResponsibility' in all the non-trivial (or ambiguous) cases), I
don't really see a problem either. Every object undertands every selector,
but if the default behavior of such a selector is non-tribial (or ambiguous)
it has to be explicitely defined by the class itself or by a mixin that is
explicitely added to the class, right?


Well, as I said in my last email, I'm very excited about the perspective of
creating a new Squeak kernel, and I'm looking forward to discussing more
things with you.

Cheers,
Nathanael







More information about the Squeak-dev mailing list