Proposal: make throwIO and throw strict

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Proposal: make throwIO and throw strict

David Feuer
It's possible for code to throw an exception that itself throws an
imprecise exception. Such an exception is a bit tricky to catch. For
example:

import Control.Exception

strange = throwIO (undefined :: SomeException) `catch` \ex ->
  case () of
    _ | Just _ <- (fromException ex :: Maybe IOError) -> print "IOError"
      | otherwise -> print "Something else"

You might think that this would catch the exception and print
"Something else", but in fact it does not. If others think this is as
surprising as I do, then I think we should make throwIO and throw
strict, so an exception will never itself be bottom. Using

throwIO' !e = throwIO e

in the code above instead of throwIO allows the exception to be caught.

A more conservative approach might be to just force result of
toException before calling raise#, but this only works when users use
an explicit type signature to fix the expression type, rather than an
exception constructor.

David
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: make throwIO and throw strict

Eric Mertens
Forcing the exception to WHNF doesn't do anything to resolve any of the other bottom values you might attempt to force inside your exception handler contained inside the thrown exception value. I think that the current behavior makes sense as it exists now. I'd prefer not making throwIO more magical. The user of throwIO throwing a potentially undefined exception value should take care to evaluate the exception before throwing it if that is a concern.

Did this happen in some code somewhere that you discovered? It might be more compelling if we could see how this came up it some otherwise reasonable code.

Regards,
Eric Mertens

On Mon, Feb 27, 2017 at 12:42 PM David Feuer <[hidden email]> wrote:
It's possible for code to throw an exception that itself throws an
imprecise exception. Such an exception is a bit tricky to catch. For
example:

import Control.Exception

strange = throwIO (undefined :: SomeException) `catch` \ex ->
  case () of
    _ | Just _ <- (fromException ex :: Maybe IOError) -> print "IOError"
      | otherwise -> print "Something else"

You might think that this would catch the exception and print
"Something else", but in fact it does not. If others think this is as
surprising as I do, then I think we should make throwIO and throw
strict, so an exception will never itself be bottom. Using

throwIO' !e = throwIO e

in the code above instead of throwIO allows the exception to be caught.

A more conservative approach might be to just force result of
toException before calling raise#, but this only works when users use
an explicit type signature to fix the expression type, rather than an
exception constructor.

David
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries