Dynamic typing as safe as static typing is based on wrong assumption

Update 3: Because I got stalked, I change the tilte of the post from "The unit testing lie aka dynamic typing testing lie". I like this blog, but it's not worth it. The view that dynamic typing and static are equally safe is based on the assumption that dynamic developers do more unit testing (what the compiler otherwise does) than static developers to ensure safety.

Update 1: Thanks to Graeme. I have been unclear with my post. The lie I'm talking aboutis that there is no problem with dynamic languages or a difference between dynamic languages and static languages concerning type bugs you can write unit test, suggesting that developers really write unit tests to cover type checks. All would be good if people write tests. Josh as someone who fixes Rails projects says that he often sees not enough or no unit tests in the Rails projects they are called to fix. If you use dynamic languages and have >90% test coverage including duck typing, you're safe and this post does not apply

Update 2: If you want to make a sensible comment, you could say "Lie is an exaggeration, could it be a logic fallacy?" and I would reply "Saying knowingly not the truth is lying". Or you could say "From the 37 projects in [Dynamic Language Of Your Choice] which I have investigated, the lowest code coverage with unit testing was 80%" and I would reply "Thanks for the facts, seems contrary to the facts in my post unit testing is widespread in dynamic language projects" and change the title. Or you could give your opinion about any topic you wish, attack me and spare me facts.

Stumbling upon one of the very best articles about web programming for some time: Rails Worst Practices: 13 Coding Nightmares You Should Avoid by Josh Symonds. One of the experiences Josh is that developers don't do - enough - unit testing:

[Testing] This should probably be higher since it's one of the most annoying things about picking up an existing codebase. A lot of the code we get isn't well tested, or even tested at all. Untested code is very very difficult to alter: you're not sure if the small change you're making will break functionality out in the middle of nowhere, and you have no way of testing it without following through the application flow every time you make a change.

When discussing dynamic vs. static languages, the arguments for not needing static type checks are based on more unit tests.

The blog post says: Nada, developers don't test. [1]

This reflects my experience. Developers don't test. They do test after they got a bloody nose several times, best a bug lost some money, lost bookings or orders or the plattform was down. Then developers literally yearn for more security. They write tests if you tell them again and again (or they are very very good). And you need hard coverage metrics and goals - even if it's 100% (some won't agree). Otherwise they are over-optimistic, over-confident and always under deadline preasure. Unit tests are hard to explain to business users and managers - they can be explained but often developers do a bad job at explaining them.

I was astonished by the claim that everything is fine in Rails-land and developers, contrary to most of their brethren, do extensive (even more than for static languages) unit testing. Seems to be mostly a myth - especially with more Rails developers as the experience level goes down. You can have a community of 1000 top coders, but not of 100.000 top coders, there aren't enough.

There is much more interesting insight in the article:

Chubby Controllers Must Die
There should be no business logic in a controller.

It's not about Rails. Every project and every web framework I've seen has been abused by developers. They put code into parts where they should not. In Struts, in JSF, all the time. Developers don't change and a web framework won't help. Strict coding practices and reviews help.

NEVER Assume You Don't Have Nil
Maybe you assume that your ActiveRecord object has an association on it, like address. So you innocently type user.address.telephone and blam! Your application blows up because address was, in fact, nil.

Again the same experience. The biggest problem in Java are Null Pointer Exceptions, people don't check for null often enough. The don't use Either style error checking either (ha!). And Java doesn't support safe dereferencing yet:

Null dereference expressions - Null checks with '?' syntax similar to Groovy... lettign developers avoid a nest of null checks.

Another one from the post:

Check ActiveSupport (and other Rails/Ruby classes) FIRST
I see a ton of methods that already exist in ActiveSupport that are hand-coded from scratch. Stuff like Time#beginning_of_week and pluralize pops right to mind. Also there are a lot of people who do scratch versions of time_ago_in_words and number_to_currency (two of the most helpful ActionView Helpers)

Would easily translate to "Check commons" in Java. Or check the JDK. Especially reuse JDK code when someone asks you this in an interview

All in all, excellent post, go read it.

Thanks for listening. As ever, please do share your thoughts and additional tips in the comments below, or on your own blog (I have trackbacks enabled).

[1] All generalizations outside of physics, mathematics and chemestry are wrong. Without them one cannot make meaningful descriptions about the world. This should read most developers and "test enough".

Because people are not accustomed to the discussion, some entry points into the dynamic vs. static discussion, how static typing is just a kind of test and how unit tests are better than static typing.

About using unit tests to find usual compiler errors by Steve:

But the argument that I'm making is NOT that compilers don't occasionally help you catch errors. The argument that I'm making is that you're gonna catch the errors one way or the other. Especially if you've got unit tests, or QA or whatever.

About dynamic language users doing more unit tests:

People who use languages with strong static type systems seem to do a lot less unit testing.

In a paragraph about "The strong vs. weak typing issue really gets people worked up.":

We can achieve sufficient reliability through a combination of rigorous unit testing and agile development practices.

About useful code coverage for Rails by David:

In terms of new features, we've been able to add new features to the lift code with fewer defects than with the Rails code. Our Rails code had 70% code coverage. We discovered that anything shy of 95% code coverage with Rails means that type-os turn into runtime failures. We do not have any code coverage metrics for the lift code, but we have seen only 1 defect that's been checked in in the 2 weeks since we started using lift (vs. an average of 1 defect per checkin with the Rails code.)

About how unit testing helps to find bugs in your code when using Groovy (that otherwise the type system finds):

"It might be scary to do away with all of your static typing and compile time checking at first. [...] You should make all efforts to use unit tests to verify your intended behavior."

About the importance of unit tests in the Rails community by Eric:

"The Rails framework and the Rails community are both built on a culture of good programming habits.
[...] Unit tests? Built in and highly encouraged.

A variant of the argument about testing, which says: Static typing doesn't help you much, because it doesn't verify all behavior, you need unit test nevertheless. Suggesting that people do unit tests, by Bruce:

The only guarantee of correctness, regardless of whether your language is strongly or weakly typed, is whether it passes all the tests that define the correctness of your program. And you have to write some of those tests yourself. These, of course, are unit tests.

This should help as a starting point in the static vs. dynamic typing discussion. Unit tests are a great invention, I suggest you have 100% CC coverage. But don't read those comments on dynamic languages and feel safe. You need to write tests, otherwise they will not help you.

Stephan Schmidt Administrator
CTO Coach , svese
Stephan is a CTO coach. He has been a coder since the early 80s, has founded several startups and worked in small and large companies as CTO. After he sold his latest startup he took up CTO coaching. He can be found on LinkedIn or follow him in Twitter.
follow me