imaginary family values presents

yesh omrim

a blog that reclines to the left


Computers were invented to keep track of boring things

13 November 2006

One reason I haven’t been doing much blogging recently is that I’ve been spending a lot of time learning Haskell, a computer language with a number of intriguing features. Since I have previously remarked on weaknesses in Java’s type system, I thought I would start by remarking on Haskell’s type inference. Unlike many of the language’s other intriguing features, this one is easy to demonstrate and its benefits are easy to explain.

Consider this Haskell program:

main = do str <- getLine
          let n = read str
          putStr "Twice that is "
          putStrLn (show (n * 2.0))

Like C, C++, and Java, Haskell is statically typed: every variable has a type that is known at compile time. Unlike those other languages, though, you don’t have to explicitly declare the type of a variable when the compiler can figure it out. The compiler knows that str is a string, because that’s what the standard library function getLine returns1. The read function is polymorphic and can translate a string into any of a wide variety of Haskell types, but the compiler can still figure out the type of n, because it shows up later as an argument to *; since 2.0 is a floating-point number, then n must be one as well.

sethg@henbane:~/Desktop/hs$ ./a.out
Twice that is 7.0
sethg@henbane:~/Desktop/hs$ ./a.out
Twice that is 84.0
sethg@henbane:~/Desktop/hs$ ./a.out
Twice that is 32.0
sethg@henbane:~/Desktop/hs$ ./a.out
Twice that is a.out: no parse

I realize that programmers get into fervent religious wars over the question of static vs. dynamic typing, but I think I can avoid getting roasted by either side if I point out that if you have to use a statically typed language, it would be nice to use one with type inference. Why should we humans have to keep track of those tedious details if the computer can do it for us?

PS: Notice how in the code, the read function appears before the call to print the phrase Twice that is, but in the output of the running program, the error message from read appears after that phrase. That’s lazy evaluation, another intriguing Haskell feature….

1 Actually, getLine is type IO String. Explaining how the output of this function gets bound to a variable of type String would require explaining Haskell’s monadic IO system, which I’m not ready to do just yet.