Initial core port of "Squeak Traits"

Brian Rice water at tunes.org
Wed Nov 16 18:23:38 PST 2005


Here's something I've been thinking about for months but only coded  
up this week. Squeak Traits is research that started on Squeak but  
the idea has spread to a few other languages - I'm sure that many of  
you on this list are likely to have run into it already, and maybe  
some have tried it.

The original research homepage is here:
http://www.iam.unibe.ch/~scg/Research/Traits/

The source code for the port is in src/lib/trait.slate and is just a  
few pages including comments:
http://slate.tunes.org/repos/main/src/lib/trait.slate

Note: The Slate code is not a direct port of the Squeak code - I  
found that to be less clear than it ought to be, so I basically wrote  
it according to the specification given in the research papers.

The base prototype is "Trait" to distinguish it from the objects we  
access as "traits" and to emphasize that it is a component.  
Essentially these things wrap "services" as an analogue of the  
"method dictionary" idea found in single-dispatch languages; the  
services are a dictionary from Signatures (selector plus roles) to  
methods. The basic idea is that you sum (+) these components if you  
want a disjoint union, or exclude certain methods using #-. You can  
layer them linearly with "a ** b" so that b overrides a's services,  
although "b over: a" might be easier to read; the overlay is good for  
resolving the conflicts possible with +. There is also a crude way to  
alias the methods of one component so they are not shadowed, using "a  
aliasing: map" where the map goes from new signatures to old ones.

Anyway, the idea is that you can take a ton of small components and  
assemble them independently, then run built-in checks for conflicts,  
and this all acts as a declarative description which you can finally  
compile into a single traits object or traits+prototype. The recent  
method-send query extensions (allSelectorsSent*) were included so  
that these checks would run better.

Why does Slate need this, you ask? Well, Smalltalk-80 needed this  
more acutely because it buys its users a safe multiple inheritance  
system where they only had single inheritance. We do have a mostly- 
safe multiple inheritance system with our traitsWindow that linearly  
orders super-types and we can change that order per type no matter  
how it's inherited, but this is hard to manage and the delegations  
are still traversed dynamically. Basically it doesn't scale up to the  
ideal where every independent protocol you might want to re-use is a  
separate cluster of methods. So this buys us some ability to deal  
with bigger inheritance compositions safely. The existing system  
won't go away, but we won't have to use it for protocol composition  
nearly as much, especially where these protocols are truly static.

Finally, this ported code doesn't tie in to anything else yet, except  
that you can installServicesOn: to get the methods that are on the  
traits onto some other object(s). I'll spend the next day or two  
figuring out a manageable way to do that and also write up some  
examples to illustrate. I think that I'll try a refactoring of the  
collect:, select:, etc. protocol so that the fact that they are  
shared between Collection and ReadStream is more obvious and maybe  
eliminate some code that way.

--
-Brian
http://tunes.org/~water/brice.vcf




More information about the Slate mailing list