+Another way to control evaluation order, you'll recall from [[week6]], is to use **thunks**. These are functions that only take the uninformative `()` as an argument, such as this:
+
+ let f () = ...
+
+or this:
+
+ let f = fun () -> ...
+
+In Scheme these are written as functions that take 0 arguments:
+
+ (lambda () ...)
+
+or:
+
+ (define (f) ...)
+
+How could such functions be useful? Well, as always, the context in which you build a function need not be the same as the one in which you apply it to some arguments. So for example:
+
+ let ycell = ref 1
+ in let f () = ycell := !ycell + 1
+ in let z = !ycell
+ in f ()
+ in z;;
+
+We don't apply (or call or execute or however you want to say it) the function `f` until after we've extracted `ycell`'s value and assigned it to `z`. So `z` will get assigned to 1. If on the other hand we called `f ()` before evaluating `let z = !ycell`, then `z` would have gotten assigned a different value.
+
+In languages with mutable variables, the free variables in a function definition are usually taken to refer back to the same *reference cells* they had in their lexical contexts, and not just their original value. So if we do this for instance:
+
+ let factory (starting_value : int) =
+ let free_var = ref starting_value
+ in let getter () =
+ !free_var
+ in let setter (new_value : int) =
+ free_var := new_value
+ in (getter, setter)
+ in let (getter1, setter1) = factory 1
+ in let first = getter1 ()
+ in let () = setter1 2
+ in let second = getter1 ()
+ in let () = setter1 3
+ in let third = getter1 ()
+ in (first, second, third)
+
+At the end, we'll get `(1, 2, 3)`. The reference cell that gets updated when we call `setter1` is the same one that gets fetched from when we call `getter1`. This should seem very intuitive here, since we're working with explicit-style mutation. When working with a language with implicit-style mutation, it can be more surprising. For instance, here's the same fragment in Python, which has implicit-style mutation:
+
+ def factory (starting_value):
+ free_var = starting_value
+ def getter ():
+ return free_var
+ def setter (new_value):
+ # the next line indicates that we're using the
+ # free_var from the surrounding function, not
+ # introducing a new local variable with the same name
+ nonlocal free_var
+ free_var = new_value
+ return getter, setter
+ getter1, setter1 = factory (1)
+ first = getter1 ()
+ setter1 (2)
+ second = getter1 ()
+ setter1 (3)
+ third = getter1 ()
+ (first, second, third)
+
+Here, too, just as in the OCaml fragment, all the calls to getter1 and setter1 are working with a single mutable variable `free_var`.
+
+If however you called `factory` twice, you'd have different `getter`/`setter` pairs, each of which had their own, independent `free_var`. In OCaml:
+
+ let factory (starting_val : int) =
+ ... (* as above *)
+ in let (getter1, setter1) = factory 1
+ in let (getter2, setter2) = factory 1
+ in let () = setter1 2
+ in getter2 ()
+
+Here, the call to `setter1` only mutated the reference cell associated with the `getter1`/`setter1` pair. The reference cell associated with `getter2` hasn't changed, and so `getter2 ()` will still evaluate to 1.
+
+Notice in these fragments that once we return from inside the call to `factory`, the `free_var` mutable variable is no longer accessible, except through the helper functions `getter` and `setter` that we've provided. This is another way in which a thunk like `getter` can be useful: it still has access to the `free_var` reference cell that was created when it was, because its free variables are interpreted relative to the context in which `getter` was built, even if that context is otherwise no longer accessible. What `getter ()` evaluates to, however, will very much depend on *when* we evaluate it---in particular, it will depend on which calls to the corresponding `setter` were evaluated first.