mozart/mozart2 — pull request #59 by sjrd (2013-05-21 19:44:24+00:00)
Title: Fixes #45 with WeakDictionary (and Finalize.postmortem)

This pull request fixes #45 by providing `WeakDictionary`, and also `Finalize.postmortem` (developed in the process).

As was agreed months ago in a PLDC meeting with P. Van Roy, this implementation has post-mortem semantics, whereas Mozart 1 had pre-mortem semantics for WeakDictionaries.

This means that instead of sending Key#Value to the stream when Value is about to become dead, we send Key#unit to the stream when Value is dead. (It should be just Key, but I feel Key#unit is less incompatible).

There are a few commits because the journey to there was not trivial. Basically it all relies on two simple concepts in the VM.

First, there is a read-only property `'gc.watcher'` (`{Property.get 'gc.watcher'}`) that is always a read-only variable (future). After each GC, the VM binds this future to `unit`, and installs a new, fresh future in the property.

This provides a very simple means for a thread to "wait until a GC has occurred": simply `{Wait {Property.get 'gc.watcher'}}`. Put in a loop, such a construct effectively produces code that will be run after every GC.

The other core concept is the new data type `WeakReference`. The builtin module `WeakReference` provides three builtins to deal with weak references:
* `{Boot_WeakRef.new X ?WR}` creates a new weak ref for the entity `X`
* `{Boot_WeakRef.is V ?B}` tests whether `V` is a weak reference
* `{Boot_WeakRef.get WR ?Y}` dereferences the weak ref. `Y` will be `some(X)` if `X` is still alive (reachable through strong references), and `none` otherwise.

Combined with the `'gc.watcher'` property, a very simple pattern is derived to execute code when a given entity `X` becomes unreachable (dead):

```
WeakX = {Boot_WeakRef.new X}
proc {Watch}
{Wait {Property.get 'oz.watcher'}} % wait for next GC
if {Boot_WeakRef.get WeakX} == none then
{DoSomething} % X is dead
else
{Watch} % loop
end
end
thread {Watch} end % start the watcher thread
```

This pattern is used almost as is to implement `{Finalize.postmortem}`, which is actually implemented in `lib/main/sys/System.oz`.

The same concepts are used, in a more elaborate way, to implement postmortem weak dictionaries, in `lib/main/base/WeakDictionary.oz`.

To the reviewer, here is some code snippet to play with for testing:
```
% Declare these
declare S WD = {NewWeakDictionary ?S} {Browse S}
declare X = {NewCell {NewName}}

% Then play with these by feeding individual lines
X := {NewName}
{WeakDictionary.put WD foo @X}
{Show {WeakDictionary.entries WD}}
{Show {WeakDictionary.toRecord lab WD}}
{System.gcDo}
{WeakDictionary.close WD}
{Show {WeakDictionary.isEmpty WD}}
```