prose :: and :: conz

Maybe type checking is a good idea

I’ve once commented on twitter that I’d grown comfortable with dynamic typing as long as I use unit testing:

I hereby retract that statement.

First off, at the time I had not started playing with functional languages and I had no idea what a legit type system was. As Paul Callaghan put it, you need to “put aside your bad experiences from Java”. I was at the peak of my Groovy enthusiasm. Now that I’ve spent ample time in Scala, I realize that a static type system doesn’t have to suck. While I once would have agreed with Martin Fowler that dynamic typing makes programming fun, I much more enjoy the secure feeling that a solid type system gives me (BTW, I can’t help but notice that he doesn’t mention any languages written by academic type theory junkies).

1. Catch the bugs earlier
If it’s true that the earlier you catch a bug, the cheaper the bug costs, then I can think of nothing better than compile-time checking. Many bugs enter the code the moment you type it (that is, bugs that are introduced during coding after spec/design). Now you’re on the clock to find them. If you’re working with a dynamically typed language, maybe you can run your unit tests in the time a compiler runs. But let’s not forget that the type checker can even run in an IDE, finding bugs as soon as they are typed!

2. A good static type system is free, but unit tests are costly.
The fact is, if you want to use unit testing, you have to write the unit tests! Now I know someone has to write the type system, but my point is that YOU don’t have to. Maybe static type checker doesn’t cover all bugs (a debatable point), but it will have 100% coverage over your code. There’s no such guarantee for unit tests. You’ll have to find a coverage tool, and not to mention that 100% coverage can be achieved with useless unit tests.

3. A type checker will pinpoint exactly where you broke it
In my spare time project, I’m learning a lot. I mean a LOT. Unfamiliarity with a technology is a heavy factor for my selection process, allowing me to learn new stuff en passant to producing a product I’d like to use. This results in lots of rewrites. Just yesterday I had a class that I was modeling as an embedded document and realized it would be better off as a reference in my MongoDB. When I make a change to the API of a class/trait, I love how the compiler points at every usage of that code that is now broken. If I were to rely on unit testing, I would only know that my code is in fact broken (duh!). I would also know what functionality broken, but I would not know immediately where it is broken. So if you do a lot of refactoring (the other pillar of Test-Driven Development!), then I’d argue you’ll refactor faster with a good statically-typed language.

I don’t believe that static type checking catches all bugs, but neither do unit tests. Furthermore the notion that type checking can be set aside for unit testing isn’t supported by data. However, a functional language with a good type system will make even the venerable Kent Beck rethink TDD. Software quality is a complex problem, and there’s no sense in throwing out one tool for another when you can have both. This isn’t to say that you’re stupid for using dynamically typed languages, but the benefits of static type checking have won me over.

My next blog post will highlight some of the Scala language features that helped flip my position. And thanks as always for reading my blog, Mom.

Olde Comments
  1. […] types if you so desire), but without relinquishing the perks of static type checking which I argue is a good thing. Next time, I plan to add implicit conversions to this discussion before moving on to structural […]

  2. […] doesn’t have to suck post, I introduced type inference. This allows the developer to have the perks of static type checking without the pain of redundantly labeling […]

  3. […] The explicit declaration that a type could be undefined is a fantastic idea. The caller of the API is explicitly warned in the code that None is a distinct possibility and any calls that just return T are guaranteed to be legit instances of T (WARNING: Not true for Scala, unfortunately. In order to interop with Java libraries, Scala also has a null. If only Java had gone the option route!). Hence it’s not even possible for the call to return something dereferenceable unless the creator of the API explicitly advertised that possibility. It does in fact just move the null reference problem, but it moves it to the type system which I’m finding more and more is a good idea. […]

  4. […] I’ve been singing the praises of static typing for a few weeks now, but it’s time for me to admit some of the faults I’ve run into […]

  5. […] I’m still struggling to decide if I agree. On the surface it sounds true, but while I love static typing I really don’t like […]

Tagged with: scala (41), static-typing (16), tdd (1)