
András Mocsáry wrote:
*My concern* is about predictable failure of sw written in Haskell. To illustrate it let's see a Haskell pattern matching example:
And in Haskell pattern matching:
switch 1 = "Unchecked"
switch 2 = "Checked"
switch 3 = "Unknown"
Let's say, these are clearly defined states of some objects. Then let's say something unexpected happens: x gets something else than 0 1 2. Now we have a problem, which is most generally fixed in these ways:
switch 1 = "Unchecked"
switch 2 = "Checked"
switch 3 = "Unknown"
switch x = "Nothing"
These general ways really avoid this particular crash, but does something real bad to the code in my opinion.
Agreed. The real cause of the problem is that the programmer didn't prove that x is in {1,2,3} when calling switch.
Below are some cases x can go wrong: *1. The bad data we got as 'x', could have came from an another part of our very program, which is the REAL CAUSE of the crash, but we successfully hide it.* * Which makes it harder to fix later, and thus eventually means the death of the software product. Eventually someone has to rewrite it. Which is economically bad for the company, since rewriting implies increased costs.
Yes.
2. The bad data we got as 'x', could also could have come form a real word object, we have underestimated, or which changed in the meantime.
You should not assume that your input is correct in fault-tolerant programs.
3. This 'x' could have been corrupted over a network, or by 'mingling' or by other faulty software or something.
Unlikely. There is nothing you can do about this, though.
Point 1: If we allow ourself such general bugfixes, we eventually kill the ability of the project to 'evolve'.
Point 2: Programmers eventually take up such 'arguably bad' habits, thus making harder to find such bugs.
Thus it would be wiser to tell my people to never write Default cases, and such general pattern matching cases.
It is a better idea to use the type system to prevent this kind of bugs. In this particular case, it's better to try to have a datatype like data X = One | Two | Three
* Which leads to the very reason I wrote to you:
I want to propose this for Haskell prime:
I would like to have a way for Haskell, not to crash, when my coders write pattern matching without the above mentioned general case. Like having the compiler auto-include those general cases for us, but when those cases got hit, then* instead of crashing*, it *should **report some error* on *stdout *or *stderr*. (It would be even nicer if it cold have been traced.)
And, how would it continue? Suppose that we have the function head :: [a] -> a head (x:_) = x What would you propose that would happen if I call head [] ? Print an error on stderr, say, but what should it return? Surely it cannot make an value of type "a" out of thin air? Nowadays, head [] crashes the program, and you get an error message to standard error.
This is very much like warning suppression, just that it's crash suppression, with the need of a report message of course.
This is already possible with exception handling.
*I would like to hear your opinion on this.*
I don't think it can be implemented in a sane way, or that it's a good idea to suppress this silently, when an explicit solution already exists.
I also think, that there are many similar cases in haskell, where not crashing, just error reporting would be way more beneficial. In my case for server software, where network corrupted data, ( and data which has been 'tampered with' by some 'good guy' who think he's robin hood if he can 'hack' the server ) is an every day reality.
You should validate your data in any case. You may even turn a DoS attack into a "real" security problem with your "solution". Cheers, Jochem -- Jochem Berndsen | jochem@functor.nl | jochem@牛在田里.com