Reason #1: I want to be freeeeeee.

So, this is the total stereotype of the dynamic, LISPy geek but it’s true. I feel tied down by the type system.

All static, dependently-typed systems will rule out or be incapable of expressing some perfectly good, error-free programs. Or as some of my smart friends say:

Type systems may make it hard or impossible to do things you don’t want to do, but they certainly don’t make it easy to do things you do want to do. That is the nature of placing the challenge of placating a compiler between the programmer and running code.

In particular, adding in something like Typescript has interfered with some dynamic solutions we’ve come up with at work — code that was idiomatic Javascript, but would have required a dynamic type generation. While this was solvable with effort, the necessity of the effort itself brings us into the next reason:

Reason#2: The effort-to-payoff ratio is skewed.

Even beyond the reduced solution space, using a type system requires a lot of extra overhead — cognitive and otherwise. Not only is there the extra time spent understanding and implementing system-compliant types, but because inference remains Not Great, for a system to be useful, you have to tell the compiler quite a lot, as our friend Will learned.

thanks will for letter me drag you into this

That might be okay, of course, if the time invested here took away time spent in other locations, but you still need good tests to check for logic and integration issues among other things, and despite what people like to think,

↗️ this is not actually documentation. So we still need both documentation and tests, even with types.

Okay, so onto reason 3:

Reason #3: All that fighting with compilers.

This is a bit of an inversion of what some folks love about type systems: the compiler tells you you have a problem before you even run the program.

However, because of the nature of compilers and code parsing, compilers often locate an error some distance from the code we have to change to fix it. An interpreter or a just-in-time compiler, by contrast, usually breaks closer to the issue.

Now sure, Elm is polite and Javascript tells me that undefined is not a function, but I’ll take a vague message in a precise context over a precise, displaced error any day.

And now, reason #4.

Reason #4: They don’t fit me or the the world.

This big, multivalent grab-bag of a reason is in many ways an extension of reasons one and three.

Because I’m used to dynamic runtimes, I tend to code by writing small bit then running it to be sure it’ll work — often in a REPL (which in Javascript is just your browser console). This is not consonant with the type-driven approach of top-down design and implementation, typing big blocks of code until they compile.

I would argue that more than just being a preference,

developing with tiny iterations is actually better. It’s a structure and a stance that is more aligned with what the whole point of programming is — to accomplish something.

So I’ve mentioned Rich Hickey a few times — and I always like to when I am talking about programming because if I have programming heroes, he’s pretty high on that list — but in this case, it’s also because he just gave a talk at the most recent Clojure Conj that spends a bunch of time on why Clojure is dynamic, why he made the choices he did.

And he brings this up, particularly in the context of typed research languages, this idea that residing in, reflecting, and changing the world are the purpose of the type of programming he is interested in and arguably all programming that is not mathematics research. In this context,