Re: Control.Exception
Jason Dagit wrote: On Tue, Nov 4, 2008 at 2:47 AM, Simon Marlow [EMAIL PROTECTED] wrote: Jason Dagit wrote: Thanks. This helps a lot. Mind if I put it somewhere, such as on the wiki? A good description of how to deal with exceptions would be great to have in the Haddock documentation for Control.Exception - would you (or someone else) like to write and submit a patch? Or failing that, just putting it on the wiki would be useful too. I don't mind submitting a patch. What is the URL of the repo I should download? http://darcs.haskell.org/packages/base and the file is Control/Exception.hs. Cheers, Simon ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Tue, Nov 4, 2008 at 2:47 AM, Simon Marlow [EMAIL PROTECTED] wrote: Jason Dagit wrote: Thanks. This helps a lot. Mind if I put it somewhere, such as on the wiki? A good description of how to deal with exceptions would be great to have in the Haddock documentation for Control.Exception - would you (or someone else) like to write and submit a patch? Or failing that, just putting it on the wiki would be useful too. I don't mind submitting a patch. What is the URL of the repo I should download? Thanks! Jason ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
Jason Dagit wrote: On Mon, Nov 3, 2008 at 6:24 AM, Simon Marlow [EMAIL PROTECTED] wrote: Jason Dagit wrote: On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow [EMAIL PROTECTED] wrote: Johannes Waldmann wrote: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? As long as you're aware that it is bad programming style. We deliberately didn't include an easy way to do this, because we want people to think about why they need to catch *all* exceptions (most of the time it's a bug). Since the above is bad form, what should I be doing? Could someone please provide some examples or point me at the list of exceptions that I can catch? What about catching multiple types of exceptions? Let's distinguish two kinds of exception handling: Thanks. This helps a lot. Mind if I put it somewhere, such as on the wiki? A good description of how to deal with exceptions would be great to have in the Haddock documentation for Control.Exception - would you (or someone else) like to write and submit a patch? Or failing that, just putting it on the wiki would be useful too. Cheers, Simon ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Tue, 04 Nov 2008 19:41:58 +0900, Duncan Coutts [EMAIL PROTECTED] wrote: action `catches` [ \(e :: ExitCode) - ... , \(e :: PatternMatchFail) - ... ] or just by using multiple catch clauses: action `catch` (\(e :: ExitCode) - ...) `catch` (\(e :: PatternMatchFail) - ...) I don't think those are equivalent. In the second case, the PatternMatchFail handler scopes over the ExitCode handler. I think Duncan forgot to write parens. According to Ian's example, here is an equivalent code. (action `catch` (\(e :: ExitCode) - ...)) `catch` (\(e :: PatternMatchFail) - ...) David is right. If the exit code handler throws a pattern match exception then the code behaves differently than the `catches` version. I see. I misunderstood the problem. Thanks, -- shelarcy shelarcyhotmail.co.jp http://page.freett.com/shelarcy/ ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
Jason Dagit wrote: On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow [EMAIL PROTECTED] wrote: Johannes Waldmann wrote: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? As long as you're aware that it is bad programming style. We deliberately didn't include an easy way to do this, because we want people to think about why they need to catch *all* exceptions (most of the time it's a bug). Since the above is bad form, what should I be doing? Could someone please provide some examples or point me at the list of exceptions that I can catch? What about catching multiple types of exceptions? Let's distinguish two kinds of exception handling: 1. Cleaning up. If you want to catch errors in order to clean up - release resources, remove temporary files, that sort of thing - then use bracket or finally. Behind the scenes, these catch all exceptions, but crucially they re-throw the exception after cleaning up, and they do the right block/unblock stuff for asynchronous exceptions. 2. Recovery. You want to catch certain kinds of exception in order to recover and do something else, e.g. when calling getEnv. In that case, I recommend using try or tryJust. tryJust (guard . isDoesNotExistError) $ getEnv HOME it's good practice to separate the filter (the kinds of exception you're catching) from the code to handle them, and that's what tryJust does. There's some subtelty here to do with whether you need to be in blocked mode to handle the exception or not: if you're handling an exception you expect to be thrown asynchronously, then you probably want to use catch instead of try, because then the handler will run in blocked mode. But be careful not to tail-call out of the handler, because then the thread will stay in blocked mode, which will lead to strange problems later. A bit more background is here: http://hackage.haskell.org/trac/ghc/ticket/2558 (hmm, perhaps exception handlers should be STM transactions. Then you wouldn't be able to accidentally tail-call out of the exception handler back into IO code, but you would be able to re-throw exceptions. Just a thought.) As for the kinds of exception you can catch, nowadays you can catch any type that is an instance of Exception. A good place to start is the list of instances of Exception in the docs: http://www.haskell.org/ghc/dist/stable/docs/libraries/base/Control-Exception.html#t%3AException although that only contains types defined by the base package. Others have commented on the backwards-compat issues, I don't have anything to add there. Cheers, Simon ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Mon, Nov 3, 2008 at 6:24 AM, Simon Marlow [EMAIL PROTECTED] wrote: Jason Dagit wrote: On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow [EMAIL PROTECTED] wrote: Johannes Waldmann wrote: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? As long as you're aware that it is bad programming style. We deliberately didn't include an easy way to do this, because we want people to think about why they need to catch *all* exceptions (most of the time it's a bug). Since the above is bad form, what should I be doing? Could someone please provide some examples or point me at the list of exceptions that I can catch? What about catching multiple types of exceptions? Let's distinguish two kinds of exception handling: Thanks. This helps a lot. Mind if I put it somewhere, such as on the wiki? As for the kinds of exception you can catch, nowadays you can catch any type that is an instance of Exception. A good place to start is the list of instances of Exception in the docs: http://www.haskell.org/ghc/dist/stable/docs/libraries/base/Control-Exception.html#t%3AException although that only contains types defined by the base package. Others have commented on the backwards-compat issues, I don't have anything to add there. Ah, but I had one more question that I don't think anyone has answered yet. That is, how to deal with multiple types of exceptions. Suppose, as a concrete example, that I was looking out for both ExitCode and PatternMatchFail exceptions. Maybe I'm being naive, but it seems like I'm in that situation again where I have to catch all and then check if fromException succeeds on either PatternMatchFile or ExitCode types. And then throw if it both give Nothing? Thanks! Jason ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Mon, Nov 3, 2008 at 9:34 AM, Jason Dagit [EMAIL PROTECTED] wrote: Ah, but I had one more question that I don't think anyone has answered yet. That is, how to deal with multiple types of exceptions. Suppose, as a concrete example, that I was looking out for both ExitCode and PatternMatchFail exceptions. Maybe I'm being naive, but it seems like I'm in that situation again where I have to catch all and then check if fromException succeeds on either PatternMatchFile or ExitCode types. And then throw if it both give Nothing? I haven't tried this, so it may not work: data MyException = MyArithException ArithException | MyIOException IOException deriving Typeable instance Exception MyExcpetion where toException (MyArithException e) = toException e toException (MyIOExcpetion e) = toException e fromException se = case fromException se of Just e - Just $ MyArithException e Nothing - case fromException se of Just e - Just $ MyIOException e _ - Nothing Then anyone can catch your exceptions by catching the ArithException or IOException as normal, and you can catch IOExceptions and ArithExceptions into your own custom type. -Antoine ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Mon, 2008-11-03 at 09:26 -0800, Sigbjorn Finne wrote: On 11/3/2008 07:34, Jason Dagit wrote: Ah, but I had one more question that I don't think anyone has answered yet. That is, how to deal with multiple types of exceptions. Suppose, as a concrete example, that I was looking out for both ExitCode and PatternMatchFail exceptions. Maybe I'm being naive, but it seems like I'm in that situation again where I have to catch all and then check if fromException succeeds on either PatternMatchFile or ExitCode types. And then throw if it both give Nothing? One way to do this now is to use Control.Exception.catches: catches :: IO a - [Handler a] - IO a data Handler a where Handler :: forall a e. (Exception e) = (e - IO a) - Handler a ie: action `catches` [ \(e :: ExitCode) - ... , \(e :: PatternMatchFail) - ... ] or just by using multiple catch clauses: action `catch` (\(e :: ExitCode) - ...) `catch` (\(e :: PatternMatchFail) - ...) Duncan ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On 11/3/2008 07:34, Jason Dagit wrote: Ah, but I had one more question that I don't think anyone has answered yet. That is, how to deal with multiple types of exceptions. Suppose, as a concrete example, that I was looking out for both ExitCode and PatternMatchFail exceptions. Maybe I'm being naive, but it seems like I'm in that situation again where I have to catch all and then check if fromException succeeds on either PatternMatchFile or ExitCode types. And then throw if it both give Nothing? One way to do this now is to use Control.Exception.catches: catches :: IO a - [Handler a] - IO a data Handler a where Handler :: forall a e. (Exception e) = (e - IO a) - Handler a --sigbjorn ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Mon, Nov 3, 2008 at 12:53 PM, Duncan Coutts [EMAIL PROTECTED] wrote: On Mon, 2008-11-03 at 09:26 -0800, Sigbjorn Finne wrote: One way to do this now is to use Control.Exception.catches: catches :: IO a - [Handler a] - IO a data Handler a where Handler :: forall a e. (Exception e) = (e - IO a) - Handler a ie: action `catches` [ \(e :: ExitCode) - ... , \(e :: PatternMatchFail) - ... ] or just by using multiple catch clauses: action `catch` (\(e :: ExitCode) - ...) `catch` (\(e :: PatternMatchFail) - ...) I don't think those are equivalent. In the second case, the PatternMatchFail handler scopes over the ExitCode handler. -- Dave Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Tue, 04 Nov 2008 07:40:50 +0900, David Menendez [EMAIL PROTECTED] wrote: ie: action `catches` [ \(e :: ExitCode) - ... , \(e :: PatternMatchFail) - ... ] or just by using multiple catch clauses: action `catch` (\(e :: ExitCode) - ...) `catch` (\(e :: PatternMatchFail) - ...) I don't think those are equivalent. In the second case, the PatternMatchFail handler scopes over the ExitCode handler. I think Duncan forgot to write parens. According to Ian's example, here is an equivalent code. (action `catch` (\(e :: ExitCode) - ...)) `catch` (\(e :: PatternMatchFail) - ...) http://www.haskell.org/pipermail/libraries/2008-July/010095.html Best Regards, -- shelarcy shelarcyhotmail.co.jp http://page.freett.com/shelarcy/ ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Mon, Nov 3, 2008 at 7:27 PM, shelarcy [EMAIL PROTECTED] wrote: On Tue, 04 Nov 2008 07:40:50 +0900, David Menendez [EMAIL PROTECTED] wrote: ie: action `catches` [ \(e :: ExitCode) - ... , \(e :: PatternMatchFail) - ... ] or just by using multiple catch clauses: action `catch` (\(e :: ExitCode) - ...) `catch` (\(e :: PatternMatchFail) - ...) I don't think those are equivalent. In the second case, the PatternMatchFail handler scopes over the ExitCode handler. I think Duncan forgot to write parens. According to Ian's example, here is an equivalent code. (action `catch` (\(e :: ExitCode) - ...)) `catch` (\(e :: PatternMatchFail) - ...) http://www.haskell.org/pipermail/libraries/2008-July/010095.html That's equivalent to the code without the parentheses, but it isn't equivalent to the code using catches. Assume we have exitCodeHandler :: ExitCode - IO () and pattternMatchHandler :: PatternMatchFail - IO (), 1. action `catches` [ Handler exitCodeHandler, Handler patternMatchHandler ] 2. (action `catch` exitCodeHandler) `catch` patternMatchHandler Let's further assume that action throws an ExitCode exception and exitCodeHandler throws a PatternMatchFail exception. In example 1, the PatternMatchFail exception thrown by exitCodeHandler is not caught by patternMatchHandler, but it in example 2 it is caught. In other words, patternMatchHandler is active during the evaluation of exitCodeHandler in example 2, but not in example 1. -- Dave Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/ ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
I think the best way to get backwards compatibility is to flesh out and use the extensible-exceptions package that Ian started, which models extensible exceptions on top of the old exception mechanism. Alternatively, you can decide not to use extensible exceptions and have your package depend on base-3 instead of base-4. For a library, however, I don't think there's a good solution, since most of the time changing the exception mechanism for the library will make the library incompatible with existing clients. I guess the best way to deal with this is to properly use the package versioning policy and hope that clients specify their dependencies precisely. 2008/11/2 Sigbjorn Finne [EMAIL PROTECTED]: (+1) to that request - what is the best practices for portable exception handling code that straddles version 6.10, i.e. that compiles with compilers at either side with minimal fuss? I can imagine a couple of alternatives, but would like to hear what others are doing here. thanks --sigbjorn likes backward code compatibility On 11/1/2008 18:15, Jason Dagit wrote: On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow [EMAIL PROTECTED] wrote: Johannes Waldmann wrote: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? As long as you're aware that it is bad programming style. We deliberately didn't include an easy way to do this, because we want people to think about why they need to catch *all* exceptions (most of the time it's a bug). Since the above is bad form, what should I be doing? Could someone please provide some examples or point me at the list of exceptions that I can catch? What about catching multiple types of exceptions? Thanks, Jason ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Sat, 2008-11-01 at 19:09 -0700, Sigbjorn Finne wrote: (+1) to that request - what is the best practices for portable exception handling code that straddles version 6.10, i.e. that compiles with compilers at either side with minimal fuss? I can imagine a couple of alternatives, but would like to hear what others are doing here. As far as I know there is no nice easy way to be compatible with both models. There's no subset you can stick to that works with both. In libraries like Cabal and other libs we've done things like: catchIO :: IO a - (Exception.IOException - IO a) - IO a #ifdef BASE4 catchIO = Exception.catch #else catchIO = Exception.catchJust Exception.ioErrors #endif catchExit :: IO a - (ExitCode - IO a) - IO a #ifdef BASE4 catchExit = Exception.catch #else catchExit = ... etc ... #endif The point is, the old catch deals with just one exception type, while the new one works with various kinds of specific exception types. So you'd need one of these ifdefs for each type of exception you're catching. The other alternative is to just keep using the base 3 exceptions for a while and switch next time your lib makes a major api change. If you need to switch to base 4 for other reasons you can use the Control.OldExceptions if you don't want to switch to the new exceptions at the same time. I don't know much about the extensible-exceptions package, I'll let someone else explain about that. I was initially rather annoyed that the api has changed to much that it was not possible to make code work nicely without using cpp. On the other hand, the new exceptions api is a good deal nicer to use and is much more easily extensible. The old dynamic exceptions stuff was horrible. We used it in gtk2hs to implement the detailed exceptions that glib/gtk throws, but it constantly confused users. The new api also encourages you not to do silly things like catching all exceptions, known and unknown like the previous api did. This is important now that we have things like ^C being exceptions. Duncan ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow [EMAIL PROTECTED] wrote: Johannes Waldmann wrote: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? As long as you're aware that it is bad programming style. We deliberately didn't include an easy way to do this, because we want people to think about why they need to catch *all* exceptions (most of the time it's a bug). Since the above is bad form, what should I be doing? Could someone please provide some examples or point me at the list of exceptions that I can catch? What about catching multiple types of exceptions? Thanks, Jason ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
(+1) to that request - what is the best practices for portable exception handling code that straddles version 6.10, i.e. that compiles with compilers at either side with minimal fuss? I can imagine a couple of alternatives, but would like to hear what others are doing here. thanks --sigbjorn likes backward code compatibility On 11/1/2008 18:15, Jason Dagit wrote: On Wed, Oct 8, 2008 at 1:19 AM, Simon Marlow [EMAIL PROTECTED] wrote: Johannes Waldmann wrote: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? As long as you're aware that it is bad programming style. We deliberately didn't include an easy way to do this, because we want people to think about why they need to catch *all* exceptions (most of the time it's a bug). Since the above is bad form, what should I be doing? Could someone please provide some examples or point me at the list of exceptions that I can catch? What about catching multiple types of exceptions? Thanks, Jason ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
Johannes Waldmann wrote: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? As long as you're aware that it is bad programming style. We deliberately didn't include an easy way to do this, because we want people to think about why they need to catch *all* exceptions (most of the time it's a bug). Cheers, Simon ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Control.Exception
with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' It is probably bad programming style anyway but what is the workaround? I found some references (in list emails) to catchAny, ignoreExceptions but these don't seem to have made it? Best regards, J.W. signature.asc Description: OpenPGP digital signature ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
2008/10/7 Johannes Waldmann [EMAIL PROTECTED]: with 6.10, the following does not typecheck: foo `Control.Exception.catch` \ _ - return bar Ambiguous type variable `e' in the constraint: `Control.Exception.Exception e' catch \(e :: SomeException) - ... This requires language ScopedTypeVariables (and perhaps PatternSignatures). Of cause, you should try to be more specific about which exceptions you want to catch as e.g., Ctrl-C and many other things are also reported as exceptions. It is probably bad programming style anyway but what is the workaround? I found some references (in list emails) to catchAny, ignoreExceptions but these don't seem to have made it? Best regards, J.W. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
catch \(e :: SomeException) - ... So, this changes the API (from 6.8 to 6.10)? I see there is Control.OldException (providing the old catch) but that still does not help me if I want my code compile with both 6.8 and 6.10. Is there some version of catch that works both ways? best regards, J.W. signature.asc Description: OpenPGP digital signature ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Tue, 2008-10-07 at 20:50 +0200, Johannes Waldmann wrote: catch \(e :: SomeException) - ... So, this changes the API (from 6.8 to 6.10)? I see there is Control.OldException (providing the old catch) but that still does not help me if I want my code compile with both 6.8 and 6.10. Is there some version of catch that works both ways? Build your package using base-3 rather than base-4. Duncan ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Control.Exception
On Tue, Oct 07, 2008 at 12:54:55PM -0700, Duncan Coutts wrote: On Tue, 2008-10-07 at 20:50 +0200, Johannes Waldmann wrote: catch \(e :: SomeException) - ... So, this changes the API (from 6.8 to 6.10)? I see there is Control.OldException (providing the old catch) but that still does not help me if I want my code compile with both 6.8 and 6.10. Is there some version of catch that works both ways? Build your package using base-3 rather than base-4. Another option would be for someone to fill out http://darcs.haskell.org/packages/extensible-exceptions/ so that it becomes a complete replacement. Currently it only has what we needed in GHC. Thanks Ian ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users