Saturday, September 10, 2005

SortedCollection, Block, and Polymorphism

I was having a discussion with a friend of mine tonight and they were having problems with serializing an object. After a few questions, I learned that they had a SortedCollection with a custom block. He was using Dolphin and I mentioned that there were other avenues to take. One such avenue is that he could use another object in place of the block as long at it understood #value:value: and returned a boolean. This is a common oversight because it's hard breaking "type thinking" and to step into "protocol thinking". The type of an object doesn't matter, it's the protocol it understands. Rubyists call this "duck typing". Call it what you want, it's powerful. As a side note, this is why interfaces make programming in Java nicer. So, I showed a quick example, say we take the following code:
| collection |
collection := Array
with: 'second' -> 'turbine'
with: 'third' -> 'earth'
with: 'fourth' -> 'good apollo'.
collection asSortedCollection: [:a :b | a key <= b key]

And it returns:

a SortedCollection(
'fourth' -> 'good apollo'
'second' -> 'turbine'
'third' -> 'earth')

In Dolphin, I can use Message instead of block since it understands the same protcol:
collection asSortedCollection: (Message selector: #key)

Or even write a method to do the comparison:
compare: anObjectA to: anObjectB
anObjectA key <= anObjectB key

collection asSortedCollection: (MessageSend receiver: someObject selector: #compare:to:)

Or we could implement #value:value: on an object and pass that in as the block into SortedCollection. Just remember, to use the polymorphism, luke. We can use these tricks anywhere we use a block (Depending on the number of arguments needed, you might been #value:, #value:value:value:, or #valueWithArguments:). And all of the above sample solutions are serializable...=)

It's great to work in a language that allows you the freedom to be creative and extend it in ways the creators never thought of (or perhaps they did). Let the Smalltalk FLOW!

6 comments:

T.A. Jones said...

Blaine,

Cool article. I feel like parts of my mind have atrophied after using Java for so long, these articles are helping to stop thinking in Java.

Btw, in VisualWorks I serialize out my blog to a file and am able to read it back in just fine even though it contains a SortedCollection with a block.

Can't wait for dolphin 6, it reminds a lot of VSE... VSE was my first love (as far as programming environments go) and when it died I felt almost like a friend had died. VSE + windowbuilder was awesome (never really cared for parts, though).

Regards,
Tim

T.A. Jones said...

I don't want to rag on Java *too* much... I think Interfaces are a cool idea and a real step forward. Checked exceptions, however.....

Peter William Lount said...

The SortCriteria is implemented in the above manner using the value:value: protocol of SortedCollection. Give it a try. Oh, a couple of other messages had to be implemented in some Smalltalk's so the protocol is more than just the value:value: message.

It would be awesome if someone would port it into Dolphin and send me a file with the Dolphin version so I can add it to the web site. Thanks.

Blaine said...

Vincent,
You're right. Dolphin handles serializing blocks as well. I don't know why I thought this. It must be another one of those old hold backs that I have. Still it was a fun article to write!

T.A. Jones said...

Peter,

I read about your SortCriteria object, it looks really nice.

Regards,
Tim

Peter William Lount said...

Tim,

Thanks for the appreciation. The SortCriteria, or SortCritter as it's affectionetly known in Squeak, is really cool. What I like about it is the simplicity of extending the Smalltalk SortedCollection capability. It's awesome that this was possible without modifying any of the existing Smalltalk classes, and yet it's such a fundamental addition to those capabilities. It's also tiny with much of the code being the test class.

When hooked up to a GUI that allows for realtime adjustments of the SortCriteriaColumns via clicks of the GUI table columns it's very powerful indeed!

The other aspect that blows my mind about it is that it's so damed simple to use as a programmer! Funny enough it was inspired by the ease of sorting in Microsoft Excell! Notably the SortCritter is even easier to use - from a programming point of view - since it can be memorized with SortCritter instances configured for various purposes. If the GUI is constructed right the user can easily switch between them and be in FULL control over this aspect of how the information is presented to them in the GUI.

The SortCritter was inspired when I had to write yet another block to sort multiple columns. Sigh... the idea of using value:value: polymorphicly came to mind and within a few hours I had a fully working and tested SortCritter, essentially what you see now!

It seems that it's rare to have such funcationality and power in such a condensed space and yet still be readable and potently reusable.

While recently working on two very large Smalltalk applications in production - desktop and web - it became clear that most of the classes were, I don't know the best way to describe it, maybe defused is close. The classes capabilities were defused all over the place, not focused in one place, and with so many of them having that characteristic it made the system that much harder to grasp.

Clear design is essential to not only comprehension but effectiveness of the design of object components as implemented in their classes. In the case of the SortCritter two classes conspire in such a way as to pretend to be what they are not - a block of code. The two classes divide up their responsibilities with a SortCriteria instance taking on the role of the "sort block" and the SortCriteriaColumn instances knowing about their vertical slice of the sorting problem. It's also interesting that the "sorting algorithm extension" for sorting multiple columns indpendently from each other is such a one off algorithm. That is, it's an algorithm that highly ameniable to encoding once and for all! Once encoded and tested it has powerful benefits such as reliablity in that humans can then trust their sorting requirements. In effect it becomes a new reliable and reuable control structure for Smalltalk.

If you can - when you find yourself spewing out an algorithm over and over and over again manually as you write code - seize the day and evolve that manual spew into a truely generic and reusable component! Then share it the new wealth!

I'm glad that you like it. How about porting it to your favorite Smalltalk and sending me the ported file out for posting for others?

All the best,

Peter William Lount
peter@smalltalk.org

Amazon