Ask HN: A well-typed program won't go wrong?
Let's say I'm writing a recursive factorial function in Haskell. But, because it's early morning and the caffeine hasn't kicked in yet, I mess up the recursive call. I say "+ 1" instead of "- 1".
What is Haskell's type system going to say about this mistake? I believe it will say nothing at all, because the problem isn't the type of the value, it's the value of the value. But what's the program going to do? It's going to run until it exhausts memory, and then it's going to die in disgrace.
It seems to me that there are only four possibilities here:
1. Haskell's type system can in fact catch this error at compile time.
2. Despite its celebrated type system, Haskell is not a sufficient base for building a well-typed program, but some other language would be. (Coq? Agda? Some not-yet-existent language?)
3. Dying in disgrace rather than returning the correct value does not count as "going wrong".
4. The statement "a well-typed program won't go wrong" is false.
Of those options, I believe that number 4 is correct, but I am willing to listen to reasoned arguments to the contrary.
According to "Generalized Arrows"[1] by Adam Megacz Joseph the slogan "Well typed programs do not go wrong" was coined by type theorist Robin Milner and means something very specific: 'To "go wrong" means to exhibit undefined behavior. For example, programs written in strongly statically typed programming languages cannot crash, write to random memory locations, or read past the end of a buffer.' If you want precise details please read Milner's "A Theory of Type Polymorphism in Programming"[2].
Note that this does not imply that well typed functional programs do not contain bugs. Futhermore it only applies to a very specific ML-like language with a precisely defined denotational semantics. It is not known to apply to Haskell as no one has even written down the denotational semantics for Haskell. Furthermore it is trivially easy to write crashing programs in most Haskell implementations by taking advantage of any of a variety of non-standard features and functions.
Please let us not build up and knock down straw men about Haskell claiming to prevent all bugs.
[1] http://www.eecs.berkeley.edu/Pubs/TechRpts/2014/EECS-2014-13...
[2] http://tfeng.me/papers/milner78theory.pdf
I accept Milner's claim, with his definition of "go wrong". The problem then becomes that people repeat the claim, but not the definition, and so people like me hear the claim, don't know the technical definition of "go wrong", and assume that the general meaning of the words is being used.
For your specific question, google "dependent types", which are types that depend on a value.
In your case, Haskell can type check positive integers:
http://mvanier.livejournal.com/3820.html
1. I think that the scenario here is one that Haskell can type check, though it takes some work. But I'm not sure.
2. Haskell's type system is better than many, but limited. Coq/Agda/Idris are more powerful.
3. One common definition of "going wrong" is "returning an incorrect answer". Crashing isn't going wrong in that framework. (I don't necessarily agree with it, though I've seen it; at any rate, there is a good reason to think that crashing is a lesser problem than executing and returning incorrect results.)
4. While there may be definitions of "well-typed programs" and "go wrong" for which this is true, ISTR that they are either ones which make it so that a type system that completely supports general computation is not possible, or ones ones which require excluding a lot of errors from "going wrong".
FWIW, I don't know Haskell, but off the top of my head in Ada if I couldn't use a subrange type, I might use a Contract (Pre or Post condition) to insure I was iterating correctly, if I thought to include one without appropriate caffenation.
https://www.google.com/search?q=a+well-typed+program+won't+g...
(+) Probably including this one.
In terms of reducing errors, Haskell goes a long way, but it does not eliminate all errors.