«« History Repeating Repeating Where are the Software Project Management Case Studies? »»
blog header image
The Code is the BVA?

I could just have had my programming world turned upside down today. It's funny how that happens sometimes. I started out pretty innocently: I was reading the darcs mailing list. From there I went to investigating Haskell, which lead me to the best Paul Graham article I've read (and I've disagreed with him before, but that's OK) titled Beating the averages.

I was indeed assured by Paul's statement: "The purpose of this article is not to change anyone's mind, but to reassure people already interested in using Lisp-- people who know that Lisp is a powerful language, but worry because it isn't widely used." His anecdote about selling a successful Lisp-based company to Yahoo! also helped, naturally.

But the lightbulb went off while I was reading Why does Haskell matter?. Haskell and Lisp are both functional programming languages. I've been racking my brain over the general problem of testing for weeks, honestly ... and it seemed pretty hopeless and even worse: manual.

It got to the point that I realised that if you wanted to do really good boundary value analysis, which is a common unit testing technique, you end up specifying the function in two equivalent ways: once in the implementing code, and again in the tests that verify it. The tests work because these two different ways of saying the same thing lean on each other like two playing cards.

If the code or tests say something that disagrees, a unit test might fail [1]. The mistake could be in the code or a test, it's hard to tell if all you know is that it failed. But either way it means there's probably a bug somewhere.

It might be very rare that you get a bug that's duplicated identically in both test and code, unless you've just misunderstood the spec you're implementing. You have to remember that your tests can have bugs too and that the code might catch these errors, and it might not. The fact that the tests and the code are two different ways of looking at the same problem is very useful and essential to the leaning against each other aspect.

Back to Haskell now. When you do boundary value analysis in an imperative language like Java, you might picture a real math function to do your boundary value analysis. You figure out boundaries based on the math function, write tests for those conditions and then write Java code that makes the tests pass. The tests are based on this math function, and the code is based on if statements, loops and variable assignments. Much different, right?

In Haskell you write the math function out to make your code, quite literally. The lightbulb went off when I also realised: holy crap, this is also the BVA!. You'd just be wasting time unit testing Haskell code. Instead of code and test being two different ways of doing the same thing, you'd just be doing the same thing twice if you unit tested a Haskell function. This doesn't have the same card-leaning effect, you're just duplicating.

This might be why Haskell has no unit testing framework -- it doesn't need one. In fact, there is no HaskellUnit! This is so absolutely counterintuitive to everything I've been learning from the XP bandwagon that it's probably going to take me weeks for it to sink in completely. update there is a Haskell unit testing framework: HUnit.

Maybe it's all just a bunch of idealistic crap though. How can I know right now? There's no way. I won't know until I dive in head first. I think now's the time to learn a functional language.

Note what that post above says about acceptance testing though: it's still necessary. I wonder if Haskell suffers from the same level of integration problems (functions using functions using functions) as imperative languages.

[1] You could be missing a test after all, then everything would seem peachy. Just because all of your tests pass doesn't mean you have no bugsin your code. In other words, if you don't test for it, you won't know if it fails.

Posted at October 08, 2004 at 06:08 PM EST
Last updated October 08, 2004 at 06:08 PM EST
Comments
Google
 
Search scope: Web ryanlowe.ca