#at:ifAbsent... (was: Polymorphism without protocol dilution)
Maurice Rabb
m3rabb at stono.com
Wed Sep 2 03:51:22 UTC 1998
At 8:13 PM 9/1/98, Bob Arning wrote:
>Dave,
>
>I'm not sure I parsed this as you intended:
>
>On Tue, 1 Sep 1998 16:55:11 -0400 "David N. Smith"
><dnsmith at watson.ibm.com> wrote:
>>I don't think of this as a type issue, but an evaluation issue. When is the
>>parameter evaluated: when first passed, when about to insert it into the
>>collection (lazy evaluation), or never? I claim one needs all three.
>>
Correct me if I am wrong, but I think you misunderstood what Dave is
saying. If we use the proposed methods:
The parameter is evaluated when it is first passed:
dict at: '200!' ifAbsentPut: (200 factorial). "<- puts a value"
The parameter is evaluate when it about to be inserted:
dict at: '55!' ifAbsentPutValueOf: [55 factorial] "<- puts a value"
The parameter is never evaluated. (It is just inserted):
dict at: '10! calculation' ifAbsentPut: [10 factorial]. "<- puts a block"
dict at: '10!' ifAbsentPut: 3628800 "<- puts a value"
At no point is he suggesting that the ifAbsent: or ifAbsentValueOf:
parameter be used or evaluated inside the method unless the #at: fails to
find the key. He is _not_ suggesting that we break from the consistent
behavior of all the other ifXxxx: protocols.
>>#at:ifAbsentPut:, as implemented elsewhere, evaluates the parameter
>>expression before the message is sent. If it is a block then the block is
>>put into the collection.
>>
Again this is what he means:
anInteger _ dict at: '22!' ifAbsentPut: (22 factorial)
^
"evaluates the parameter expression before the message is sent" ---|
aBlock _ dict at: 'bobs example'
ifAbsent: (aBoolean ifTrue: [ [:x | x doSomething] ]
ifFalse: [ [:x | x doSomethingElse] ])
^
"evaluates the parameter expression before the message is sent" ---|
>Are you referring to actual implementations? I seem to recall from VSE
>work that if the second argument is a block, then it is #value'd if the
>key does not exist and the result is added. Perhaps this was a local
>implementation (I cannot recall at this point) - do different
>implementations exist?
>
Yes, unfortunately different dialects of Smalltalk implement
#at:ifAbsentPut: with different semantics. Some insert the second
parameter whether it is a block or a simple object (as we propose). Others
insert either a simple value, or the value of a block if it is a block.
[munch]
>>Note that, for consistancy, if the thrid example is considered wrong, one
>>should then make #at:put: have the same properties as #at:ifAbsentPut:. If
>>a block is passed it is evaluated before putting its value into the
>>collection.
To restate the above: If #at:ifAbsentPut: behaves such that it accepts
either a simple value or a block, using the value of the block if it is a
block, then #at:put: should behave the same. Thus:
dict at: 1 put: 10 factorial "puts a 3628800"
dict at: 2 put: [10 factorial] "puts a 3628800"
dict at: 3 put: [ [10 factorial] ] "puts a block"
IMHO, these semantics are not just ugly, but "astonishing"! I vote for Dave's.
Dave, please correct me if I got this all wrong.
--Maurice
---------------------------------------------------------------------------
Maurice Rabb 773.281.6003 Stono Technologies, LLC Chicago, USA
More information about the Squeak-dev
mailing list
|