Polymorphism without protocol dilution
mike at twinsun.com
Mon Aug 31 19:16:12 UTC 1998
On Mon, 31 Aug 1998, Maurice Rabb wrote:
> >I'd like to make a third kind of suggestion for your list. Don't mix blocks
> >and other values. Make the protocol different. For example:
> > at: key ifAbsentPut: anObject
> > self at: key ifAbsent: [ self at: key put: anObject ]
> > at: key ifAbsentPutValue: aBlock
> > self at: key ifAbsent: [ self at: key put: aBlock value ]
> >Another effect of this suggestion is that it still allows putting blocks
> >into dictionaries as values, while suggestions 1 and 2 do not.
> Good point. I was so focused on other aspects of protocol dilution, didn't
> consider the other form or dilution I was introducing.
First off, both the above methods are incorrect since they have no
return value. (a typo, I assume)
at: key ifAbsentPut: valueProvider
^self at: key ifAbsent: [self at: key put: valueProvider value]
Now it is clear that the second parameter is expected to provide a value.
(Not necesarily a block)
I think the problem with #value is that it *is* so diluted as to be
practically meaningless. What posible semantics (given today's
Smalltalks) could one ascribe to the message? The best I can come up with
"Answer some appropriate object"
I especially don't like that in VW, the ValueModel protocol intends
the #value message as being functional (as in free of side-effects)
whereas the blocks use value primarily in there imperative usage.
Yet, somehow, like static typing, it never seems to be a problem,
As long as were suggesting alternate selector names for Smalltalk-2002
how about #invoke, #invokeWith:, #invokeWith:with:
> Though this wasn't the best example to illustrate it, sometime you still
> want an variable to hold either anObject or aBlock that it can evaluate in
> the same way. If you want to prevent dilution, you shouldn't use #value.
> However in this case IMHO I think that the name should be #asEvaluated.
> ^self value
> (I still wish the convention for Blocks wasn't #value, and was instead
> something like #evaluate.)
Object >> fullyEvaluated
| result lastResult |
result := self.
[(lastResult := result) respondsTo: #value] whileTrue: [
result := lastResult value.
result = lastResult ifTrue: [^result]].
This is sort of like Mathematica's evaluation loop (without the Hold)
[0->] fullyEvaluated => 3
-- Mike Klein
More information about the Squeak-dev