2 ms·
Thanks, that covers much of what I had in mind before. Error handling in Haskell seems to suffer from two fundamental problems. One is that there is a clash b
by Silhouette 9y ago
Thanks, that covers much of what I had in mind before.
Error handling in Haskell seems to suffer from two fundamental problems.
One is that there is a clash between non-strict evaluation and exceptions, as your first example illustrates. I understand the arguments about why throwing can be done in pure code but catching needs to be in IO in Haskell, but those reasons are consequence of other design decisions in Haskell. The asymmetry is awkward, and it feels like you can never quite trust pure functions to do what you expect. It's a little like the long-standing criticisms of exceptions in C++, except that at least in C++ idioms have evolved to compensate, whereas shoving everything behind one or another of the `catch` variants in Haskell feels very unidiomatic to me.
The other fundamental problem is that the different techniques for representing potential failure don't compose very elegantly. Given that flexible composition is arguably the biggest selling point of being lazy in the first place, that is unfortunate. The elegance gained from a language like Haskell in expressing tidy, pure code loses its shine a little if you then have to wrap a lot of real world code that calls out to other libraries to do things inside 17 levels of monad transformers, forced evaluations and catches.
Of course I'm not suggesting that these are new or insurmountable problems or that no-one can write reasonably safe code in Haskell or anything silly like that. But I do think some advocacy, as if the type system is borderline magical, can be rather idealistic, and sometimes overlooks the warts that also arise as a direct result of the decisions that made the language safer and more elegant in other respects.