Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / MLtonFinalizable.adoc
CommitLineData
7f918cf1
CE
1MLtonFinalizable
2================
3
4[source,sml]
5----
6signature MLTON_FINALIZABLE =
7 sig
8 type 'a t
9
10 val addFinalizer: 'a t * ('a -> unit) -> unit
11 val finalizeBefore: 'a t * 'b t -> unit
12 val new: 'a -> 'a t
13 val touch: 'a t -> unit
14 val withValue: 'a t * ('a -> 'b) -> 'b
15 end
16----
17
18A _finalizable_ value is a container to which finalizers can be
19attached. A container holds a value, which is reachable as long as
20the container itself is reachable. A _finalizer_ is a function that
21runs at some point after garbage collection determines that the
22container to which it is attached has become
23<:Reachability:unreachable>. A finalizer is treated like a signal
24handler, in that it runs asynchronously in a separate thread, with
25signals blocked, and will not interrupt a critical section (see
26<:MLtonThread:>).
27
28* `addFinalizer (v, f)`
29+
30adds `f` as a finalizer to `v`. This means that sometime after the
31last call to `withValue` on `v` completes and `v` becomes unreachable,
32`f` will be called with the value of `v`.
33
34* `finalizeBefore (v1, v2)`
35+
36ensures that `v1` will be finalized before `v2`. A cycle of values
37`v` = `v1`, ..., `vn` = `v` with `finalizeBefore (vi, vi+1)` will
38result in none of the `vi` being finalized.
39
40* `new x`
41+
42creates a new finalizable value, `v`, with value `x`. The finalizers
43of `v` will run sometime after the last call to `withValue` on `v`
44when the garbage collector determines that `v` is unreachable.
45
46* `touch v`
47+
48ensures that `v`'s finalizers will not run before the call to `touch`.
49
50* `withValue (v, f)`
51+
52returns the result of applying `f` to the value of `v` and ensures
53that `v`'s finalizers will not run before `f` completes. The call to
54`f` is a nontail call.
55
56
57== Example ==
58
59Suppose that `finalizable.sml` contains the following:
60[source,sml]
61----
62sys::[./bin/InclGitFile.py mlton master doc/examples/finalizable/finalizable.sml]
63----
64
65Suppose that `cons.c` contains the following.
66[source,c]
67----
68sys::[./bin/InclGitFile.py mlton master doc/examples/finalizable/cons.c]
69----
70
71We can compile these to create an executable with
72----
73% mlton -default-ann 'allowFFI true' finalizable.sml cons.c
74----
75
76Running this executable will create output like the following.
77----
78% finalizable
790x08072890 = listSing (2)
800x080728a0 = listCons (2)
810x080728b0 = listCons (2)
820x080728c0 = listCons (2)
830x080728d0 = listCons (2)
840x080728e0 = listCons (2)
850x080728f0 = listCons (2)
86listSum
87listSum(l) = 14
88listFree (0x080728f0)
89listFree (0x080728e0)
90listFree (0x080728d0)
91listFree (0x080728c0)
92listFree (0x080728b0)
93listFree (0x080728a0)
94listFree (0x08072890)
95----
96
97
98== Synchronous Finalizers ==
99
100Finalizers in MLton are asynchronous. That is, they run at an
101unspecified time, interrupting the user program. It is also possible,
102and sometimes useful, to have synchronous finalizers, where the user
103program explicitly decides when to run enabled finalizers. We have
104considered this in MLton, and it seems possible, but there are some
105unresolved design issues. See the thread at
106
107* http://www.mlton.org/pipermail/mlton/2004-September/016570.html
108
109== Also see ==
110
111* <!Cite(Boehm03)>