Exceptions vs. Errors (Re: Readline read_history and write_history addition)

Henning Thielemann lemming at henning-thielemann.de
Wed Jan 23 06:14:07 EST 2008


On Wed, 23 Jan 2008, Yitzchak Gale wrote:

> Henning Thielemann wrote:
> > http://www.haskell.org/haskellwiki/Exception
> > http://www.haskell.org/haskellwiki/Error
>
> The exact usage of the terms "error" and "exception" varies
> between programming languages. Your descriptions on
> the wiki follow Java usage, where Error and Exception
> are separate subclasses of Throwable.

It's also terminology of Modula-3, from where Java inherits its exception
mechanism. And probably its the same terminology in the ancestors of
Modula-3.

> In Haskell, the usage is, let's just say, unusual. :) Perhaps some
> technolinguist will have a good time studying it some day.

It would be good if Haskell libraries would separate the two issues, with
whatever wording.

> I wrote:
> >> If we start throwing IO exceptions for common and minor
> >> occurrences like no readline history available, libraries like
> >> this become impossible to write in Haskell. And code
> >> that has already been written becomes unusable.
>
> > ...situations that cannot be avoided by the programmer
> > but must be handled. An approved method to handle these
> > cases are 'try' constructs.
>
> Approved? The question is: when is it appropriate to
> use this technique in Haskell? Every function that can
> return more than one possible value has "situations
> that must be handled", but usually we will not throw
> exceptions.

You know, in Haskell we do not need a built-in exception handling facility
because we can handle it with the elements of the language. Returning an
exceptional value or throwing an exception is the same. We can only hide
the exception propagation by appropriate binding of actions.

> > Now if 'bracket' does not work for general
> > MonadIO then it should be generalized.
>
> 'bracket', 'try', and 'catch' do need to be generalized.
> Realistically, that will not happen for a long time, if ever.

 Why not? We could design standard IO functions with improved API, with
exceptions explicitly declared in the type. (One could also get rid of
'hFunction' names and use module name qualification instead.) In the
future, when it becomes more usual to install a custom set of packages
from Hackage instead of installing a large set of base libraries, people
can more easily decide to use this library instead of System.IO.
 I think ByteString was long awaited and thus was adopted quickly by many
programmers. I hope this happens for other solutions, too.

> The reality is that Haskell's IO exception facilities have some
> rough edges.

 I remember that I read somewhere that the Haskell veterans regret to
having put so much things into IO, whenever they didn't know where to
place them correctly.  Exceptions are one such thing. Manipulating array
in-place is another example. Putting 'fail' method into the Monad class is
also acknowledged as a misconception today, and (I hope) most people
agree, that there should be a separate class MonadError.
 Solutions already exist. STArray monad and runST can replace IOArray and
unsafePerformIO in a safe way. Control.Monad.Error (which should be called
Control.Monad.Exception with a distinct type for exceptions instead of
Either) with ErrorT already allows to express in a type safe way what
exceptions an action can throw. Maybe one day we succeed keeping
exceptions completely out of IO and have them implemented by
ErrorT/ExceptionT.


More information about the Libraries mailing list