I have come to the conclusion that neither an eager (a/k/a strict, e.g. most languages) nor lazy (a/k/a total, e.g. Haskell) language is vastly superior to the other. They each have tradeoffs, because they are categorical duals.

Eager is an inductive evaluation model, meaning we run the leaves as we as build the nested function tree of runtime possibilities.

Lazy is a coinductive evaluation model, meaning we run the leaves as needed from the nested function tree of runtime possibilities.

Eager can’t instantiate coinductive types, such as bottom (i.e. the entire Universe) or any infinite type, but it can instantiate inductive types such as the natural numbers.

Lazy can instantiate coinductive types, such as bottom and infinite types, but it can’t instantiate inductive types such as the natural numbers.

(from this blog post)