One of the big myths that advocates of static typing like to wave around is the idea that having the compiler catch certain types of errors reduces the likelihood of errors in your program.

One of the big arguments of dynamic typing advocates is that you still have to write tests for your code and those types of errors don’t often come up anyway.

Now no one ought to take the arguments of C, C++, or Java programmers seriously when they start talking about the strength of their typing systems, but when certain Haskell advocates claim that “If it compiles, it’s likely correct!” then things get a little ridiculous.

It’s easy to write a perfectly type-safe Haskell program that (accidentally) gives the wrong answer… or fails to complete. (Okay, I admit I just wanted to write a program that gave the wrong answer instead of proving the halting problem by example, but bear with me.) Here’s a simple, 19-line Haskell program that could be shorter if it weren’t didactic (or I were a better Haskell program). It uses very simple Newtonian approximation to produce the square roots of given integers:

main :: IO ()
main = do
    num <- getLine
    putStrLn (show (badSqrt (stringToInteger num)))

stringToInteger :: String -> Integer
stringToInteger s = read s::Integer

badSqrt :: Integer -> Float
badSqrt 0 = 0
badSqrt x = approximate (fromInteger x) 1

approximate :: Float -> Float -> Float
approximate x y
    | x == y    = x
    | otherwise = approximate new_x new_y
    where
        new_x   = ( x + y ) * 0.5
        new_y   = ( x * y ) / new_x

… except that it only works on positive integers.

Sure, it compiles and runs just fine. At least, it appears fine until someone asks “Hey, it handles integers! How does it do when you ask for the square root of a negative number?”

Not well.

Typesafety does not necessarily imply correctness. Maybe more charitably I should say that a “correct” program won’t necessarily behave correctly or give you the correct answers.

That doesn’t mean that program correctness is useless, that Haskell’s a bad language, or that strict typing and type inferencing are never helpful. It just means that not all errors in a program are type errors. Please use the word “correct” with respect to programs… more correctly.