Import Upstream version 20180207
[hcoop/debian/mlton.git] / doc / guide / src / Lazy.adoc
CommitLineData
7f918cf1
CE
1Lazy
2====
3
4In a lazy (or non-strict) language, the arguments to a function are
5not evaluated before calling the function. Instead, the arguments are
6suspended and only evaluated by the function if needed.
7
8<:StandardML:Standard ML> is an eager (or strict) language, not a lazy
9language. However, it is easy to delay evaluation of an expression in
10SML by creating a _thunk_, which is a nullary function. In SML, a
11thunk is written `fn () => e`. Another essential feature of laziness
12is _memoization_, meaning that once a suspended argument is evaluated,
13subsequent references look up the value. We can express this in SML
14with a function that maps a thunk to a memoized thunk.
15
16[source,sml]
17----
18signature LAZY =
19 sig
20 val lazy: (unit -> 'a) -> unit -> 'a
21 end
22----
23
24This is easy to implement in SML.
25
26[source,sml]
27----
28structure Lazy: LAZY =
29 struct
30 fun lazy (th: unit -> 'a): unit -> 'a =
31 let
32 datatype 'a lazy_result = Unevaluated of (unit -> 'a)
33 | Evaluated of 'a
34 | Failed of exn
35
36 val r = ref (Unevaluated th)
37 in
38 fn () =>
39 case !r of
40 Unevaluated th => let
41 val a = th ()
42 handle x => (r := Failed x; raise x)
43 val () = r := Evaluated a
44 in
45 a
46 end
47 | Evaluated a => a
48 | Failed x => raise x
49 end
50 end
51----