Polymorphism without protocol dilution

Travis Griggs tgriggs at keyww.com
Wed Aug 26 06:32:59 UTC 1998


Maurice Rabb wrote:

> At 9:49 PM 8/25/98, Travis Griggs wrote:
> >Maurice Rabb wrote:
> >
> >> <snip>
> >> For this to work would require that I add Object>>#value which I remember
> >> is a no-no, because it dilutes the BlockContext protocol as Object>>#do:
> >> diluted the Collection protocol.  We replaced Object>>#do: with #in:, so
> >> with what do we replace Object>>#value?
> >> <snip>
> >
> >Just out of curiousity and because it's late and I'm in a devil's advocate
> >mood... What's wrong with diluting  protocols? I have vaguely seen threads
> >about this, but I've never really seen (or paid attention long enough), a good
> >reason not to dilute protocols. It's just kind of one of those unexplained
> >commandments (too me). I have personally thought many times that it would be
> >cool to totally blur the lines between collections and single objects in
> >Smalltalk for quite some time. Isn't that one of the things Lisp kind of does?
> >Why does enumeration have to be bound to a storage strategy?
>
> Travis--
>
> Well lets review what the wise ones have said:
>
> At 7:46 AM 5/29/98, Ralph E. Johnson wrote  RE: Pluggability
> >I looked at Actions, and liked what I saw.  I've seen and done things
> >like that before.  My main complaint is that the method should be
> >#value and #value:, not #evaluate and #evaluate:  A block is a
> >built-in Action, and it already defines a protocol, so we should
> >use it.
> >
> >One of the interesting things is that Actions define both #value
> >and #evaluate.  So, you can use an Action instead of a block, but
> >you can't use a block instead of an Action.  Why?  A block is just
> >a built-in Action.  Now, the fileIn defines #evaluate and #evaluate:
> >for blocks, but that does not passify me!  We should not proliferate
> >protocols, and #value and #value: are well defined and short.
> >They are not particular logical, but that is not so important for
> >the most common messages.  #at:put: is not particularly logical, either.
> >
> >It is a mistake to put #evaluate and #evaluate: in Object.
> >ParcPlace did this with #value and #value: for awhile, and the
> >problem is that you lose useful information because errors don't
> >get caught right away but the system keeps on running for awhile
> >before finally noticing some error.  It is so easy to convert
> >an object into an Action (just send #asAction to it) that you don't
> >need these helper methods in Object.  Further, using #asAction
> >provides helpful information to the reader that an object is
> >going to be used as an action, so it gives hints that can prevent
> >the reader from having to keep on reading.
> >
> >BlockContext should define asAction to return self, not to make
> >a new action that returns itself.  A block is just a built-in action.
> >
> >(I'm hoping that if I say it enough, people will believe me!)
> >
>
> At 4:08 PM 5/29/98, Andreas Raab continued:
> >> It is a mistake to put #evaluate and #evaluate: in Object.
> >> ParcPlace did this with #value and #value: for awhile, and the
> >> problem is that you lose useful information because errors don't
> >> get caught right away but the system keeps on running for awhile
> >> before finally noticing some error.
> >
> >I absolutely agree. One thing I don't like at the moment is that Object
> >implements #do: It's easy enough to define either asCollection or to
> >implement #do: in classes where this is really needed.
> >
> >> (I'm hoping that if I say it enough, people will believe me!)
> >
> >I do ;-)
> >
> >  Andreas
>
> Turning to the "Way Back Machine" even further back, a _very_ wise
> Smalltalker wrote  Re: Proposal: Object>>valueIn:
>
> At 2:44 PM 11/3/97, Travis Griggs wrote:
> >Ah yes, you are right. Having now thought about it, I think they should
> >both exist. They accomplish different things semantically. I still like the
> >presence of do: in Object for the purpose of "iterating" over single
> >objects as if they were indeed aggregations.
> >
> >--
>
> If you think about it you could argue that this is the same argument as
> #valueIn: (i.e. #in: as it is now) vs. #do:  The semantics of a Collection
> iterating over itself, and 0-1-Many iterating over itself _as_ a Collection
> are subtly different enough to make a separate protocol a "safe" ideal.  In
> practice, the gurus say that it tends to hide normal Collection use errors.
> Likewise, the potential of not catching error of using any old Object
> instead of an intended BlockContext.
>
> Personally Travis, I waffle back and forth toward your position.  There is
> a simple elegance in a unilateral #do: and a unilateral #value.

Scary to have your own quotes, long forgotten, dredged up out of the dust. I feel
like Bill (Gates or Clinton, take your pick). What continues to gnaw at brain is
what you sum up so well with the statement

    "In practice, the gurus say that it tends to hide normal Collection use errors"

When, I read this, the Hemmingway quote, "For every thousand hacking at the leaves
there is one hacking at the roots of a problem" comes to mind. It's like it's a
copp out. Not that I necessarily have the solution, but to just say it and leave it
at that is what bugs me. One of my FAVORITE things about Smalltalk is it's
readibility. Computers express ideas one way, and humans another. Smalltalk is one
of the BEST practical solutions to allowing me the programmer to express ideas my
way, and not the computer's. And in the english language at least, I dilute the
hell out of protocols. And for the most part, I get my message across. What's wrong
with our language/class library that we can't do the same? Maybe it's just one of
those very difficult basically intractible problems...

For a while now, we've had a ?framework? in VisualWorks that I've thought about
porting over to Squeak and releasing, but I've always feared the flame about
diluting protocols. But tonight, I'm coming out. :) Long ago, I went to work for a
company that used Smalltalk to write engineering decision/design tools. We were
always crunching numbers, especially collections of numbers. The OrderedCollection
was the first thing all of us FORTRAN nerds fell in love with. Patterns of what we
did with these collections of numbers began to emerge. We were always adding the
elements of one collection against the elements of another, or scaling all of the
elements of a collection by some constant, etc. The first thing we did was write a
NumericCollection object. At first it was a subclass of Array, then
OrderedCollection, and then we got smart and made it a wrapper type object. But we
got sick and tired of sending #asNumericCollection to all of our collections. So
finally, we just said to hell with it, and we implemented the basic ArithmeticValue
protocols in Collection and SequenceableCollection. This was a bit scary for us.
But, the use of double dispatching made it a huge mental hard on, because it was so
easy and slick. Today, I work at another company that also does
engineering/scientific stuff with Smalltalk. This framework is still with me, and
it's still my favorite. I used to do homework with it in college all the time, and
blow my friends and teachers away. I would just whip up little expressions:

#((1 2 3 4 5) + #(6 7 8 9 10) * 4) sum

and it would blow them away. It's like having MathCad inside of a Turing complete,
interactive programming system. What's the point of this long drawn out post? To
date, I have had one occurence of one of those errors where I had to scratch my
head a little longer than I might have other wise because this is in place. And
that's about 5 years of extensive use. In the year and a half or so that we used
the wrapper approach, I had many more errors where I forgot to *cast* the
collection into a numerically savvy one. Ammusingly, that one error that I speak of
occured because I had forgotten to send asNumber to aString. Since String is a
subclass of Collection, it dutifually tried to increment all of its character
values by the argument, but got hung because the result was larger than 255. :)

Maybe the arithmetic protocol is one that dilutes better. We've found it to be
immensely powerful (and that includes two Junior Smalltalkers who tend to make more
silly mistakes), and we're not getting bogged down by errors that take longer to
occur.

--
Travis Griggs
Key Technology
tgriggs at keyww.com
Smalltalk - 100% Pure Objects, Always had 'em, Always will!

BTW: We've been thinking about that one String error, and we've got a solution.
We're going to make Strings understand the Arithmetic protocol too, but in that
case we're going to implicitly extract the number from the string if possible. Can
you say Perl?





More information about the Squeak-dev mailing list