I have heard there is a branch of GHC that compiles to strict code by default whereas laziness can be enabled by annotation. (IIRC, he said a financial company develops the branch and uses it for production code.) Is that true? I can't find it.
The person also suggested that the opinion that strict evaluation is more practical than lazy evaluation (by default) gains acceptance more and more. I don't find this confirmed in the Haskell mailing list, but maybe that is because people there are not that practice-oriented?
All I find on strict Haskell are explicit things like $!
and rnf
. While I find lazy evaluation very elegant, I'd like to develop a a program in Haskell where I want to avoid space leaks and would like to have predictable performance.
Disclaimer: I'm not making a case for strictness, I'd just like to have a look at strict Haskell or something like that.
You're looking for Disciple.
So there are two kinds of laziness to distinguish in Haskell. There's lazy I/O, which is an abomination and is solved by iteratee libraries (Shameless plug: including my pipes library). Then there's laziness in pure computations, which is still open to debate, but I'll try to summarize the key advantages of laziness since you are already familiar with the disadvantage:
Laziness is more efficient
A simple example is:
any = foldr (||) False
any
finds if any value in a list is True
. This only evaluates the elements up to the first True
, so it doesn't matter if the list is very long.
Laziness only computes as much as it has to, meaning that if you chain together two lazy computations, it can actually improve the time complexity of the resulting computation. This Stack Overflow comment gives another good example of this.
This is actually the same reason why iteratee libraries are very resource-efficient. They only do as much work as they have to generate results, and this leads to very efficient memory and disk usage with very easy-to-use semantics.
Laziness is inherently more composable
This is well known by people who have programmed in both strict and functional languages, but I actually inadvertently demonstrated a limited proof of this while working on the pipes
library, where the lazy version is the only version that permits a Category
instance. Pipes actually work in any monad, including the pure Identity
monad, so my proofs translate to pure code as well.
This is the true reason why I believe that laziness in general is really the future of programming, however I still think that it's an open question of whether or not Haskell implemented laziness "right".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With