1.1 -- Inconsistent enumeration behavior of WeakKeyDictionary and subclasses

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

1.1 -- Inconsistent enumeration behavior of WeakKeyDictionary and subclasses

Martin McClure-2
If you run this in 1.1:

| dict |
dict := WeakKeyDictionary new.
dict at: 'foo' copy put: 'bar'.
Smalltalk garbageCollect.
dict associationsDo: [:assoc | self halt].
dict do: [:val | self halt]


It stops in the second halt, but not the first.

This is because #associationsDo: does not include associations whose
keys have been GCed, but #do: *does* include values whose corresponding
keys have been GCed.

This behavior seems inconsistent, and not particularly useful, and also
seems to contradict the comments by the author in the Squeak bug from
2007, from which I'd think that #do: would not include the value which
it currently does.

So I *think* this is an oversight, and is easy to fix by defining
WeakKeyDictionary>>do: in terms of self associationsDo:.

But then there's the question of #size. The collection above answers 1
to #size, which also seems wrong.


Comments?

Regards,

-Martin

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: 1.1 -- Inconsistent enumeration behavior of WeakKeyDictionary and subclasses

Igor Stasenko
2009/12/31 Martin McClure <[hidden email]>:

> If you run this in 1.1:
>
> | dict |
> dict := WeakKeyDictionary new.
> dict at: 'foo' copy put: 'bar'.
> Smalltalk garbageCollect.
> dict associationsDo: [:assoc | self halt].
> dict do: [:val | self halt]
>
>
> It stops in the second halt, but not the first.
>
> This is because #associationsDo: does not include associations whose
> keys have been GCed, but #do: *does* include values whose corresponding
> keys have been GCed.
>
> This behavior seems inconsistent, and not particularly useful, and also
> seems to contradict the comments by the author in the Squeak bug from
> 2007, from which I'd think that #do: would not include the value which
> it currently does.
>
It is useful in terms, that sometimes you don't want to see the
objects which GCed,
but sometimes do. See how WeakRegistry using this.
The lack of ephemerons support in VM, forcing us to deal with such
things manually.

> So I *think* this is an oversight, and is easy to fix by defining
> WeakKeyDictionary>>do: in terms of self associationsDo:.
>
> But then there's the question of #size. The collection above answers 1
> to #size, which also seems wrong.
>
#size for weak key dict is non-deterministic. Because even if you want to know
the exact number of elements, you will need to iterate over the
collection, but then,
iteration can trigger GC, and you have a big chances to answer wrong value.

>
> Comments?
>
> Regards,
>
> -Martin
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>



--
Best regards,
Igor Stasenko AKA sig.

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: 1.1 -- Inconsistent enumeration behavior of WeakKeyDictionary and subclasses

Martin McClure-2
Igor Stasenko wrote:

> 2009/12/31 Martin McClure <[hidden email]>:
>> If you run this in 1.1:
>>
>> | dict |
>> dict := WeakKeyDictionary new.
>> dict at: 'foo' copy put: 'bar'.
>> Smalltalk garbageCollect.
>> dict associationsDo: [:assoc | self halt].
>> dict do: [:val | self halt]
>>
>>
>> It stops in the second halt, but not the first.
>>
>> This is because #associationsDo: does not include associations whose
>> keys have been GCed, but #do: *does* include values whose corresponding
>> keys have been GCed.
>>
>> This behavior seems inconsistent, and not particularly useful, and also
>> seems to contradict the comments by the author in the Squeak bug from
>> 2007, from which I'd think that #do: would not include the value which
>> it currently does.
>>
> It is useful in terms, that sometimes you don't want to see the
> objects which GCed,
> but sometimes do. See how WeakRegistry using this.
> The lack of ephemerons support in VM, forcing us to deal with such
> things manually.

I see the value in being able to choose both. WeakRegistry uses
#allAssociationsDo:, not #associationsDo:. Seems like it would be more
consistent to also have an #allDo: that includes values of collected
keys, and a #do: that does not.

