Brian Doll posted a few interesting questions as a comment on my “Continuous tax” entry, which I’ll try to address in turn:
Oddly enough, some people see the act of writing tests as “continuous tax” in that it’s something else you have to write that does not go toward the “bottom line” of the features you’re implementing.
Actually, I don’t see writing tests as part of this continuous tax that I was describing earlier. While I agree that you usually write less tests in a statically typed language than a dynamically typed one, I think the difference in lines of code or number of tests is not significant enough to meaningfully impact the engineering cycle.
The continuous tax is triggered by the loss in explicitness that dynamic code usually suffers from. While it looks innocuous, the loss of typing actually has dire consequences on the maintainability and readability of your code by not giving you any hint on what type an object passed to a method really is and, worse, by making it impossible to apply even the simplest automatic refactorings such as renaming public functions (see this post for more details).
I’m interested to get your thoughts, as an author of a testing tool, on how you see the overall reliability of testing in dynamic and strongly typed languages.
As shocking as it may seem from the creator of a testing framework and the author of a book on testing, I actually always try to write as few tests as possible. The secret is to find the smallest subset of tests possible for a given functionality.
The way I see it, dynamically typed languages usually make me write the following tests:
- Tests to verify type consistency.
- Unit tests.
- Functional tests.
Statically typed languages usually let me get away with writing:
- Unit tests.
- Functional tests.
To make matter worse, changing a type in my dynamic code forces me to update my tests manually, while the same operation in a statically typed language will not only be performed automatically by my IDE, it will also automatically update my business code *and* my test code (note that I haven’t mentioned TDD a single time because I believe that the practice of TDD is orthogonal to whether the language you are using is dynamically or statically typed).
In the past couple of days, a few people have chimed in with their private experiences of the continuous tax, among which Mark Derricutt and Eric Burke.
What’s interesting about a continuous tax is that you keep paying it all the time to the point that you might even forget about it. From that respect, I wouldn’t be surprised to see that developers who work with dynamic languages on a daily basis encounter the problems described by Eric and Mark regularly, but they just don’t notice any more: it’s just part of their routine. Java (and other statically typed languages) developers simply don’t ever pay this particular tax, so having to face these problems feels like a step backward in productivity (obviously, Java programmers pay different continuous taxes in other areas, but let’s save this topic for another day).
In a comment on Eric’s post, Weiqi wrote:
In that regard, the static typing works just like unit tests – it prevents you from breaking your code.
… which summarizes this issue pretty well: static typing gives you tests for free, and who would turn down free tests?