Surprising behavior of WeakArrays

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

Surprising behavior of WeakArrays

Joachim Geidel
I wanted to test if a WeakArray contains any living elements. #isEmpty gives
the same answer as an Array, i.e. it answers true only when the WeakArray's
size is zero. That's okay, as it is Array semantics. However, when I send
asSet to a WeakArray containing tombstones, the tombstone is part of the
result, although it is only an internal marker and not really an element of
the WeakArray:

| weak |
weak := WeakArray with: Object new.
ObjectMemory garbageCollect.
weak isEmpty.   "false -> that's okay"
weak asSet.     "Set with: 0"

Is this intended, or is it a bug? Should asSet (and other inherited methods
like asArray etc.) be reimplemented in WeakArray as

asSet
    ^self nilAllCorpsesAndDo: [super asSet]
?

Not that this would be very important - I usually don't want to use
WeakArrays in this way, and I can always use nilAllCorpsesAndDo: explicitly.

Best regards,
Joachim Geidel


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Surprising behavior of WeakArrays

Paul Baumann
The tombstone is both an internal marker and a marker that a user of a weak array is interested in. Weak arrays are often paired with an array so that when a tombstone is found then the same slot in the other array can be managed appropriately. The tombstone is important and useful for the management of related data.

Not all dialects use tombstones. Other dialects use a VM notify with a queued high-priority sweep approach. The other dialects have no tombstone and behave as you are expecting. The tombstone design is more reliable and allows you to distinguish between an empty slot and a slot that could use cleanup. The queue approach has queue-size issues, finalization error issues, and atomic finalization issues.

>> Is it intended, or is it a bug?

WeakArray is normally used with indexed access. WeakArray is dialect-specific. The use of tombstones is better than other approaches. VW has tomstones and you just need to code to anticipate them for typical indexed access.

It is a bug in design intent, but others would not consider it a bug because there is no common understanding of how a WeakArray should behave. It would take an ANSI spec declaration to persuade a change in this behavior.

The design of VW WeakArray is more suited for use within other collections. That design didn't likely anticipate that WeakArray would be converted to a set. Implementing WeakArray>>asSet (and perhaps some others) to ignore tombstones for index irrelevant enumerations (like #do:) wouldn't be harmful because most uses of WeakArray are indexed access with tombstone checks. VW WeakArray could have been designed to ignore tombstones for all but indexed access and specialized enumeration. WeakArray could be changed to behave as you are expecting, but I doubt Cincom would do that out of concern that it might break existing code.

Paul Baumann


-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Joachim Geidel
Sent: Saturday, May 22, 2010 3:46 AM
To: VWNC
Subject: [vwnc] Surprising behavior of WeakArrays

I wanted to test if a WeakArray contains any living elements. #isEmpty gives the same answer as an Array, i.e. it answers true only when the WeakArray's size is zero. That's okay, as it is Array semantics. However, when I send asSet to a WeakArray containing tombstones, the tombstone is part of the result, although it is only an internal marker and not really an element of the WeakArray:

| weak |
weak := WeakArray with: Object new.
ObjectMemory garbageCollect.
weak isEmpty.   "false -> that's okay"
weak asSet.     "Set with: 0"

Is this intended, or is it a bug? Should asSet (and other inherited methods like asArray etc.) be reimplemented in WeakArray as

asSet
    ^self nilAllCorpsesAndDo: [super asSet] ?

Not that this would be very important - I usually don't want to use WeakArrays in this way, and I can always use nilAllCorpsesAndDo: explicitly.

Best regards,
Joachim Geidel


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc


This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Surprising behavior of WeakArrays

Joachim Geidel
Hello Paul,

Thanks for the explanation! That makes sense and confirms what I suspected.
I'll just avoid using "aWeakArray asSet" - there are myriad other ways of
testing what I need to test. :-)

Joachim

Am 24.05.10 17:11 schrieb Paul Baumann:

