[Haskell-cafe] Re: Extensible Exceptions and IO

Alexander Dunlap alexander.dunlap at gmail.com
Sat May 23 16:02:15 EDT 2009


On Sat, May 23, 2009 at 9:09 AM, Ian Lynagh <igloo at earth.li> wrote:
> On Sat, Apr 25, 2009 at 11:18:43AM -0700, Alexander Dunlap wrote:
>> In the extensible exceptions paper[1], which I believe is the guide
>> behind the current Control.Exception in GHC 6.10, a SomeIOException
>> type is discussed so that it would be possible to use the nice
>> interface for IOExceptions. Is this implemented anywhere? In the GHC
>> libraries, all I see is the old interface just plugged into a simple
>> wrapper, so you have to use guard . isDoesNotExistError (for example)
>> with catchJust to catch a certain type of exception. If not, are there
>> any plans to implement it?
>
> I'm not aware of anyone currently working on putting the various core
> libs' exceptions into a sensible hierarchy, but it would be great if
> someone was to do so!
>
> I'd suggest that the best way to do this would be initially a
> combination of discussions on the mailing list (if anything is
> non-obvious) and building a design (and, if appropriate, rationale) on a
> wiki page, and ending with a library submissions proposal once you have
> a design worked out:
>
> http://www.haskell.org/haskellwiki/Library_submissions
>
>
> Thanks
> Ian
>
>

I'm moving this from the GHC users' mailing list to the haskell-cafe
mailing list because I think the discussion probably involves the
entire Haskell community.

Hi all,

We have this new exception hierarchy in GHC base-4 and a lot of new
machinery for dealing with it. Other libraries also seem to be
springing up to provide alternative methods of dealing with these new
exceptions.

However, I have found that in most of my programming, the new
exception functionality cannot be used to its fullest extent because
the exceptions in the core libraries are not part of any sensible
"tree" of exceptions, even though having this giant exception tree
seems to be one of the premises of the new exception library.

For example, there is an ArithException type in Control.Exception
which records various arithmetic exceptions. However, there are two
problems: (1) in order to fit in with the extensible exceptions theme,
the type ought to be called SomeArithException and all of the types of
ArithExceptions ought to be sub-exceptions of it, and (2) to my
knowledge, this exception type doesn't seem to be thrown by anything
in the base libraries.

I think the biggest culprit is the IOException type, which also
happens to be probably the most commonly-used exception type, since
exceptions from IOException cannot really be anticipated and
prevented.

The current design of IOException is as follows. There is an abstract
type called IOException. This can be queried with functions like
isDoesNotExistError (which determines if the exception is because a
file did not exist). Furthermore, to make an IOException, one has to
use the mkIOError function, which takes a value of type IOErrorType,
which is again an abstract type. I believe the reason for the abstract
types is to allow implementations to extend the range of exceptions.
Unfortunately, this has even more problems. For example, the error
returned by using readFile on a directory cannot be determined using
any Haskell98 function, meaning that code that wants to detect this
error cannot be portable to compilers that don't have the new
InappropriateType IO exception.

The biggest problem with the current design of IOException, however,
is that it doesn't play very nicely with the main hierarchy. Like with
ArithExceptions, there should be a SomeIOException type.
http://www.haskell.org/~simonmar/papers/ext-exceptions.pdf, which was
the original paper on extensible exceptions, recommends having a class
for IOExceptions that would allow us to get standard information from
any specific IOException.

I asked the GHC-users mailing list about this and Ian Lynagh
recommended starting a discussion about how to put all of the core
library exceptions into a sensible hierarchy.

I think the goals here ought to be to make our new hierarchy as
backward-compatible as possible. In particular, since many programs
rely on the isWhateverError functionality, it would be nice to keep
these in place.

For IOExceptions, I think it would be nice to have a more
multi-layered hierarchy than just SomeIOException and its subtypes.
For example, I could see a hierarchy for IOExceptions looking
something like this:

SomeIOException
  - SomeCouldNotOpenException
    - AlreadyExists, NoSuchThing, PermissionDenied, InappropriateType
  - SomeResourceException
    - ResourceBusy, ResourceExhausted, ResourceVanished

etc.

I'm not all that familiar with the various exceptions and how they are
used, so I'm not really able to propose a complete hierarchy for all
the exceptions. I guess the purpose of this email was just to start
off a discussion about what our exception hierarchy ought to look
like.

Thanks for reading this (admittedly long) message.

Alex


More information about the Haskell-Cafe mailing list