
Bjorn Lisper
My current work includes [among other things] ways to eliminate this problem---that is, we may do a computation eagerly and defer or discard any errors.
What you basically have to do is to treat purely data-dependent errors (like division by zero, or indexing an array out of bounds) as values rather than events.
Indeed. We can have a class of deferred exception values similar to IEEE NaNs. [later]:
Beware that some decisions have to be taken regarding how error values should interact with bottom. (For instance, should we have error + bottom = error or error + bottom = bottom?) The choice affects which evaluation strategies will be possible.
Actually, as far as I can tell we have absolute freedom in this respect. What happens when you run the following little program? \begin{code} forever x = forever x bottomInt :: Int bottomInt = error "Evaluating bottom is naughty" + forever () main = print bottomInt \end{code} I don't know of anything in the Haskell language spec that forces us to choose whether to signal the error or diverge in this case (though it's clear we must do one or the other). Putting strong constraints on evaluation order would cripple a lot of the worker/wrapper-style optimizations that (eg) GHC users depend on for fast code. We want the freedom to demand strict arguments as early as possible; the consequence is we treat all bottoms equally, even if they exhibit different behavior in practice. This simplification is a price of "clean equational semantics", and one I'm more than willing to pay. -Jan-Willem Maessen jmaessen@mit.edu [PS - I've deliberately dodged the issue of program-level exception handling mechanisms and the like.]