> The tombstone is both an internal marker and a marker that a user of a weak
> array is interested in. Weak arrays are often paired with an array so that
> when a tombstone is found then the same slot in the other array can be managed
> appropriately. The tombstone is important and useful for the management of
> related data.
>
> Not all dialects use tombstones. Other dialects use a VM notify with a queued
> high-priority sweep approach. The other dialects have no tombstone and behave
> as you are expecting. The tombstone design is more reliable and allows you to
> distinguish between an empty slot and a slot that could use cleanup. The queue
> approach has queue-size issues, finalization error issues, and atomic
> finalization issues.
>
>>> Is it intended, or is it a bug?
>
> WeakArray is normally used with indexed access. WeakArray is dialect-specific.
> The use of tombstones is better than other approaches. VW has tomstones and
> you just need to code to anticipate them for typical indexed access.
>
> It is a bug in design intent, but others would not consider it a bug because
> there is no common understanding of how a WeakArray should behave. It would
> take an ANSI spec declaration to persuade a change in this behavior.
>
> The design of VW WeakArray is more suited for use within other collections.
> That design didn't likely anticipate that WeakArray would be converted to a
> set. Implementing WeakArray>>asSet (and perhaps some others) to ignore
> tombstones for index irrelevant enumerations (like #do:) wouldn't be harmful
> because most uses of WeakArray are indexed access with tombstone checks. VW
> WeakArray could have been designed to ignore tombstones for all but indexed
> access and specialized enumeration. WeakArray could be changed to behave as
> you are expecting, but I doubt Cincom would do that out of concern that it
> might break existing code.
>
> Paul Baumann


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Surprising behavior of WeakArrays

Alan Knight-2
In reply to this post by Paul Baumann
Interesting comments. I note that the ephemeron mechanism also in VW, does not use a tombstone type of approach. It also has some other advantages, e.g. handling of weak cycles. I'm not sure what the issues are that you're mentioning with respect to other dialects, or if ephemerons suffer from them.

At 11:11 AM 2010-05-24, Paul Baumann wrote:
The tombstone is both an internal marker and a marker that a user of a weak array is interested in. Weak arrays are often paired with an array so that when a tombstone is found then the same slot in the other array can be managed appropriately. The tombstone is important and useful for the management of related data.

Not all dialects use tombstones. Other dialects use a VM notify with a queued high-priority sweep approach. The other dialects have no tombstone and behave as you are expecting. The tombstone design is more reliable and allows you to distinguish between an empty slot and a slot that could use cleanup. The queue approach has queue-size issues, finalization error issues, and atomic finalization issues.

>> Is it intended, or is it a bug?

WeakArray is normally used with indexed access. WeakArray is dialect-specific. The use of tombstones is better than other approaches. VW has tomstones and you just need to code to anticipate them for typical indexed access.

It is a bug in design intent, but others would not consider it a bug because there is no common understanding of how a WeakArray should behave. It would take an ANSI spec declaration to persuade a change in this behavior.

The design of VW WeakArray is more suited for use within other collections. That design didn't likely anticipate that WeakArray would be converted to a set. Implementing WeakArray>>asSet (and perhaps some others) to ignore tombstones for index irrelevant enumerations (like #do:) wouldn't be harmful because most uses of WeakArray are indexed access with tombstone checks. VW WeakArray could have been designed to ignore tombstones for all but indexed access and specialized enumeration. WeakArray could be changed to behave as you are expecting, but I doubt Cincom would do that out of concern that it might break existing code.

Paul Baumann


-----Original Message-----
From: [hidden email] [[hidden email]] On Behalf Of Joachim Geidel
Sent: Saturday, May 22, 2010 3:46 AM
To: VWNC
Subject: [vwnc] Surprising behavior of WeakArrays

I wanted to test if a WeakArray contains any living elements. #isEmpty gives the same answer as an Array, i.e. it answers true only when the WeakArray's size is zero. That's okay, as it is Array semantics. However, when I send asSet to a WeakArray containing tombstones, the tombstone is part of the result, although it is only an internal marker and not really an element of the WeakArray:

| weak |
weak := WeakArray with: Object new.
ObjectMemory garbageCollect.
weak isEmpty.   "false -> that's okay"
weak asSet.     "Set with: 0"

Is this intended, or is it a bug? Should asSet (and other inherited methods like asArray etc.) be reimplemented in WeakArray as

asSet
    ^self nilAllCorpsesAndDo: [super asSet] ?

Not that this would be very important - I usually don't want to use WeakArrays in this way, and I can always use nilAllCorpsesAndDo: explicitly.

Best regards,
Joachim Geidel


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc


This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

--
Alan Knight [|], Engineering Manager, Cincom Smalltalk

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc