> I'd be interested to know what people think of this.
> Here's a reasonable design for exceptions in Haskell:
> ...
> The neat thing about this is that the exceptions can
> be *raised* in arbitrary purely functional code, without
> violating referential transparency. The question of
> which exception is chosen is done in the IO monad, where
> of course it is allowed to be non-deterministic.
> The implementation does not keep sets of exceptional values,
> of course. It simply propagates the first one it trips
> over to the nearest enclosing handler.
That's neat indeed. What is especially nice is the ability
to catch `error' exceptions.
> We're implementing an experimental version of this
> in GHC, integrated with the IO monad exceptions, so that
>
> handle :: (IOError -> IO a) -> IO a -> IO a
>
> and we add an extra constructor (UserError String) to the
> IOError type for exceptions raised by raise).
The fact that the type of exceptions is fixed (`String' or `IOError')
is a weak point of the design (compared to Standard ML). It forces the
programmer to encode exceptions as strings which is not what I would
call elegant. [I weakly recall that there was a discussion on this
point some years ago.] However, I see no way to improve the design :-(
other than extending Haskell (with extensible sum types a la SML's
`exception' declaration).
> One merit of the system is that it chops out a tremendous
> number of run-time error checks in the IO monad, since
> we are now free to implement the mechanism with standard
> stack-unwinding techniques. Result: much better I/O performance.
I love performance gains ;-).
Cheer, Ralf