Error Handling

Fergus Henderson fjh@cs.mu.OZ.AU
Fri, 13 Dec 2002 19:39:25 +1100


On 10-Dec-2002, Alastair Reid <alastair@reid-consulting-uk.ltd.uk> wrote:
> 
> On Sun, 8 Dec 2002, John Meacham wrote: (snip)
> >> throw (userException "foo") + throw (userException "bar")
> >> 
> >> without defining an evaluation order you cannot know which
> >> exepction is to be thrown. catching the exception in the IO monad
> >> makes this 'okay'
> > (snip)
> 
> Mark Carroll <mark@chaos.x-philes.com> writes:
> > Would it help if you defined an order over the possible exceptions,
> > then if one is thrown you evaluate other parts of the expression to
> > see if they also threw one, and return the "first" according to the
> > ordering? I still haven't given up my hope for simple exceptions
> > without monads. (-:
> 
> To do this, we have to actually build the set of all exceptions that
> an expression could raise.  This could take quite a while to build
> (lots more evaluation may need to be done)

[playing devil's advocate for a moment]

The set of all exceptions only needs to be built if an exception is
actually raised.  If no exception is raised, couldn't the code run just
as fast as it currently does in Haskell?

(My answer: yes, in theory it could; but only at the cost of major
code bloat in the generated code and major increases in the degree of
complication of the compiler.  It's not worth the trade-off.)

> and getting any one
> exception probably isn't going to be any more useful than the 'random'
> choice you get at present.

The advantage of what Mark Carroll was suggesting is not that you would
get a more useful exception, just that you get a more predictable one,
and that you don't need to use Monads.

(My response: the potential advantages of more deterministic behaviour
and [slightly] reduced need to use Monads would be outweighed by the
drawbacks mentioned above, i.e. code bloat and compiler complexity.)

> And even this wouldn't get rid of the monads since the problem monads
> deal with is present even if we can't observe the exceptions.  For
> example, a simple operation like this:
> 
>   choose :: a -> a -> a
> 
> which returns its first argument if it can evaluate its argument to
> WHNF without raising an exception and returns its 2nd argument
> otherwise has severe semantic problems.

That depends on what kind of exceptions you are trying to catch,
doesn't it?  If you need to catch out-of-memory errors (e.g.
stack overflow or heap overflow), yes, that would cause semantic
problems.  Likewise for asynchronous exceptions/signals such as
time-outs or user interrupts.  But if `choose' is only catching
exceptions raised by explicit calls to "throw" or "error", then
I think it would be semantically OK, wouldn't it?

(Still, most of the time you probably do want to handle those kinds of
errors -- at least the out-of-memory case, anyway -- so most of the
time you'd still need Monads.)

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.