Strong Typing vs. Strong Testing
A few months back I saw (via the web - do not remember where) Bruce Eckel speaking to a group. In the middle of the talk he posed a question (paraphrased below).
Do we need strong typing if we have unit tests?
The question gave me pause as clearly he had a point ... but something did not sit right.
More recently Bruce explores this same subject under Strong Typing vs. Strong Testing.
In the time between it became plain to me why this notion gave me pause. There is a hidden assumption. To substitute testing for typing you must believe your tests are perfect.
Personally, I am a bit of a skeptic. I will guarantee you that neither the code I write, nor my tests are perfect. I suspect the same tolds true for pretty much everyone else. When your tests are perfect, Bruce is right -- you have no need for strong typing. But what happens when your code encounters a situation you did not anticipate, and that your tests do not cover?
As an aside, I should mention that strong typing generally allows the compiler to emit more efficient code. A good part of the time, this is not important. There are still times when efficiency matters.
A couple years back an intern asked me to review some of his code. I stopped writing when my comments got to be longer than his original code. What I realised is that over the years I have collected a rather large number of practices, all aimed at reducing the occurance of errors in my code. Many of the individual practices may only make a small percentage difference is the error rate, but add together a few dozen of these small items and you get a large whack taken out of the error rate.
Strong typing is one of those practices. Strong typing can help cut back our error rate when our code wanders off into waters uncharted by unit tests.
Not that I want to be using strong typing all the time! I have been a strong believer in "dynamic" languages since using Lisp in college (where I first ran into Bruce - we were both taking physics and computer science courses at about the same time). What I would like is to be able to choose the level of "strictness" on a case by case basis.
There is a group of developers who can get away with using just dynamic languages and unit testing. This is the group that essentially has one application, and direct access to the machine(s) on which the application is deployed. Web applications like those hosted by Yahoo and Google fall into this group. With only one deployment environment, unit tests have a better chance at complete coverage. With direct access to the machine(s) on which the application is deployed, any problems can be fixed immediately, and the period of time any bug is seen in the field can be very limited.
Guys who write books about software kind'a belong in this group too :).
I do not have this luxury. My applications get mainly deployed within company intranets. I do not have direct access to most customer systems. Practically every customer system is different -- operating system versions, patches applied, hardware, disk layout, virus scanners, firewalls, security configuration, and other applications running on the same machine -- there is a lot of variation. Guaranteed when a new version of the software goes out, we will find some combination that causes a problem, that we did not anticipate, and for which we did not test.
Add to this the fact that determining the source of the error may be difficult, as these are production customer systems to which we do not have direct access. What this often means is more time needed to detect the error, more time needed to diagnose the error, and (much!) more time needed to get the error corrected on all the customer systems.
In this scenario our unit tests have failed, and my only hope to stay out of trouble is all the other tricks I have learned over the years - all the other practices that cut down the error rate. In this environment I want to do everything I can up-front to minimize the chance of error.
Bruce has a point - unit tests count for a lot, and sometimes may be enough by themselves.
Sometimes is not always, and strong typing still has a place in our bag of tricks.