I don't know what it is, but I seem to be running into a lot of people [1] lately who are against static typing. And most of theses people who dismiss static typing have a seemingly narrow view of what it enables. I assume this comes from lack of experience with good statically typed languages (here I'm thinking a language like Haskell [2] or and ML dialect with a "modern" type system. Something with polymorphic types and type inference, like the Hindley-Milner system (circa 1970's)). What I'd like to do is present another view that many people are apparently unaware of.
If you want you manifesto against static typing to be taken seriously,
here's at least one scenario I think you'd be wise to address: using
the type system to perform "Computer Assisted Programming". This is what
I mean. We know that both static and dynamic languages can be Turing
complete, so we can solve any computable problem in either domain. And
I think that (regardless of type system) most people would agree that
there is a spectrum of program complexity, ranging from trivial, on
though moderate, then hard to understand, ending up eventually at
utterly incomprehensible. (Two people might disagree where to draw the
line between simple and obtuse, but they'll still agree on the spectrum
idea).
Now let's take the set of hard and very hard to understand programs.
Is it conceivable that a sub-set of these programs are hard for humans
to deal with because they require lots of tedious bookkeeping to make
sure that everything works together correctly? Shouldn't we leave the
tedious bookkeeping to the machines and let people handle the high level
concepts? Couldn't an automated bookkeeping system allow for
greater programmer productivity and shift some of those problems
from the hard-to-very-hard domain down into the medium-to-hard domain?
Here's an analogy. Think of the stealth fighter [3]. A conscious decision was made to sacrifice aerodynamic performance in order to achieve a low radar signature. In fact, unlike regular aircraft, the stealth fighter is completely unstable. It requires constant readjustment of its control surfaces to keep it from immediately tumbling out of control. And the adjustments needed are too complicated for the human nervous system to make. But the task can be handled easily with a computer. The pilot makes the high level decision of which direction the plane should point, and the electronic machine makes it happen.
But back to static typing. For a concrete example of a situation with very complicated types that is immensely improved by static typing, I'd take a look at monadic parser combinators [4] like in the Parsec [5] library. It has been my experience that the types involved are complex enough that trying to debug an implementation in a dynamic setting is so difficult that you'd probably be better off trying a different approach. But in a statically typed setting, they work great, since any errors you make are caught at the source of the problem, not when you get a runtime error trying to apply an anonymous closure to an invalid argument after its been passed around through several different functions.
If you say that those situations aren't that widespread, or that trying to use these more complicated programs is bad practice under any circumstance, then fine, make that argument. I personally would be genuinely interested in what you have to say, and we all might learn something from the dialog. But if you're going to trot out the same tired examples to shoot down static typing, be prepared for a yawn and a "seems like you're preaching to the choir" reaction.
(Boilerplate Disclaimer: Let's just get a few standard things out of the way...
- Yes, I agree that it is perfectly possible to create real, working
systems in dynamic languages. - If you want to argue against static typing, shouldn't you argue against one of the best example languages, instead of the weaker ones? Otherwise you might be accused of attacking a straw man.
- Complaints about not being able to write programs like you are use to sounds suspiciously like complaints made by procedural programmers towards object oriented programming. In other words, it seems like that's mostly a problem of not being familiar enough with the style. If you are constantly "fighting" the type system, it may indicate that you are not using it in the proper manner. Maybe you should think of it as a totally different programming paradigm (type oriented [6] if you will).
- If you claim you never (or rarely) make type errors, maybe that's because you're not taking enough risks and pushing the limits? (i.e. you're not using sophisticated enough algorithms and/or data structures). Most economists would agree that in an imperfect world, the optimal number of bankruptcies is not zero. No bankruptcies implies that credit is too tight, and entrepreneurs aren't being allowed to take enough risks (since the successes outweigh the costs of the inevitable losses for the economy as a whole).
- Finally, just for the record, you can (if you so desire) shift your Haskell type errors to run time [7]. And you can have your compile-time meta-programming [8] and runtime eval [9] cake in Haskell and eat it too.