9.4 Weak Dictionaries

The module WeakDictionary contains procedures operating on weak dictionaries. A weak dictionary is much like an ordinary dictionary and supports the same API. The main difference is that an entry is kept only as long as its item (i. e. the value recorded under the key) has not become garbage. If the item is only reachable through one or more weak dictionaries, the corresponding entries will automatically be dropped from all weak dictionaries at the next garbage collection.

Finalization Stream

Each weak dictionary is associated with a finalization stream. When an item X (indexed under Key) becomes garbage, the entry is automatically removed from the weak dictionary at the next garbage collection and the pair Key#X is sent on to the finalization stream (as if the weak dictionary were associated with a port and the pair was sent to it using Port.send). This means that the item, which was garbage, becomes again non-garbage when it is sent to the finalization stream. If subsequently, this last remaining reference disappears, then the item really becomes garbage since it won't be referenced even through a weak dictionary.

The finalization stream is created at the same time as the weak dictionary; both are output arguments of NewWeakDictionary. If you are not interested in the finalization stream, you can explicitly close it using WeakDictionary.close.

Module WeakDictionary can also be accessed as Dictionary.weak.


{WeakDictionary.is +X ?B}

tests whether X is a weak dictionary.


{WeakDictionary.new ?L ?Weak}

has the same arguments as Port.new. Returns a new empty weak dictionary associated with a new finalization stream L.


{WeakDictionary.close +Weak}

drops the finalization stream (if any). After this, any entry that becomes garbage is simply dropped instead of being sent to the finalization stream. Note that the close, put, remove, and removeAll operations cannot be used in a (subordinated) space other than where the weak dictionary has been constructed.


{WeakDictionary.put +Weak +LI X}

sets the item in Weak under key LI to X.


{WeakDictionary.get +Weak +LI X}

returns the item X of Weak under key LI.


{WeakDictionary.condGet +Weak +LI X Y}

returns the item Y of Weak under key LI, if LI is a valid key of Weak. Otherwise, returns X.


{WeakDictionary.exchange +Weak +LI OldVal NewVal}

returns the current value of Weak under key LI as item OldVal and updates the value of Weak under key LI to be NewVal.


{WeakDictionary.condExchange +Weak +LI DefVal 
OldVal NewVal}

If LI is a valid key of Weak then returns the current value of Weak under key LI as item OldVal otherwise, returns DefVal as item OldVal. Sets the value of Weak under key LI to be NewVal.


{WeakDictionary.keys +Weak ?LIs}

returns a list of all currently valid keys of Weak.


{WeakDictionary.entries +Weak ?Ts}

returns the list of current entries of Weak. An entry is a pair LI#X, where LI is a valid key of Weak and X the corresponding item.


{WeakDictionary.items +Weak ?Xs}

returns the list of all items currently in Weak.


{WeakDictionary.isEmpty +Weak ?B}

tests whether Weak currently contains an entry.


{WeakDictionary.remove +Weak +LI}

removes the item under key LI from Weak if LI is a valid key. Otherwise, does nothing.


{WeakDictionary.removeAll +Weak}

removes all entries currently in Weak.


{WeakDictionary.member +Weak +LI ?B}

tests whether LI is a valid key of Weak.


{WeakDictionary.toRecord +L +Weak ?R}

returns a record R with label L whose features and their fields correspond to the keys and their entries of Weak.

Denys Duchier, Leif Kornstaedt and Christian Schulte
Version 1.4.0 (20080702)