[squeak-dev] IdentitySet>>collect:
Eliot Miranda
eliot.miranda at gmail.com
Wed Nov 26 21:56:32 UTC 2014
On Wed, Nov 26, 2014 at 1:26 PM, Levente Uzonyi <leves at elte.hu> wrote:
> On Wed, 26 Nov 2014, David T. Lewis wrote:
>
> On Wed, Nov 26, 2014 at 08:01:49PM +0100, Levente Uzonyi wrote:
>>
>>> On Wed, 26 Nov 2014, Eliot Miranda wrote:
>>>
>>> Hi All,
>>>> ? ? IdentitySet>>collect: answers a Set, not an IdentitySet.? Anyone
>>>> else
>>>> agree this is a serious bug?? Anyone else disagree?
>>>>
>>>> WTF??
>>>>
>>>> (IdentitySet withAll: #(1 2 3 1.0 2.0 3.0)) collect: [:e| e] a Set(1.0
>>>> 2 3)
>>>> --
>>>> best,Eliot
>>>>
>>>>
>>> Sometimes it's feasable to return an IdentitySet, other times it's not,
>>> so
>>> there's no optimal solution - #collect: can't cover all cases.
>>>
>>> Set >> #collect: explicitly returns a Set, because this is the least bad
>>> solution to handle all of its subclasses reasonably well.
>>> In case of WeakSet, returning a WeakSet makes no sense, because some of
>>> your objects will disappear immediately.
>>> In case of IdentitySet, PluggableSet, KeyedSet and KeyedIdentitySet the
>>> returned values may not behave well in the original collection.
>>>
>>> The best is to always be explicit:
>>>
>>> (IdentitySet withAll: #(1 2 3 1.0 2.0 3.0)) collect: [ :e | e ] as:
>>> IdentitySet
>>> "==> an IdentitySet(1 2 3 1.0 2.0 3.0)"
>>>
>>> Levente
>>>
>>>
>> In Squeak 2.8 (checked on http://bertfreudenberg.github.io/SqueakJS/run/
>> ):
>>
>> (IdentitySet withAll: #(1 2 3 1.0 2.0 3.0)) collect: [:e| e] ==> a
>> Set(2.0 1 2 3 3.0 1.0)
>>
>>
>> But in trunk I get this:
>>
>> (IdentitySet withAll: #(1 2 3 1.0 2.0 3.0)) collect: [:e| e] ==> a Set(1
>> 2 3)
>>
>>
>> So answering a Set makes sense for the reasons that Levente explains, but
>> trunk
>> is definitely broken WRT the contents of that set.
>>
>> This bug needs a unit test to go along with whatever fix we agree on.
>>
>
> It's not a bug either. The Floats are not there, because they are equal to
> the integers:
>
> 1 = 1.0 "==> true"
> 1.0 = 1 "==> true"
>
> Therefore they have the same hash:
>
> 1 hash "==> 1"
> 1.0 hash "==> 1"
>
> The bug was in Squeak 2.8:
> 1.0 = 1 "==> true"
> 1 = 1.0 "==> true"
> 1 hash "==> 1"
> 1.0 hash "==> 61440"
>
> Here's the comment of Float >> hash from The Trunk:
> "Hash is reimplemented because = is implemented. Both words of the
> float are used. (The bitShift:'s ensure that the intermediate results do
> not become a large integer.) Care is taken to answer same hash as an equal
> Integer."
>
Exactly.
My hope would be something like this (Set order is arbitrary)
((IdentitySet withAll: #(1 2 3 1.0 2.0 3.0)) collect: [:e| e]) =>
IdentitySet (1 2 3 1.0 2.0 3.0)
but that
(Set withAll: #(1 2 3 1.0 2.0 3.0)) => Set (1 2 3)
(and it always contains just the integers since these are added first).
But Levente's collect:as: solution is perfectly acceptable and as he points
out has the advantage of being explicit.
> Levente
>
>
>> Dave
>>
>>
>>
>>
>
--
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20141126/58279cf9/attachment.htm
More information about the Squeak-dev
mailing list
|