I was reading about continuations in Standard ML (SMLofNJ.Cont). I understood what callcc and throw does, but could not understand isolate. The documentation says
Discard all live data from the calling context (except what is reachable from f or x), then call f(x), then exit. This may use much less memory then something like f(x) before exit().
However this does not make any sense to me. I just wanted to know what this function does, with some examples.
MLton does a better job of explaining an implementation of isolate
using callcc
and throw
:
val isolate: ('a -> unit) -> 'a t = fn (f: 'a -> unit) => callcc (fn k1 => let val x = callcc (fn k2 => throw (k1, k2)) val _ = (f x ; Exit.topLevelSuffix ()) handle exn => MLtonExn.topLevelHandler exn in raise Fail "MLton.Cont.isolate: return from (wrapped) func" end)
We use the standard nested callcc trick to return a continuation that is ready to receive an argument, execute the isolated function, and exit the program. [...]
The page continues to explain how to achieve the same effect with less space leaking.
MLton's CONT
signature has a different documentation line than SML/NJ's CONT
signature:
isolate f
creates a continuation that evaluatesf
in an empty context.This is a constant time operation, and yields a constant size stack.