fun $ (x, y) = x y infixr 0 $ fun printLn s = (print s; print "\n") fun lazy thunk = let datatype 'a value = Unevaluated of unit -> 'a | Evaluated of 'a | Exn of exn val value = ref $ Unevaluated thunk in fn () => case !value of Unevaluated th => let val x = th () handle e => (value := Exn e; raise e) val () = value := Evaluated x in x end | Evaluated v => v | Exn e => raise e end