Call by need compared to pass by function
Call-by-need is more than call-by-name.  Call-by-name is syntactic sugar for wrapping a closure (thunk) around each argument and then passing the pointer to the closure.  Your example shows what call-by-name turns into under the covers.

Call-by-need goes one step further by memoizing.  If an argument is used twice in a function then the thunk corresponding to that argument is only evaluated once, the result is stored, and then on the second (and after) use of that argument the stored value is returned instead of paying the cost of reevaluating the function.

This only works because Haskell is pure functional.  That means that every function call always returns the same result for the same inputs.  With a language with any mutation you can't make this guarantee, so it is much harder to do call-by-need automatically.  SML allows mutation.