[Haskell-cafe] Type System vs Test Driven Development

Jonathan Geddes geddes.jonathan at gmail.com
Wed Jan 5 10:44:20 CET 2011


Cafe,

In every language I program in, I try to be as disciplined as possible
and use Test-Driven Development. That is, every language except
Haskell.

There are a few great benefits that come from having a comprehensive
test suite with your application:

1. Refactoring is safer/easier
2. You have higher confidence in your code
3. You have a sort of 'beacon' to show where code breakage occurs

Admittedly, I don't believe there is any magical benefit that comes
from writing your tests before your code. But I find that when I don't
write tests first, it is incredibly hard to go back and write them for
'completed' code.

But as mentioned, I don't write unit tests in Haskell. Here's why not.

When I write Haskell code, I write functions (and monadic actions)
that are either a) so trivial that writing any kind of unit/property
test seems silly, or are b) composed of other trivial functions using
equally-trivial combinators.

So, am I missing the benefits of TDD in my Haskell code?

Is the refactoring I do in Haskell less safe? I don't think so. I
would assert that there is no such thing as refactoring with the style
of Haskell I described: the code is already super-factored, so any
code reorganization would be better described as "recomposition." When
"recomposing" a program, its incredibly rare for the type system to
miss an introduced error, in my experience.

Am I less confidence in my Haskell code? On the contrary. In general,
I feel more confident in Haskell code WITHOUT unit tests than code in
other languages WITH unit tests!

Finally, am I missing the "error beacon" when things break? Again I
feel like the type system has got me covered here. One of the things
that immediately appealed to me about Haskell is that the strong type
system gives the feeling of writing code against a solid test base.

The irony is that the type system (specifically the IO monad) force
you to structure code that would be very easy to test because logic
code is generally separated from IO code.

I explained these thoughts to a fellow programmer who is not familiar
with Haskell and his response was essentially that any language that
discourages you from writing unit tests is a very poor language. He
(mis)quoted: "compilation [is] the weakest form of unit testing" [0].
I vehemently disagreed, stating that invariants embedded in the type
system are stronger than any other form of assuring correctness I know
of.

I know that much of my code could benefit from a property test or two
on the more complex parts, but other than that I can't think that unit
testing will improve my Haskell code/programming practice. Am I
putting too much faith in the type system?

[0] http://blog.jayfields.com/2008/02/static-typing-considered-harmful.html



More information about the Haskell-Cafe mailing list