SML uses pass‑by‑value, Haskell uses call‑by‑need. Unless I'm wrong (the purpose of this question), one can do call‑by‑need with SML, passing a function instead of a value; a function to be later evaluated when needed.
Adapting a classical example:
(* This will print `0` *)
fun pass_by_function (cond, a1, a2) =
if cond then a1
else a2
val e1 = fn () => 1 * 0
val e2 = fn () => 1 div 0
val _ = print (Int.toString (pass_by_function (true, e1, e2) ()))
(* This will fail with a divide error *)
fun pass_by_value (cond, a1, a2) =
if cond then a1
else a2
val _ = print (Int.toString (pass_by_value (true, 1 * 0, 1 div 0)))
It's a big matter for Haskell to be call‑by‑need. I'm just wondering if there is something else or if it's just, say “syntactic sugar”, compared to the way it needs to be done with SML.
Is this just a different way to write the same or is there a semantic difference I'm not aware of? Passing a function, is it indeed always the same as call‑by‑need? If not, when and how does it differs?