Re: [Haskell-cafe] Errors in non-monadic code

jabolopes@google.com,
MIME-Version: 1.0
Content-type: text/plain; charset=UTF-8
In-Reply-To:
Even in IO, exceptions should be reserved for truly exceptional conditions (of the "program cannot safely continue" variety), not merely for error checking when this can be described as a normal flow of evaluation. Exceptions are not simply alternative flow of control, even in procedural languages; they are *disruptions* of flow of control.
I think that would be debatable, especially as applied to procedural languages in general. It's very common to use exceptions in routine flow of control in Python programs, if I remember right. Meanwhile, the Haskell library in my opinion somewhat weakens your case by making ordinary conditions into exceptions, for example end-of-file. In the end it's a large grey area. Ideally, what the program has to do, or whether it can even continue at all, is determined by the program using information reported by the function that encounters the error. If there's a good reason why exceptions should be used only when the program won't be able to continue, it must be that the language's exception handling facililty isn't very robust. Donn

I agree that whether to use exceptions or not is a very debatable subject and it is a grey area. Still, in your Python example, I would like to point out that just because something is common, it does not mean it is the right thing to do. For example, something that some Java programmers were doing a lot was to loop through an array and, instead of using a counter, they were catching the array out of bounds exception. This is clearly not the right thing to do! But I would like to see more code move away from exceptions and into types like "Maybe" or "Either" or other types defined for the particular situation (as some people were suggesting in the beginning of the thread). And the reason for this it is because when you program against types you have to make a decision whether to handle the error or let it bleed through: you can't ignore the choice because you can't ignore the type. On the other hand, with exceptions, you can easily forget to handle the exception if you're not looking at the documentation at the time when you write the code. Jose On Mon, Aug 19, 2013 at 01:12:13PM -0700, Donn Cave wrote:
jabolopes@google.com, MIME-Version: 1.0 Content-type: text/plain; charset=UTF-8 In-Reply-To:
References: quoth Brandon Allbery,
Even in IO, exceptions should be reserved for truly exceptional conditions (of the "program cannot safely continue" variety), not merely for error checking when this can be described as a normal flow of evaluation. Exceptions are not simply alternative flow of control, even in procedural languages; they are *disruptions* of flow of control.
I think that would be debatable, especially as applied to procedural languages in general. It's very common to use exceptions in routine flow of control in Python programs, if I remember right. Meanwhile, the Haskell library in my opinion somewhat weakens your case by making ordinary conditions into exceptions, for example end-of-file.
In the end it's a large grey area. Ideally, what the program has to do, or whether it can even continue at all, is determined by the program using information reported by the function that encounters the error. If there's a good reason why exceptions should be used only when the program won't be able to continue, it must be that the language's exception handling facililty isn't very robust.
Donn
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Mon, Aug 19, 2013 at 05:15:39PM -0400, jabolopes@google.com wrote:
But I would like to see more code move away from exceptions and into types like "Maybe" or "Either" or other types defined for the particular situation (as some people were suggesting in the beginning of the thread). And the reason for this it is because when you program against types you have to make a decision whether to handle the error or let it bleed through: you can't ignore the choice because you can't ignore the type. On the other hand, with exceptions, you can easily forget to handle the exception if you're not looking at the documentation at the time when you write the code.
This is /exactly/ the reason to avoid exceptions where possible. Tom

On Mon, Aug 19, 2013 at 5:24 PM, Tom Ellis < tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
On Mon, Aug 19, 2013 at 05:15:39PM -0400, jabolopes@google.com wrote:
But I would like to see more code move away from exceptions and into types like "Maybe" or "Either" or other types defined for the particular situation (as some people were suggesting in the beginning of the thread). And the reason for this it is because when you program against types you have to make a decision whether to handle the error or let it bleed through: you can't ignore the choice because you can't ignore the type. On the other hand, with exceptions, you can easily forget to handle the exception if you're not looking at the documentation at the time when you write the code.
This is /exactly/ the reason to avoid exceptions where possible.
Tom
And tangentially related, it's why Go uses error return values (with functions being able to "return multiple values"), e.g. http://blog.golang.org/error-handling-and-go

jabolopes@google.com :
I would like to see more code move away from exceptions and into types like "Maybe" or "Either" or other types defined for the particular situation (as some people were suggesting in the beginning of the thread). And the reason for this it is because when you program against types you have to make a decision whether to handle the error or let it bleed through: you can't ignore the choice because you can't ignore the type. On the other hand, with exceptions, you can easily forget to handle the exception if you're not looking at the documentation at the time when you write the code.
Tom Ellis:
This is/exactly/ the reason to avoid exceptions where possible.
I disagree. Types which neutralize some particular conditions (whether you call them exceptional or not is conventional) and propagate "Nothing" etc. is not a panacea. Some exceptions, e.g. in the traversal of deep structures may be and ARE used as escaping continuations. Calling all that "not the right thing to do", or issuing other normative statements is, how would I express it... , is not the right thing to do. Now you can add here some dozen smileys... More seriously, some people like exquisite continuations and will use them. Instead of fighting against exceptions it might be more fruitful to make them more robust, powerful, parametrable and sexy. Jerzy Karczmarczuk

Some exceptions, e.g. in the traversal of deep structures may be and ARE used as escaping continuations.
If I understand correctly, by "escaping continuations" you mean that you can easily transfer control between the point where the exception is raised and the exception handler. If this is what you mean, you can achieve the same effect with monadic code by chaining monads together, for example, you can have your structure traversal code as several 'Maybe' functions. And if I understand correctly the underlying technical details of Haskell, because of continuation-passing style, the "control transfer" should be simpler because it comes down to invoking the proper continuation, so all of that code that compilers have to generate to look into the stack and find the proper exception handler, and unwind the stack and transfer control, is avoided. Jose

Le 20/08/2013 00:19, jabolopes@google.com a écrit :
If I understand correctly, by "escaping continuations" you mean that you can easily transfer control between the point where the exception is raised and the exception handler.
If this is what you mean, you can achieve the same effect with monadic code by chaining monads together
Yes. José, this is mainly the question of efficiency. You don't need to establish contact between the distant stack frames, and you may propagate failures if this happens seldom. But if the escaping continuation is a frequent case, it might be more economic to "jump". This is as simple as that. Jerzy Karczmarczuk

On Tue, Aug 20, 2013 at 12:25:44AM +0200, Jerzy Karczmarczuk wrote:
Le 20/08/2013 00:19, jabolopes@google.com a écrit :
If I understand correctly, by "escaping continuations" you mean that you can easily transfer control between the point where the exception is raised and the exception handler.
If this is what you mean, you can achieve the same effect with monadic code by chaining monads together
José, this is mainly the question of efficiency. You don't need to establish contact between the distant stack frames, and you may propagate failures if this happens seldom. But if the escaping continuation is a frequent case, it might be more economic to "jump". This is as simple as that.
That's all very well, in which case I wish implementors of such code would wrap their possibly-exception-throwing values in a newtype ThisMightThrowAnException a = ThisMightThrowAnException a monad. Then at least we'd all know. Tom
participants (5)
-
Donn Cave
-
jabolopes@google.com
-
Jerzy Karczmarczuk
-
Patrick Mylund Nielsen
-
Tom Ellis