
On Mon, Oct 18, 2010 at 2:14 PM, Paolo Losi
Thanks for you reply, Michael. See inline ...
On Mon, Oct 18, 2010 at 11:21 AM, Michael Snoyman
As an haskell newbie, I've got some questions on this matter.
Is it using ErrorT instead of extensible exeptions really necessary? I've read your comment stating that we cannot pass function arguments to Exceptions because of the Show class constraint. But is that really limiting? Wouldn't your use case (e.g. HTTP redirection in Yesod) be implementable with extensible exceptions?
I would guess that the rule of thumb would be not to mix extensible exception and ErrorT whenever it is possibile.
I've quickly read your post on inverting transformer stacks and, from my newbie point of view, I feel that the extra complexity isn't worth the gain.
I'm not sure why you think inverting the ErrorT monad is more complicated than MonadCatchIO: they're both doing basically the same thing. The difference is that MonadInvertIO does this generically for a whole class of functions, and therefore does it right.
I could have written MonadCatchIO, I could not have written InvertIO :-)
The typeclass itself is simple. It's the *instances* that are complicated. At least I find InvertIO to be not much more complicated on the instance side.
Anyway, it *is* theoretically possible to use extensible exceptions anywhere you would use ErrorT, but there's always a runtime hit in using runtime exceptions. Also, it's a difference in philosophy: coming from a language like Python or Ruby, it may feel natural to use exceptions for these kinds of cases. In Haskell, we try to make exceptions respect their name, and only use them in exceptional circumstances.
Is the performance penalty of using runtime exception so high? I would sacrifice some bits of performance for a more consistent error reporting / flow control. For the argument that Exceptions are for exceptional cases I'm totally with David MacIver [1]. I perfectly see the point of using ErrorT, but not when you need to handle runtime exceptions as well. As an haskell newbie I think that _THIS_, error handling strategies, is the single most troublesome point where some consistency (at least as a best practice) is really needed. I had hopes that extensible execptions could clarify the issue raised by [2] at least in "new" code...
The point here is that we want to treat these things very differently. Just take a look at the runHandler code in the Yesod.Handler module: runtime exceptions need to be wrapped up in an internal server error, whereas "Left" values from the ErrorT get "case"d on. I understand that all of this could be done with extensible exceptions, but that's really just taking something which is currently explicit and type-checkable and making it implicit. It really does seem to me to be a typical dynamic-versus-static issue. Michael