How about... something completely different? (Re: [squeak-dev] Re: On traits composition)

Igor Stasenko siguctua at gmail.com
Thu Dec 10 00:44:45 UTC 2009


2009/12/9 Göran Krampe <goran at krampe.se>:
> Hi!
>
> Igor Stasenko wrote:
>>
>> 2009/12/9 Göran Krampe <goran at krampe.se>:
>>>
>>> Given Andreas' statement above - wouldn't it be *much* cooler to evolve
>>> Smalltalk along the axis of composition instead of the axis of
>>> inheritance?
>>>
>>> I have always thought that having better mechanisms for delegation would
>>> be
>>> awesome, and would in most ways be much more powerful than inheritance
>>> (in
>>> whichever form).
>>>
>>> For example, what if one could declare that for class Foo (having ivars
>>> x,
>>> y, z) any message that would result in a DNU would instead be "delegated"
>>> to
>>> ivar x (and then y if no lookup is found in x either).
>>>
>>> This would be equivalent to tons of messages in Foo like:
>>>
>>> Foo>>name
>>>       ^(x respondsTo: #name) ifTrue: [x name] ifFalse: [y name]
>>>
>>> (well, kinda, you get the picture - but also, taking care of x/y
>>> returning
>>> "self" in which case we probably should return the "Foo self" instead
>>> etc)
>>
>>
>> Hmm, how is it different to inheritance?
>> I mean, you can achieve similar effect by making
>> an instance of Foo class superclass to be x, and x superclass to be y.
>
> There are several differences I think. And do note I only made a "loose"
> sketch of the idea, not going into details like for example, "should Foo
> really delegate *everything* it doesn't respond to or just a specified
> protocol etc?".
>
> A few differences off the top of my head:
>
> - Since we delegate to ivars it is fully dynamic. We can change x and y
> dynamically. Sure, you can claim that we can change the class hierarchy
> dynamically too - but hey.
>
> - We have the distinction of "selves". Ted mentions "self" (the part) and
> "whole" (the composition).
>
> - We have encapsulation. Composition is black box reuse, inheritance is
> glass box :). In other words, x can not touch ivars of Foo and so on.
>
> And probably more.
>
If you seen my other post about prototypes, i think its easily doable with them.

Consider a following sample code:

proto := PrototypeFactory new.
proto inheritTrait: TPoint.
proto prototype initialize.
proto inheritTrait: TColor
proto prototype initialize.

now you can send getters or setters like #x , #y , #red, #green, #blue etc.
In such composition you will get

TPoint (x,y)
TColor(red,green,blue)
proto

so, a proto, as a top-level receiver doesn't having any of slots (and
hence does not carrying any state), but its prototypes do.
But it still can transparently access them without much overhead.

Then, at any moment you could allocate own private slot
proto slotAt: #x put: 10

and now it will look like:

TPoint (x,y)
TColor(red,green,blue)
proto(x)

and #x accessor will shadow the TPoint's accessor, providing an access
to prototype-local slot.
So, it shows us that you can choose freely, who is going to be the
state holder.
A same initialization, but made little different:

proto := PrototypeFactory new.
proto inheritTrait: TPoint.
proto initialize.
proto inheritTrait: TColor
proto initialize.

will give you:

TPoint
TColor
proto(x,y, red,green,blue)

granted, that correspoding #initialize methods of above traits
allocating the slots.

I am sure, i'm not Discovering an America here for any who dealt with
prototype-based stuff before :)

Is this a kind(s) of delegation you having in mind?

> regards, Göran
>
>
>



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list