>
>> So I *think* this is an oversight, and is easy to fix by defining
>> WeakKeyDictionary>>do: in terms of self associationsDo:.
>>
>> But then there's the question of #size. The collection above answers 1
>> to #size, which also seems wrong.
>>
> #size for weak key dict is non-deterministic. Because even if you want to know
> the exact number of elements, you will need to iterate over the
> collection, but then,
> iteration can trigger GC, and you have a big chances to answer wrong value.

That seems reasonable, though there's no effort to even come close in size.

-Martin

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: 1.1 -- Inconsistent enumeration behavior of WeakKeyDictionary and subclasses

Igor Stasenko
2009/12/31 Martin McClure <[hidden email]>:

> Igor Stasenko wrote:
>> 2009/12/31 Martin McClure <[hidden email]>:
>>> If you run this in 1.1:
>>>
>>> | dict |
>>> dict := WeakKeyDictionary new.
>>> dict at: 'foo' copy put: 'bar'.
>>> Smalltalk garbageCollect.
>>> dict associationsDo: [:assoc | self halt].
>>> dict do: [:val | self halt]
>>>
>>>
>>> It stops in the second halt, but not the first.
>>>
>>> This is because #associationsDo: does not include associations whose
>>> keys have been GCed, but #do: *does* include values whose corresponding
>>> keys have been GCed.
>>>
>>> This behavior seems inconsistent, and not particularly useful, and also
>>> seems to contradict the comments by the author in the Squeak bug from
>>> 2007, from which I'd think that #do: would not include the value which
>>> it currently does.
>>>
>> It is useful in terms, that sometimes you don't want to see the
>> objects which GCed,
>> but sometimes do. See how WeakRegistry using this.
>> The lack of ephemerons support in VM, forcing us to deal with such
>> things manually.
>
> I see the value in being able to choose both. WeakRegistry uses
> #allAssociationsDo:, not #associationsDo:. Seems like it would be more
> consistent to also have an #allDo: that includes values of collected
> keys, and a #do: that does not.
>
Well, let first take in account that Dictionary is not well consistent
with Collection protocol.
For instance, if #add: expects association, then one could say, that
Dictionary is a Collection of associations.
But if you try pass association to #includes: , or observe what
objects iterated in #do: you'll find out that its not.
And so, if you treat a dictionary as a collection of values, indexed
by associated keys,
then from this POV, a #do: behavior in weak dict is consistent with
Collection protocol.
But #associationsDo: will not report same number of entries, since
some of them having invalid (nil) keys.

>>
>>> So I *think* this is an oversight, and is easy to fix by defining
>>> WeakKeyDictionary>>do: in terms of self associationsDo:.
>>>
>>> But then there's the question of #size. The collection above answers 1
>>> to #size, which also seems wrong.
>>>
>> #size for weak key dict is non-deterministic. Because even if you want to know
>> the exact number of elements, you will need to iterate over the
>> collection, but then,
>> iteration can trigger GC, and you have a big chances to answer wrong value.
>
> That seems reasonable, though there's no effort to even come close in size.
>
I don't think that #size having any value for weak key dicts at all,
since there is no strict
guarantees at any point of time, that collection will have same number
of elements as few cycles before.
So, measuring size of weak dict is pointless, and existing simply to
conform with Collection protocol.

> -Martin
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>



--
Best regards,
Igor Stasenko AKA sig.

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: 1.1 -- Inconsistent enumeration behavior of WeakKeyDictionary and subclasses

Stéphane Ducasse
In reply to this post by Martin McClure-2
>>
> I see the value in being able to choose both. WeakRegistry uses
> #allAssociationsDo:, not #associationsDo:. Seems like it would be more
> consistent to also have an #allDo: that includes values of collected
> keys, and a #do: that does not.

yes and a good method comment

>
>>
>>> So I *think* this is an oversight, and is easy to fix by defining
>>> WeakKeyDictionary>>do: in terms of self associationsDo:.
>>>
>>> But then there's the question of #size. The collection above answers 1
>>> to #size, which also seems wrong.
>>>
>> #size for weak key dict is non-deterministic. Because even if you want to know
>> the exact number of elements, you will need to iterate over the
>> collection, but then,
>> iteration can trigger GC, and you have a big chances to answer wrong value.
>
> That seems reasonable, though there's no effort to even come close in size.
>
> -Martin
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project