Explicitly controlled laziness offers a lot that you can't do in e.g. Haskell with a more principled implementation of laziness.
Here's are a couple examples:
- Suppose you've got a list of values and you want to know if any of them satisfy some predicate. If you first check every value that you know has already been thunked and only then try the others, you avoid a bunch of potentially expensive computation.
- If you're lazy in a way that exposes not just a thunk but also the operations, you can perform algebraic rewrites at runtime.
- Special case of the above: If you can distinguish between a thunked value and an unthunked one you can do conditional optimisations. e.g. if you do a * b then you can check if either of a or b are an unthunked zero and replace the whole expresison with 0, without forcing an evaluation.
There are a bunch more I've run into like this. Some of them are things that a sufficiently smart compiler would do for you anyway, but even then it would only do them in circumstances where the algebraic properties of your operations are visible to it, and most of the time that's not going to be the case.