Since pure functions compute the same results under lazy or strict evaluation and require that any data dependencies they have are explicitly provided as inputs, they interact with lazy computations in a much more tractable way. This means that adding a strictness operator to a lazy language is much easier than adding a laziness operator a a strict language.
An alternate approach is what python did with generators where there is a data type for lazy computation, but it lives apart from the rest of the language, so it is mostly used for e.g. stream processing where a default-lazy approach is conceptually straightforward and is less likely to lead to extremely non-trivial control flow. This approach does, however, basically give up on having a laziness operator that will turn a strict computation into a lazy one.
One example would be Eigen: https://eigen.tuxfamily.org/index.php?title=Main_Page
See also their page on lazy evaluation: https://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html
Of course, C++ is powerful enough that using specific tools can make the expression template abstraction fall apart (e.g. auto), but fundamentally you can write matrix code very cleanly and get great lazy-evaluated performance.
lazy by default enables better composition and local reasoning.
https://publish.obsidian.md/paretooptimaldev/Advantages+of+l...
There was a good Reddit thread recently where a lot of experts weighed in: https://www.reddit.com/r/haskell/comments/wpbs4z/what_things...
I recommend reading the thread -- lot's of great stuff in there, but...
TL;DR: It's a lot more complicated than it seems at first and it's far from obvious that strict-by-default is worth the cost.