Proposal: Extensible exceptions
lemming at henning-thielemann.de
Mon Jul 7 06:20:06 EDT 2008
On Sun, 6 Jul 2008, Isaac Dupree wrote:
> Henning Thielemann wrote:
>>> If your code divides by zero, you still want any "finally" or "bracket"
>>> clauses to get called before the program terminates.
>> A program which divides by zero is broken and must be fixed. A program
>> which divides by zero but cleans up a bit, is still broken and must be
>> fixed. Cleaning up may make things better, but may also make things worse!
> it can make things worse? (When cleanup is somehow significantly dependent
> on the buggy part of the code that led to the error? How often does that
An error is a programming error, often a stupid mistake where you wonder,
how this could happen. How do you predict how evil your mistakes are and
whether the assumptions you put into the cleanup routines are fulfilled?
> I appreciate how bugs in Haskell are much better-behaved than many
> languages. For finally-clauses, they should be called equally whether there
> is a legitimate IO exception (if you believe in such a thing; they're even in
> Haskell98 in a form), or a buggy-program exception, and there is no good
> reason to fail to call 'hClose' just because some pure code in some part of
> the program divided by zero.
As I answered to David, the file might well be deleted in the meantime.
Your code is buggy and then it may well be that the file is already
deleted. Maybe due to other "error handling code" that tried to recover
from the division by zero.
> This way, if my IO uses 'bracket' when it should, a bug in one part of the
> code is less likely to cause obscure bugs in entirely unrelated IO parts of
> the code. Exceptions are designed to be ubiquitous and always-possible...
That's especially unsatisfying. If you have to expect any exceptional
situation at every time, you can no longer concentrate on what you intend
to program. Instead, if I open a file I expect exceptions that are
specific to that operation, and I handle them. I do not expecct OpenGL
exceptions and not division by zero errors. With the design I proposed you
can easily see in the type signature what exceptions can occur in an
action (and btw. there is even no need to restrict this to IO, you can use
this for any monad, e.g. monad transforms of IO).
> especially when you consider asynchronous exceptions.
Do you mean the problem of 'readFile' raising an exception? I think we
already clarified on Haskell-Cafe how to solve that properly:
Instead of a signature like
readFile :: IO (Either ErrorMsg String)
the function should have a type like
readFile :: IO (String, Maybe ErrorMsg)
where the ErrorMsg is generated lazily when reading the file stops. If
the file could be read completely it is Nothing, otherwise it is (Just
errorMsg). The consumer of the file content can throw a regular exception
after consuming the content. There is no need for complicating the
exception handling mechanism.
> In fact it's possible to use these exception capabilities to isolate
> different parts of the program from each other's bugs so the whole thing
> doesn't crash: although that's when it becomes much closer to your assessment
> of "a hack". That "hack" still can be quite useful, of course, if you agree
> with the Awkward Squad paper. It depends whether modularity of bugs is part
> of your worldview? -- I'm glad Linux (and all other modern OS) isolates
> different processes' address spaces using MMU!
I'm glad about all tools to help debugging - but please keep debugging and
exception handling strictly separated!
Let me give another example. We have learned that 'head' and 'tail' are
evil, because they are undefined for some inputs. Using them we run into
the risk of forgetting some cases. It is better to use a function like
or to use 'case':
case xs of
 -> a
(_:ys) -> f ys
Now, if we take the perspective that exceptions and errors are
interchangeable, then we could also call 'tail' and catch the error in
case the input list is empty. Do you consider this a good application of
More information about the Libraries