Closures in Standard ML

Standard ML supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

(* This function intSeq returns another function, which
   we define anonymously in the body of intSeq. The
   returned function closes over the variable i to
   form a closure. *)
fun intSeq () =
    let
        val i = ref 0
    in
        fn () => (i := !i + 1; !i)
    end;

(* We call intSeq, assigning the result (a function)
   to nextInt. This function value captures its
   own i value, which will be updated each time
   we call nextInt. *)
val nextInt = intSeq ();

(* See the effect of the closure by calling nextInt
   a few times. *)
val _ = print (Int.toString (nextInt ()) ^ "\n");
val _ = print (Int.toString (nextInt ()) ^ "\n");
val _ = print (Int.toString (nextInt ()) ^ "\n");

(* To confirm that the state is unique to that
   particular function, create and test a new one. *)
val newInts = intSeq ();
val _ = print (Int.toString (newInts ()) ^ "\n");

To run this Standard ML program, you would typically save it to a file (e.g., closures.sml) and then use an SML interpreter or compiler. For example, if you’re using Standard ML of New Jersey (SML/NJ):

$ sml closures.sml
1
2
3
1

In this Standard ML version:

  1. We define intSeq as a function that returns another function. The inner function captures the reference i in its closure.

  2. We use a reference (ref) to create mutable state, as Standard ML is primarily a functional language.

  3. The anonymous function returned by intSeq increments the reference and returns its value.

  4. In the main part of the program, we demonstrate the use of the closure by calling nextInt multiple times and then creating a new closure with newInts.

  5. We use print and Int.toString to output the results, as Standard ML doesn’t have a direct equivalent to Go’s fmt.Println.

This example demonstrates how closures work in Standard ML, capturing and maintaining state between function calls.