Re: [Haskell-cafe] Re: New Hackage category: Error Handling
Michael Snoyman schrieb: On Mon, Dec 7, 2009 at 5:30 AM, Ben Franksen ben.frank...@online.de mailto:ben.frank...@online.de wrote: Michael Snoyman wrote: On the other hand, what's so bad about treating errors as exceptions? If instead of the program crashing on an array-out-of-bound or pattern-match it throws an exception which can be caught, so what? The error gets hidden instead of fixed? Cheers Ben You're right; bad programmers could do this. A good programmer will know to do one of two things when it gets an exception it does not know how to handle: It is certainly not the task of a programming language or a library to parent its users. Despite an interesting idea, it will not work, since programmers will simply switch to a different language or library if they feel pushed around. There is an important reason to not simply catch an error and proceed as if it were only an exception: The error might have corrupted some data and there is no general way to recover from that. Say, after detecting an error you might want to close a file that you were working on. But since you are coping with an error, something you did not foresee, you cannot tell whether the file was already closed again or never opened. So it is better to just abort the program. The next higher level, the shell calling your program or the browser calling your plugin, might have registered what have opened and allocated and can reliably free those resources. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Mon, Dec 7, 2009 at 2:13 PM, Henning Thielemann lemm...@henning-thielemann.de wrote: Michael Snoyman schrieb: On Mon, Dec 7, 2009 at 5:30 AM, Ben Franksen ben.frank...@online.de mailto:ben.frank...@online.de wrote: Michael Snoyman wrote: On the other hand, what's so bad about treating errors as exceptions? If instead of the program crashing on an array-out-of-bound or pattern-match it throws an exception which can be caught, so what? The error gets hidden instead of fixed? Cheers Ben You're right; bad programmers could do this. A good programmer will know to do one of two things when it gets an exception it does not know how to handle: It is certainly not the task of a programming language or a library to parent its users. Despite an interesting idea, it will not work, since programmers will simply switch to a different language or library if they feel pushed around. How did you get from what I said that I have any desire to parent users of a language? I think my sentiment is clear: a bad programmer will do bad things with any tool. I don't care about how a bad programmer might screw things up. In fact, I think your ideas are much more likely to give the feeling of being pushed around. The only opinion I've stated so far is that it's ridiculous to constantly demand that people follow your definition of error vs exception, since the line is incredibly blurry and it buys you very little. However, my opinion on what libraries should do is simple: Provide a simple, uniform interface for receiving both errors and exceptions, and let the library user decide what to do with them. If they are unhandable, then don't handle them; if a user *does* handle something which can't be dealt with, they fall into the over-defensive bad programmer category and I don't care. Otherwise, it gives people the flexibility that they need in all cases. I think under no circumstances* should a library simply terminate a runtime because it decides to. This is one of the great things of being able to catch all errors. * Of course, there are no absolutes. Ever. Not a single one. There is an important reason to not simply catch an error and proceed as if it were only an exception: The error might have corrupted some data and there is no general way to recover from that. Say, after detecting an error you might want to close a file that you were working on. But since you are coping with an error, something you did not foresee, you cannot tell whether the file was already closed again or never opened. So it is better to just abort the program. The next higher level, the shell calling your program or the browser calling your plugin, might have registered what have opened and allocated and can reliably free those resources. And what if you're calling a library in the same runtime? I think you are conflating the idea of treating errors as exceptions, which I think is a good one, and not letting there be any distinction between errors and exceptions, which is a bad one. The fact that I can use Control.Exception.catch to catch either errors or exceptions, but I can differentiate based on the data type, is IMO a great solution to this issue. I also believe that the failure package is a better** solution to the problem, because it makes it exceedingly clear which error/exception might have occurred. ** Of course, failure cannot handle a lot of what IO exceptions can, so it's a silly comparison in general. However, for the purpose of good error/exception handling, I think it's a better solution. Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: New Hackage category: Error Handling
On Mon, 7 Dec 2009, Michael Snoyman wrote: The only opinion I've stated so far is that it's ridiculous to constantly demand that people follow your definition of error vs exception, since the line is incredibly blurry and it buys you very little. If you have an example that is not contained in my article on the Haskell Wiki, where you think the error vs. exception distinction is not appropriate, please let me know and will think about it. http://www.haskell.org/haskellwiki/Error_vs._Exception ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: New Hackage category: Error Handling
On Mon, Dec 7, 2009 at 9:07 PM, Henning Thielemann lemm...@henning-thielemann.de wrote: On Mon, 7 Dec 2009, Michael Snoyman wrote: The only opinion I've stated so far is that it's ridiculous to constantly demand that people follow your definition of error vs exception, since the line is incredibly blurry and it buys you very little. If you have an example that is not contained in my article on the Haskell Wiki, where you think the error vs. exception distinction is not appropriate, please let me know and will think about it. http://www.haskell.org/haskellwiki/Error_vs._Exception I think it's a silly, unnecessary distinction. Sure, when you're teaching beginning programmers how to deal with out-of-bounds versus file not found, you can use the terminology. But as far as insisting that library authors have their programs die on an error, it's pointless. Having errors thrown as their own type of exception (like AssertionFailed, for example) is a much more resilient option, and for decent programmers who understand they shouldn't just catch every exception and return a default value, there is no downside. I don't care to make systems less resilient to deal with the sub-par programmer. I turn it around: give me an example where it's better for the runtime to exit than for some type of exception to be thrown, and *I'll* think about it ;). Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: New Hackage category: Error Handling
I turn it around: give me an example where it's better for the runtime to exit than for some type of exception to be thrown, and *I'll* think about it ;). If you would have read my article, you had one ... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: New Hackage category: Error Handling
On Mon, 7 Dec 2009, Michael Snoyman wrote: I actually *did* read your article, and don't know what you are referring to. If this is true, sorry, I didn't had the impression. I also think that in an earlier mail I answered, that errors can leave you with corrupt data, say invalid file handles, memory pointers, or data structures that violate invariants. You won't like to close files from invalid file handles and free memory from corrupt pointers or run into infinite loops by traversing the corrupt data structures. That's the reason why it is better to stop execution of the program and hand over control to the next higher level, say the shell or the web browser, that can free resources safely. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: New Hackage category: Error Handling
On Mon, Dec 7, 2009 at 9:53 PM, Henning Thielemann lemm...@henning-thielemann.de wrote: On Mon, 7 Dec 2009, Michael Snoyman wrote: I actually *did* read your article, and don't know what you are referring to. If this is true, sorry, I didn't had the impression. I also think that in an earlier mail I answered, that errors can leave you with corrupt data, say invalid file handles, memory pointers, or data structures that violate invariants. You won't like to close files from invalid file handles and free memory from corrupt pointers or run into infinite loops by traversing the corrupt data structures. That's the reason why it is better to stop execution of the program and hand over control to the next higher level, say the shell or the web browser, that can free resources safely. Firstly: I'm really referring exclusively to non-FFI Haskell programs, to which most of the issues you mention don't really apply. Nonetheless, I think that for a language with exceptions, it still makes sense to use the exceptions in these cases. In all these cases, I think the correct thing is to have a specific exception type that is thrown that signals that it is such an unrecoverable error. This allows the programmer to do *whatever* they want. Perhaps they want to save some other data to a file before exiting? Perhaps they want to spawn a process to send in a bug report? Who knows. It doesn't matter. The point is, the user *might* want to do something, and exceptions let them do it if they wish, or they can completely ignore that specific exception type and let the program crash anyway. Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
When I was working at Quintus, I came up with a classification which I can simplify something like this: operating system fault Something bad happened (like a remote node going down) that was entirely out of your control. There is nothing you can do to your program to prevent this. Example: power failure. It's still your problem to clean up on your way out. resource faults your program tried to do something possibly meaningful but the system ran out of some kind of resource (cpu limit, memory limit, disc quota, c) You might respond to this by increasing the limit and trying again. representation faults your program tried to do something meaningful but the system was unable to represent the result (integer overflow, upper case of ÿ in a Latin 1 system, floating point overflow on a non-IEEE system, c) Your program isn't *wrong* but you will still have to change it. existence errors Your program tried to do something with a (typically external) resource that doesn't exist (missing file) Your program could be wrong but probably isn't. You will have to create the resource or provide a different name. permission errors Your program tried to do something to a (typically external but not always) resource that you do not have permission to do (typically writing to a read-only file) You may have named the wrong resource. If not, you may have to get the permissions for the resource changed, or ask someone else to run the program. domain errors A precondition on the input arguments of an operation was not satisfied (e.g., X/0, sqrt(-1), malformed file name, head []). Your program is definitely wrong. postcondition errors Your program invoked some operation and the precondition for the operation was satisfied, but when it completed, the postcondition was not. The operation you invoked is broken. If it's yours, you will have to fix it. If the precondition was not strong enough, it may be your program at fault. Otherwise, until you can get a fix from someone, you will have to program around it. I didn't find a simple error/exception distinction helpful, and still don't. Take the case of trying to write to /dev/nul. This is a permission error. If the program is responsible for the name being what it is, it's a mistake in the program. If the user typed the name in, it's the user's mistake. You really can't tell without tracing each value to its origin. I dare ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: New Hackage category: Error Handling
Michael Snoyman wrote: On Mon, Dec 7, 2009 at 9:53 PM, Henning Thielemann lemm...@henning-thielemann.de wrote: On Mon, 7 Dec 2009, Michael Snoyman wrote: I also think that in an earlier mail I answered, that errors can leave you with corrupt data, say invalid file handles, memory pointers, or data structures that violate invariants. You won't like to close files from invalid file handles and free memory from corrupt pointers or run into infinite loops by traversing the corrupt data structures. That's the reason why it is better to stop execution of the program and hand over control to the next higher level, say the shell or the web browser, that can free resources safely. Firstly: I'm really referring exclusively to non-FFI Haskell programs, to which most of the issues you mention don't really apply. Nonetheless, I think that for a language with exceptions, it still makes sense to use the exceptions in these cases. In all these cases, I think the correct thing is to have a specific exception type that is thrown that signals that it is such an unrecoverable error. This allows the programmer to do *whatever* they want. Perhaps they want to save some other data to a file before exiting? Perhaps they want to spawn a process to send in a bug report? Who knows. It doesn't matter. The point is, the user *might* want to do something, and exceptions let them do it if they wish, or they can completely ignore that specific exception type and let the program crash anyway. Michael, Henning There are two meanings to the word 'exception' in this context; both of you tend to conflate these different meanings. One meaning is about a *mechanism* for non-local control flow; the other is about certain classes of un-desired program conditions. Michael, you are above arguing that it is ok to use the same /mechanism/ to signal errors and exceptions. That is ok with me. There are certainly good use cases, you have presented a few. However, that does not mean it is 'silly' or 'unnecessary' to distinguish between program(-mer) errors and other kinds of expected exceptional conditions in general, as you claimed in a previous message. I agree with Henning insofar as I think it is important to make the *conceptual* distinction -- regardless of whether we use the same mechanism to signal (and, perhaps, after serious consideration, handle) them. So, maybe it would help if we could agree to use different terms for those two meanings of the word 'exception'. I think 'exception' is too strongly associated with the non-local control flow mechanism to introduce a new word for it. Henning, what about calling an undesired but expected condition a 'failure' instead of an exception, so we could reserve this word for the language mechanism? Calling something a 'failure' in this sense (i.e. in contrast to 'error') would always include some judgement, as it needs to take the different program levels into account. Cheers Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Tue, 8 Dec 2009, Richard O'Keefe wrote: When I was working at Quintus, I came up with a classification which I can simplify something like this: It's certainly possible to classify errors and exceptions in other (also more fine grained) ways ... operating system fault Something bad happened (like a remote node going down) that was entirely out of your control. There is nothing you can do to your program to prevent this. Example: power failure. It's still your problem to clean up on your way out. This is an exception. Of course, if the machine your program runs on goes out of power, then neither exception handling nor debugging will help. resource faults your program tried to do something possibly meaningful but the system ran out of some kind of resource (cpu limit, memory limit, disc quota, c) You might respond to this by increasing the limit and trying again. An exception. representation faults your program tried to do something meaningful but the system was unable to represent the result (integer overflow, upper case of ÿ in a Latin 1 system, floating point overflow on a non-IEEE system, c) Your program isn't *wrong* but you will still have to change it. It is the responsibility of the programmer to choose number types that are appropriate for the application. If I address pixels on a todays screen I will have to choose at least Word16. On 8-bit computers bytes were enough. Thus, this sounds like an error. existence errors Your program tried to do something with a (typically external) resource that doesn't exist (missing file) Your program could be wrong but probably isn't. You will have to create the resource or provide a different name. Exception permission errors Your program tried to do something to a (typically external but not always) resource that you do not have permission to do (typically writing to a read-only file) You may have named the wrong resource. If not, you may have to get the permissions for the resource changed, or ask someone else to run the program. Exception domain errors A precondition on the input arguments of an operation was not satisfied (e.g., X/0, sqrt(-1), malformed file name, head []). Your program is definitely wrong. X/0, sqrt(-1), head [] are errors Malformed constant file name in your program is an error but it will raise an exception. The fix is to correct the filename, but you will still need the exception handling, since also the file with the correct name might not exist. postcondition errors Your program invoked some operation and the precondition for the operation was satisfied, but when it completed, the postcondition was not. The operation you invoked is broken. If it's yours, you will have to fix it. If the precondition was not strong enough, it may be your program at fault. Otherwise, until you can get a fix from someone, you will have to program around it. This is an error. Take the case of trying to write to /dev/nul. This is a permission error. If the program is responsible for the name being what it is, it's a mistake in the program. If the user typed the name in, it's the user's mistake. You really can't tell without tracing each value to its origin. Sure, the distinction exception/error depends on the source of the data that causes problems.___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Dec 8, 2009, at 12:28 PM, Henning Thielemann wrote: representation faults your program tried to do something meaningful but the system was unable to represent the result (integer overflow, upper case of ÿ in a Latin 1 system, floating point overflow on a non-IEEE system, c) Your program isn't *wrong* but you will still have to change it. It is the responsibility of the programmer to choose number types that are appropriate for the application. If I address pixels on a todays screen I will have to choose at least Word16. On 8-bit computers bytes were enough. Thus, this sounds like an error. That kind of attitude might have done very well in the 1960s. In an age when Intel have demonstrated 48 full x86 cores on a single chip, when it's possible to get a single-chip DSP with 240 cores that's fast enough to *calculate* MHz radio signals in real time, typical machine-oriented integer sizes run out _really_ fast. For example, a simple counting loop runs out in well under a second using 32-bit integers. The programmer doesn't always have the information necessary to choose machine-oriented integer sizes. Or it might not offer a choice. Or the choice the programmer needs might not be available: if I want to compute sums of products of 64-bit integers, where are the 128-bit integers I need? domain errors A precondition on the input arguments of an operation was not satisfied (e.g., X/0, sqrt(-1), malformed file name, head []). Your program is definitely wrong. X/0, sqrt(-1), head [] are errors It depends on WHERE THE DATA CAME FROM. Sure, the distinction exception/error depends on the source of the data that causes problems. And sadly, the library does not know this, so the library cannot classify problems _that_ way. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Tue, 8 Dec 2009, Ben Franksen wrote: Michael, Henning There are two meanings to the word 'exception' in this context; both of you tend to conflate these different meanings. One meaning is about a *mechanism* for non-local control flow; the other is about certain classes of un-desired program conditions. Michael, you are above arguing that it is ok to use the same /mechanism/ to signal errors and exceptions. That is ok with me. I'm actually arguing that errors and exceptions (or failures) should not be treated the same way. This is my opinion because 1. You cannot catch all kinds of errors (infinite loops, memory corruption, and so on) at run-time 2. The program cannot help itself if it is buggy. The next higher level in the software hierarchy certainly can, but this requires obviously a different mechanism. The correct treatment of those things is in my opion: 1. Errors must be fixed by the programmer 2. Exceptions must be appreciated by the programmer and handled by the program at runtime So, maybe it would help if we could agree to use different terms for those two meanings of the word 'exception'. I think 'exception' is too strongly associated with the non-local control flow mechanism to introduce a new word for it. I used the term exception because this is the term used for the concept of handling file not found, could not allocate resource in the introduction to modern languages that I have read. Thus my impression was that exception is the term for the concept, whereas there are different implementations and ways of handling them. For instance in Modula-3 the EXIT statement is called an exception that escapes the LOOP structure, but it cannot be catched with TRY, that is used for user defined exceptions. http://www.cs.purdue.edu/homes/hosking/m3/reference/exit.html In Modula-3 a detected error (range violation, NIL dereference, division by zero) terminates the program. An undetected error (which is restricted to UNSAFE modules) can cause memory corruption and all those bad things, and cannot be handled in any way. Before exceptions got a special handling in programming language, they still existed. In C for instance they were expressed by return codes. The Wikipedia author also seem to consider exception to be the term for the concept, not for the implementation: http://en.wikipedia.org/wiki/Exception_handling Exception handling is a programming language construct or computer hardware mechanism designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Tue, 8 Dec 2009, Richard O'Keefe wrote: X/0, sqrt(-1), head [] are errors It depends on WHERE THE DATA CAME FROM. If your program actually computes X/0 or sqrt(-1) or head [] your program is buggy, independent from where the zero, the minus one or the empty list comes. Sure, the distinction exception/error depends on the source of the data that causes problems. And sadly, the library does not know this, so the library cannot classify problems _that_ way. To this end the library documentation says: Precondition: This function must only be called on non-empty lists. If the programmer calls it with an empty list anyway, it's his fault. The library user made the error then. Of course it would be better, if types or contracts could force such restrictions: http://www.haskell.org/pipermail/haskell-cafe/2009-November/068877.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Tue, 8 Dec 2009, Richard O'Keefe wrote: On Dec 8, 2009, at 12:28 PM, Henning Thielemann wrote: It is the responsibility of the programmer to choose number types that are appropriate for the application. If I address pixels on a todays screen I will have to choose at least Word16. On 8-bit computers bytes were enough. Thus, this sounds like an error. That kind of attitude might have done very well in the 1960s. I don't quite understand. If it is not the responsibility of the programmer to choose numbers of the right size, who else? If the operating system uses Int32 for describing files sizes and Int16 for screen coordinates, I'm safe to do so as well. The interface to the operating system could use type synonyms FileSize and ScreenCoordinate that scale with future sizes. But the programmer remains responsible for using ScreenCoordinate actually for coordinates and not for file sizes. In an age when Intel have demonstrated 48 full x86 cores on a single chip, when it's possible to get a single-chip DSP with 240 cores that's fast enough to *calculate* MHz radio signals in real time, typical machine-oriented integer sizes run out _really_ fast. For example, a simple counting loop runs out in well under a second using 32-bit integers. The programmer doesn't always have the information necessary to choose machine-oriented integer sizes. Or it might not offer a choice. Or the choice the programmer needs might not be available: if I want to compute sums of products of 64-bit integers, where are the 128-bit integers I need? And the consequence is to ship a program that raises an exception about problems with the size of integers? I'm afraid I don't understand what you are arguing for. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Dec 8, 2009, at 1:27 PM, Henning Thielemann wrote: On Tue, 8 Dec 2009, Richard O'Keefe wrote: On Dec 8, 2009, at 12:28 PM, Henning Thielemann wrote: It is the responsibility of the programmer to choose number types that are appropriate for the application. If I address pixels on a todays screen I will have to choose at least Word16. On 8-bit computers bytes were enough. Thus, this sounds like an error. That kind of attitude might have done very well in the 1960s. I don't quite understand. If it is not the responsibility of the programmer to choose numbers of the right size, who else? It is the responsibility of the computer to support the numbers that the programmer needs. It is the responsibility of the computer to compute CORRECTLY with the numbers that it claims to support. I repeat: the programmer might not KNOW what the integer sizes are. In Classic C and C89, the size of an 'int' was whatever the compiler chose to give you. In c89, limits.h means that the program can find out at run time what range it got, but that's too late. If the operating system uses Int32 for describing files sizes and Int16 for screen coordinates, I'm safe to do so as well. In a very trivial sense, this is true. In any less trivial sense, not hardly. Suppose I am calculating screen coordinates using / x \ / a11 a12 a13 \ / u \ | y | = | a21 a22 a23 | | v | \ 1 / \ 0 0 1 / \ 1 / which is a fairly standard kind of transformation, it is not in general sufficient that u, v, x, and y should all fit into Int16. The intermediate results must _also_ fit. (Assume for the moment that overflow is checked.) If I need to represent *differences* of Int32 pairs, I know perfectly well what type I need: Int33. But there is no such type. The interface to the operating system could use type synonyms FileSize and ScreenCoordinate that scale with future sizes. But the programmer remains responsible for using ScreenCoordinate actually for coordinates and not for file sizes. Consider this problem: We are given a whole bunch of files, and want to determine the total space used by all of them. Smalltalk: fileNames detectSum: [:each | (FileStatus fromFile: each) size] The answer is correct, however many file names there are in the collection. But if we're using C, or Pascal, or something like that, we want to do FileCollectionSize fcs = 0; for (i = 0; i n; i++) { fcs += OS_File_System_Size(filename[i]); } and how on earth do we compute the type FileCollectionSize? Remember, it has to be big enough to hold the sum of the sizes of an *unknown* and quite possibly large number of quite possibly extremely large files, not necessarily confined to a single disc, so the total could well exceed what will fit in FileSize. This is especially so when you realise that there might be many repetitions of the same file names. I can _easily_ set this up to overflow 64 bits on a modern machine. In Haskell, you'd want to switch straight over to Integer and stay there. In an age when Intel have demonstrated 48 full x86 cores on a single chip, when it's possible to get a single-chip DSP with 240 cores that's fast enough to *calculate* MHz radio signals in real time, typical machine-oriented integer sizes run out _really_ fast. For example, a simple counting loop runs out in well under a second using 32-bit integers. The programmer doesn't always have the information necessary to choose machine-oriented integer sizes. Or it might not offer a choice. Or the choice the programmer needs might not be available: if I want to compute sums of products of 64-bit integers, where are the 128-bit integers I need? And the consequence is to ship a program that raises an exception about problems with the size of integers? Yes. Just because the programmer has TRIED to ensure that all the numbers will fit into the computer's arbitrary and application- irrelevant limits doesn't mean s/he succeeded. For that matter, it doesn't mean that the compiler won't use an optimisation that breaks the program. (Yes, I have known this happen, with integer arithmetic, and recently.) I'm afraid I don't understand what you are arguing for. I'm arguing for three things. (1) If you look at the CERT web site, you'll discover that there have been enough security breaches due to integer overflow that they recommend working very hard to prevent it, and there's an As If Ranged project to enable writing C _as if_ it could be trusted to raise exceptions about problems with the size of integers. It is better to raise an exception than to let organised crime take over your computer. (2) In a language like Ada where the programmer can *say* exactly what range they need, and the bounds can be computed at compile time, and the compiler either does it right or admits right away that it can't, it's the programmer's fault if it's wrong.
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
I'm wondering, what are we talking about here? - the meaning of error and exception? - personal responsibility when writing programs? - language features - library functions, runtime implementation etc.? The first two, I think could serve as the basis for an entertaining discussion. Where the third applies, if there are real disagreements it would be helpful to frame the discussion at least partly in those terms, so anyone who has a practical interest in the matter may understand what's being discussed. In my view, the discussion so far has shown that while everyone has interesting and valuable opinions about how various contingencies ought to be handled, in the end it no doubt it must be up to the programmer writing the code ... right? Donn Cave, d...@avvanta.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Tue, Dec 8, 2009 at 1:25 AM, Ben Franksen ben.frank...@online.de wrote: Michael Snoyman wrote: On Mon, Dec 7, 2009 at 9:53 PM, Henning Thielemann lemm...@henning-thielemann.de wrote: On Mon, 7 Dec 2009, Michael Snoyman wrote: I also think that in an earlier mail I answered, that errors can leave you with corrupt data, say invalid file handles, memory pointers, or data structures that violate invariants. You won't like to close files from invalid file handles and free memory from corrupt pointers or run into infinite loops by traversing the corrupt data structures. That's the reason why it is better to stop execution of the program and hand over control to the next higher level, say the shell or the web browser, that can free resources safely. Firstly: I'm really referring exclusively to non-FFI Haskell programs, to which most of the issues you mention don't really apply. Nonetheless, I think that for a language with exceptions, it still makes sense to use the exceptions in these cases. In all these cases, I think the correct thing is to have a specific exception type that is thrown that signals that it is such an unrecoverable error. This allows the programmer to do *whatever* they want. Perhaps they want to save some other data to a file before exiting? Perhaps they want to spawn a process to send in a bug report? Who knows. It doesn't matter. The point is, the user *might* want to do something, and exceptions let them do it if they wish, or they can completely ignore that specific exception type and let the program crash anyway. Michael, Henning There are two meanings to the word 'exception' in this context; both of you tend to conflate these different meanings. One meaning is about a *mechanism* for non-local control flow; the other is about certain classes of un-desired program conditions. Actually, I think you'll find the we are *not* conflating the terms. Henning makes it clear later on. Michael, you are above arguing that it is ok to use the same /mechanism/ to signal errors and exceptions. That is ok with me. There are certainly good use cases, you have presented a few. However, that does not mean it is 'silly' or 'unnecessary' to distinguish between program(-mer) errors and other kinds of expected exceptional conditions in general, as you claimed in a previous message. I agree with Henning insofar as I think it is important to make the *conceptual* distinction -- regardless of whether we use the same mechanism to signal (and, perhaps, after serious consideration, handle) them. So, maybe it would help if we could agree to use different terms for those two meanings of the word 'exception'. I think 'exception' is too strongly associated with the non-local control flow mechanism to introduce a new word for it. Henning, what about calling an undesired but expected condition a 'failure' instead of an exception, so we could reserve this word for the language mechanism? Calling something a 'failure' in this sense (i.e. in contrast to 'error') would always include some judgement, as it needs to take the different program levels into account. Please do *not* call them failures; a few of us have been working on a failure package and associated helper packages, and called it failure specifically because it was an unused term and thus incurred none of the wrath which rains down upon those unfortunate souls who conflate the terms error and exception in the descriptions of their issues. Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Tue, Dec 8, 2009 at 7:40 AM, Michael Snoyman mich...@snoyman.com wrote: On Tue, Dec 8, 2009 at 1:25 AM, Ben Franksen ben.frank...@online.dewrote: Michael Snoyman wrote: On Mon, Dec 7, 2009 at 9:53 PM, Henning Thielemann lemm...@henning-thielemann.de wrote: On Mon, 7 Dec 2009, Michael Snoyman wrote: I also think that in an earlier mail I answered, that errors can leave you with corrupt data, say invalid file handles, memory pointers, or data structures that violate invariants. You won't like to close files from invalid file handles and free memory from corrupt pointers or run into infinite loops by traversing the corrupt data structures. That's the reason why it is better to stop execution of the program and hand over control to the next higher level, say the shell or the web browser, that can free resources safely. Firstly: I'm really referring exclusively to non-FFI Haskell programs, to which most of the issues you mention don't really apply. Nonetheless, I think that for a language with exceptions, it still makes sense to use the exceptions in these cases. In all these cases, I think the correct thing is to have a specific exception type that is thrown that signals that it is such an unrecoverable error. This allows the programmer to do *whatever* they want. Perhaps they want to save some other data to a file before exiting? Perhaps they want to spawn a process to send in a bug report? Who knows. It doesn't matter. The point is, the user *might* want to do something, and exceptions let them do it if they wish, or they can completely ignore that specific exception type and let the program crash anyway. Michael, Henning There are two meanings to the word 'exception' in this context; both of you tend to conflate these different meanings. One meaning is about a *mechanism* for non-local control flow; the other is about certain classes of un-desired program conditions. Actually, I think you'll find the we are *not* conflating the terms. Henning makes it clear later on. Let me rephrase that: we both agree that there is at least a theoretical difference between the two. I believe the distinction in practice is difficult, if not possible, to determine, while Henning disagrees (I believe). Since I believe the two cannot in general be distinguished by name, they should not be distinguished by mechanism, and thus individual types of errors/exceptions/failures should be distinguished by type. I believe Henning thinks that errors should cause a program to abort, while exceptions should be handled by the exception mechanism. So you're right: we do conflate the terms a bit. I *think* the conflation in terminology, however, is directly correlated to the conflation in mechanism. Michael, you are above arguing that it is ok to use the same /mechanism/ to signal errors and exceptions. That is ok with me. There are certainly good use cases, you have presented a few. However, that does not mean it is 'silly' or 'unnecessary' to distinguish between program(-mer) errors and other kinds of expected exceptional conditions in general, as you claimed in a previous message. I agree with Henning insofar as I think it is important to make the *conceptual* distinction -- regardless of whether we use the same mechanism to signal (and, perhaps, after serious consideration, handle) them. So, maybe it would help if we could agree to use different terms for those two meanings of the word 'exception'. I think 'exception' is too strongly associated with the non-local control flow mechanism to introduce a new word for it. Henning, what about calling an undesired but expected condition a 'failure' instead of an exception, so we could reserve this word for the language mechanism? Calling something a 'failure' in this sense (i.e. in contrast to 'error') would always include some judgement, as it needs to take the different program levels into account. Please do *not* call them failures; a few of us have been working on a failure package and associated helper packages, and called it failure specifically because it was an unused term and thus incurred none of the wrath which rains down upon those unfortunate souls who conflate the terms error and exception in the descriptions of their issues. Michael Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: New Hackage category: Error Handling
Michael Snoyman wrote: On Sun, Dec 6, 2009 at 12:55 AM, Henning Thielemann lemm...@henning-thielemann.de wrote: On Sun, 6 Dec 2009, Michael Snoyman wrote: I think there are plenty of examples like web servers. A text editor with plugins? I don't want to lose three hours worth of work just because some plugin wasn't written correctly. For many classes of programs, the distinction between error and exception is not only blurred, it's fully irrelevant. Harping on people every time they use error in the wrong sense seems unhelpful. Hope my commenting on this subject doesn't become my own form of *pedantry*. In an earlier thread I have explained that one can consider a software architecture as divided into levels. What is an error in one level (text editor plugin, web server thread, operating system process) is an exception in the next higher level (text editor, web server, shell respectively). This doesn't reduce the importance to distinguish between errors and exceptions within one level. All approaches so far that I have seen in Haskell just mix exceptions and errors in an arbitrary way. I think we can all appreciate why it would be a bad thing is we treat exceptions as errors. For example, I don't want my program to crash on a file not found. On the other hand, what's so bad about treating errors as exceptions? If instead of the program crashing on an array-out-of-bound or pattern-match it throws an exception which can be caught, so what? The error gets hidden instead of fixed? Cheers Ben ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: New Hackage category: Error Handling
On Mon, Dec 7, 2009 at 5:30 AM, Ben Franksen ben.frank...@online.de wrote: Michael Snoyman wrote: On Sun, Dec 6, 2009 at 12:55 AM, Henning Thielemann lemm...@henning-thielemann.de wrote: On Sun, 6 Dec 2009, Michael Snoyman wrote: I think there are plenty of examples like web servers. A text editor with plugins? I don't want to lose three hours worth of work just because some plugin wasn't written correctly. For many classes of programs, the distinction between error and exception is not only blurred, it's fully irrelevant. Harping on people every time they use error in the wrong sense seems unhelpful. Hope my commenting on this subject doesn't become my own form of *pedantry*. In an earlier thread I have explained that one can consider a software architecture as divided into levels. What is an error in one level (text editor plugin, web server thread, operating system process) is an exception in the next higher level (text editor, web server, shell respectively). This doesn't reduce the importance to distinguish between errors and exceptions within one level. All approaches so far that I have seen in Haskell just mix exceptions and errors in an arbitrary way. I think we can all appreciate why it would be a bad thing is we treat exceptions as errors. For example, I don't want my program to crash on a file not found. On the other hand, what's so bad about treating errors as exceptions? If instead of the program crashing on an array-out-of-bound or pattern-match it throws an exception which can be caught, so what? The error gets hidden instead of fixed? Cheers Ben You're right; bad programmers could do this. A good programmer will know to do one of two things when it gets an exception it does not know how to handle: * Die with an error message. * In cases like web servers, print an informative error message (eg, hopefully more useful than Prelude: head) and continue doing something else. I think the kind of programmers who just ignore exceptions and try to keep going are what I think of as over-defensive programmers, who in a misguided attempt to make their code more robust think that they should eliminate any possibility of not returning a result. I saw my share of this kind of code at my previous job, and when you're dealing with data processing programs, it's *very* irritating when suddenly you have garbage data because someone thought huh, this should be negative, will just use the abs function. However, these people will find ways of doing these evils even without exceptions. Bonus: My favorite error-handling line of code at the company was a bit of VBA that went: On Error Goto Hell Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe