[Haskell-cafe] Re: [Haskell] ANNOUNCE: control-monad-exception 0.5 with monadic call traces

Nicolas Pouillard nicolas.pouillard at gmail.com
Mon Nov 9 03:56:05 EST 2009

Excerpts from Michael Snoyman's message of Sat Nov 07 22:55:14 +0100 2009:
> On Sat, Nov 7, 2009 at 9:54 PM, Henning Thielemann <
> lemming at henning-thielemann.de> wrote:
> >
> > On Sat, 7 Nov 2009, Jose Iborra wrote:
> >
> >  Sorry for the confusion, I never meant that c-m-e can show stack traces
> >> for asynchronous exceptions. It can not.
> >>
> >
> > My post was not related in any way to asynchronous exceptions. It's just
> > the everlasting issue of the distinction of programming errors and
> > exceptions.
> >
> >
> >  I'm not sure if I managed to dispel your doubts, if not perhaps you could
> >> make your points more clear.
> >>
> >
> > I'm trying that for years now, repeatedly in this mailing list and on the
> > Wiki:
> >  http://www.haskell.org/haskellwiki/Error
> >  http://www.haskell.org/haskellwiki/Exception
> >  I don't know how I can make it still clearer. It's just like concurrency
> > vs. parallelism - somehow related, but it is important to distinguish them.
> >
> > And yet if I use library ABC, which I expected to be error-free, and it in
> fact has a programming error, is this an error or an exception from my point
> of view? Based on the definitions you posted, I believe the correct answer
> is "error." However, I'd much rather have a way to recover from that kind of
> error if it's logical.
> For example, let's say that I'm writing a web browser in Haskell (it could
> happen). If there's an error in the HTTP library which causes it to die on
> certain types of headers, I'd much rather be able to tell the user sorry and
> let them continue browsing than to up and die with a "Prelude.head" message
> in their console.

If there is an "error" raised by the HTTP library on some headers, then this
is a bug (a programming error), and so by using it your program is buggy too.

However I would say that in this case wrapping the buggy function into
safely-failing one is a valid temporary hack.

A way to help distinguishing errors and exceptions would be to have pre and
post conditions on function (as in "Static Contract Checking for Haskell"[1]).

For instance head would have the following contract:

{-# CONTRACT head :: { xs | not (null xs) } -> Ok #-}
head :: [a] -> a
head []    = error "head: empty list"
head (x:_) = x

When there is a pre-condition (or a contract) like here, it
is a programming error to give an empty list to head.

This means that checking if the list is empty must be done before
the call. It has to statically deductible from the call site.

If you write a function and cannot prove that you will not call
head on the empty list then either you check before calling,
or you use a safe-head function or you add a pre-condition to
your function.

[1]: http://www.cl.cam.ac.uk/~nx200/

Nicolas Pouillard

More information about the Haskell-Cafe mailing list