Ramblings of an old-school software developer, father, and woodworker.

Recent Posts

How to Debug Anything
If you’re having trouble fixing anything, try one of these strategies.

Static Types Considered Helpful
Why static types should be considered a best practice for 2017.

Drupal is dead; Long Live Static Site Generation
Drupal security is terrible. Hugo is awesome. Any questions?

Goodbye, Lua
A long-time Lua advocate walks away from the language.

Static Types Considered Helpful

· by Tim Mensch · Read in about 8 min · (1544 Words)
languages lua typescript python security web blog

While I alluded to this in my article on why I gave up on Lua, I feel there’s a lot more to be said about the positive side of using a statically typed language for all non-trivial development.

First, what do I consider to be non-trivial? Probably anything over about 100 lines of code total. You can get benefits from static typing for even really short modules of only 10 lines, but there is a cost in setting up a compiler compared to using a completely dynamic language.

But my argument is that it’s well worth it for those non-trivial projects:

  • For developers who don’t have every API they use completely memorized, a static type system can integrate with tools to give you working, reliable autocomplete, telling you what APIs are available, and some IDEs will even show you the docs of each API as you bring it up. So you can write code more quickly.

  • I would estimate somewhere between 60% and 90% of most unit tests for dynamic languages are basically doing the work of a type checker. So you can write less code.

  • When your statically typed code compiles, you can eliminate an entire class of bug. It’s like a suite of unit tests that run the moment you write the code, and they catch the bugs before you even run the tests. In some editors, before you even save. So you waste less time tracking down bugs.

  • Type safety means that refactoring code doesn’t need an elaborate set of unit tests to ensure it will work. Generally, code with well-defined types simply won’t compile until all the parts are reconnected correctly. Some tools offer automated refactoring, so you can, for instance, rename a member variable or a function name without worrying whether other similarly named variables will accidentally be renamed. So you can purge technical debt more quickly.

  • When your tools can “understand” the types, they also know where every reference to every member is, throughout your code base. You want to know where this object’s init() function is referenced? Hit a key and you get a list of all of the references to that init(). Not the init() on these dozen other classes, but that one. So you can more easily understand the code you’re reading.

To me, the above arguments are more than a little compelling. Each of the above I have personally observed to be true, and I can’t imagine most developers ever saying that they’d prefer the opposite of any to be true.

“I love to watch technical debt accumulate!” – No developer ever.

And all of the above features interact to make a project run more smoothly. Fewer bugs lead to more time to code which is faster because of autocomplete and because less technical debt is accumulating and because you write less code to begin with… It’s a huge win all the way around.

So for any developer who has any choice about what language they’re using in 2017, I state emphatically that they should choose a language with static types, or at least static type annotation.

Why do people not choose static types?

So what are the typical arguments against using static types? Here are the ones I’m familiar with. I’ll add more as people bring them to my attention.

You’ll note below that I’m talking a lot about TypeScript. That’s because I’m currently using TypeScript. I also like Go, another statically typed language, and I’ve heard great things about the client language Elm, which also is type safe and compiles to JavaScript. Rust is also type-safe and an excellent low-level language that also is very fast. I can’t speak as much to the tooling in those languages, though, which is a big part of my list above. So I’m writing what I know.

You lose the power of dynamic languages!

This was my own complaint. I came from C++/Java, and I felt that types were too restrictive, and to be honest, totally rejoiced in the freedom I felt when I could throw off the shackles of types.

So what happened? I spent years fighting with the issues on the opposite side of all of the above bullet points, but I still stubbornly refused to go back to C++, because I remembered the pain I felt from having to carefully map out all of my types in advance. But then I encountered TypeScript, and my world view changed.

What I learned from TypeScript is that it wasn’t static types that I didn’t like. It was C++ and Java-style static types that I didn’t like. JavaScript is a powerful, flexible, dynamically typed language. It gives me all the power and expressiveness that I desired from a language1. And the type system in TypeScript is so powerful that you can express just about everything that you can do in JavaScript, giving you the full power of a static type analysis system on top of the underlying dynamic types of JavaScript.

TypeScript is also improving at an amazing rate. I enable the feature “noImplicitAny”, which requires that every single variable get a type, or be explicitly assigned the “any” type. Because I want TypeScript to protect me, and the more it knows about my code, the more it can protect me. I was surprised when, with version 2.1.1 of TypeScript, the following code worked without throwing an “implicit any” error:

function test(a = "default") {
    let result;
    if (a.length>0) {
        result = a;
    } else {
        result = "short string";
    }
    return result;
}

TypeScript can now correctly identify the function test as taking and returning a string, the variable result as a string, and as a result it will error if you try to write code that treats result as a number, or try to access a method on it that doesn’t appear on a JavaScript string. Yes, you can add types in for clarity. But you don’t have to, and you don’t lose any flexibility if you choose not to.

The build step

If you are using plain JavaScript, you have to set up a build step in order to use TypeScript. Given the number of other web technologies you’re missing out on if you don’t have a build step, this argument holds less water every day.

Without a build step you:

  • Can’t use any new ES2015 features in current browsers
  • Can’t use a compile-to-CSS language like SCSS
  • Can’t compress (Uglify) your JavaScript
  • Can’t inject code into your HTML or JavaScript files (changing them for production builds, for instance)

These are all important tools in the modern JavaScript shop. Using TypeScript in your toolchain shouldn’t even be a question today.

You’re using Ruby or Python (or Lua)

I can’t help you here. As far as I’m concerned, those languages are dead to me for everything except projects where I’m forced to interact with them.

I’ll probably still use Python for the occasional machine learning task. Some machine learning libraries are just written well for Python, and I’m not going to kill myself trying to avoid using Python.

But I still assert that it is better to choose to use TypeScript or Go or Rust or another typed language than it is to start a new project in Python. So yes, I’ll say it again: I believe it to be a best practice in 2017 to not use Python2 or Ruby3 for anything non-trivial. Or Lua.

You’re using PHP

The newest version of PHP actually has types. Upgrade to it and use them. But why are you using PHP in 2017? Didn’t you get the memo?4

Other Reasons

Aside from the standard “my boss says I have to use this language,” I think that most other reasons come down to familiarity and/or inertia. Or possibly a variant of Stockholm syndrome: Trapped in the one language you know and tortured by it, you’ve come to love your oppressor.

Learning a new language isn’t as hard as learning the first one. I promise. Give a statically typed language a college try. Even if you skipped college. Especially if you skipped college.


  1. Despite its warts. And you can protect yourself from most JavaScript warts by using an appropriate linting tool. [return]
  2. Traditional Python web sites are pretty slow, especially Django, but there do exist modern frameworks that make the speed comparable, sometimes even faster than JavaScript, if not as fast as Go. [return]
  3. Rails is also painfully slow, clocking in at 40-920x slower than Go and 40-120x slower than Node.js, depending on benchmark. I know that people like to say that “programmers are expensive and servers are cheap,” but a factor of 100 on servers can easily take an early company from profitable to hemorrhaging money. [return]
  4. OK, PHP 7 is actually a halfway decent language, and it’s actually quite fast for synchronous code. But the modern web is heavily built on real time clients using tools like Socket.io and/or other real time database connections, and due to PHP’s thread-per-connection architecture you’re wasting an entire CPU thread per real-time client connection. Architecturally you’re far better off using either Node.js or Go for the server when you’re dealing with a client with real time updates. And you’re also better off using static site generation than something like WordPress [return]

Comments