Simon L Peyton Jones <[EMAIL PROTECTED]> writes:
> Alastair Reid has been very quiet, [...]
Sorry about that - I just got back from a trip to Germany and am still
trying to catch up on my mail, get the June 98 (bugfix) release of Hugs
out the door, etc.
Exception handling has been high on "Why Haskell is a toy language" list
for quite a while now - so I'm very happy that Hugs, GHC and HBC will
all provide exception handling.
"S. Alexander Jacobson" <[EMAIL PROTECTED]> writes:
> As a matter of course, should we assume that these extensions
> (exceptions, existentials) will become part of Haskell or are they just
> part GHC? Will they be part of Hugs?
Hugs has had catchError (which is essentially the same as catch#)
for over a year now. We added it when we created the Graphics
library because we had to make sure that graphics programs
cleaned up after themselves even if they hit a pattern match error.
We'll replace/supplement catchError with catch in due course.
Existentials (and all the other goodies in Hugs 1.3c) will not be
in the June 98 Hugs release - but ought to be in the next one.
(Sorry about this - we're busy working on the Hugs-GHC merger,
generating deliverables for our funding bodies, putting
together new funding proposals, adding exception handling to
GHC, etc, etc. If someone could make a couple of clones of
Mark Jones or myself...)
Ralf Hinze <[EMAIL PROTECTED]> writes:
> The fact that the type of exceptions is fixed (`String' or `IOError')
> is a weak point of the design (compared to Standard ML).
This weakness is almost a design feature. Given the non-determinism
in which exception is raised in a program like this:
print ( (1 `div` 0) + (head []) )
we really don't recommend the construction of elaborate exception handlers
that try to figure out which exception was raised (as one might in Java
or ML).
That said, I've felt for a while thatthe fixed nature of the IOError type
was going to be a problem as we added new "actions" (such as openWindow
or sendEMail) to the IO monad. GreenCard 1 (but sadly not GC 2) allowed
you define new constructors for the IOError type. Given a declaration
(something) like this:
%exception Foo :: Int -> String -> IOError
it defined a function to construct an exception and a function to test
for an exception:
mkFoo :: Int -> String -> IOError
isFoo :: IOError -> Maybe (Int,String)
Koen Claessen <[EMAIL PROTECTED]> writes:
> How about adding the following errors:
>
> data IOError
> = ...
> | HeapOverflowError
> | StackOverflowError
>
> This is very useful when you for example want to implement a Hugs like
> system in Haskell.
Resource overflows (like timeouts and ctrl-C) are very different
beasts from pattern match failure and calls to error.
The main difference is that
1 `div` 0
always raises an exception - irrespective of what else is going on at the
time. If you evaluate 1 `div` 0 some other time, you'll still get an
exception. On the other hand, a large, stack and space hungry expression
like
sum [1..1000000]
might run out of heap/stack or may evaluate just fine depending on
a whole bunch of factors - even within the same run of the program.
The first kind of error has a tolerably straightforward domain theoretic
semantics (see Lennart's hbi paper for a first approximation) whereas
resource overflow errors can only be described in an operational semantics.
In the implementation, this difference manifests itself in things like
being able to revert black holes to their former state (but without the
space leak or duplicated work of a naive implementation) and other
such tweaking.
So they're different things, but since they're an essential part of trying
to lift Haskell out of Toyland, we will be doing it - possibly with the
interface you suggest. Stay tuned to the Hugs and GHC mailing lists...
"S. Alexander Jacobson" <[EMAIL PROTECTED]> writes:
> It would make debugging easier if the exception picked was consistent
> across implementations.
The semantics given doesn't even guarantee that you'll get the same exception
from the same implementation. Indeed, the same expression could even
raise different exceptions each time you evaluate it (though the
current implementation won't do this).
This "flaw" keeps the implementation simple and efficient because
it means that we can stop evaluating an expression and jump to the
handler the moment we hit the first raise#. All that talk of
sets of errors is just a semantic device to restrict the
non-determinism to the IO monad instead of letting it pollute the
whole system. (The idea is based on the Hughes-O'Donnell non-determinism
monad [1].)
Fixing this flaw would mean we'd have to keep evaluating even after we
hit the first error. This has two big problems:
1) I don't know how to implement it. :-)
2) If all you care about is that an error happened and that you can
print an error message on the screen or in a log file or whatever,
it's a huge waste of time hunting for the other errors, sorting them
into order, etc.
> If you can do the above and you can stay consistent about which exceptions
> you return then you should be able to catch exceptions in arbitrary purely
> function code as well, right?
Yes, the only reason we restrict catch# to the IO monad is because of the
non-determinism.
[1] RJM Hughes and J O'Donnell, Expressing and Reasoning about
Non-Deterministic Functional Programs, in Proceedings of the 1989 Glasgow FP
Workshop, Workshops in Computing Series, Springer Verlag, pp 308-329, 1989.
--
Alastair Reid Yale Haskell Project Hacker
[EMAIL PROTECTED] http://WWW.CS.Yale.EDU/homes/reid-alastair/