Tuesday, August 18, 2009

Static is only missing an N

So, I said that some folks might not be interested in static analyses like type correctness, or const correctness, or god knows what. And, to be honest, I can't blame you (too much), because in a lot of popular langauges the available static analyses (the type system, in most cases) isn't that great. Maybe it isn't powerful enough to encode useful properties (C, anybody?), or maybe it is powerful enough if you really want it to be, but everyone sort of ignores it because its more trouble than it's worth. Anyway, lot's of people aren't all about static typing, are all about dynamic typing, and will kill you with an ASCII blade if you disagree. On the other hand, some people love static typing, and static analysis in general, more than they love their own aged grandmothers. They will fight you (and any passing dragons) to the death with the dual weapons of dataflow analysis and syntax directed translation. Or something.

Anyway, the point is that I'm about to jump into the fray, so to speak, and try to convince you that thinking about static typing for a language like Mix is really a good idea. So, away we go!

First, there are a number of reasonable complaints about the static type systems of popular existing languages (clearly this list isn't even close to exhaustive, but it hits a few):

  1. They require a ton of extra code (everyone say "Java" with me).
  2. They can be subverted, making them not particularly useful (C's type system accepts code that will set you on fire; CCured is an interesting attempt to provide you with a fire extinguisher by translating flamable C to safe(r) C).
  3. They limit your freedom as a programmer, making programming slower.
  4. Their usefulness is subsumed by runtime tests.

Ok, lot's of arguments against static typing. The first one I'll give away: lot's of languages have got it "wrong" according those voicing this particular complaint. But, others have gotten it right (I'm thinking O'Caml, Haskell, F#): type inference can save a language from failing this early in the game.

The second one we can give away in the same fashion: Java, C, C++, and all kinds of others share this problem, to varying degrees: in Java you can get a ClassCastException, and in C you can cause a core dump. But again, there are plenty of languages whose type system you cannot subvert to cause runtime problems, so stronger static typing could save us from this failing as well.

The third one is were the complaints start "getting real", to quote someone or another. Basically, the idea is this: when you're programming, especially during the early phases of a project, or when you're really just "exploring the solution space" (buzzword!), or doing rapid development, types can make your code less flexible. It can take longer to twist things, experiment. There's all kinds of inertia to the code, damnit. Well, again this can be true. Here's my argument: if there isn't any manifest typing (in the form of type annotations), and you have a "good" type system, then changing your program around in this manner should only ever irritate the type checker when you've actually done something wrong, which is exactly what you want, right? Of course, the problem becomes defining "good"; that's what this blog is about.

The fourth one is tricky as well. I read about this one in a book edited by Joel Spolsky called The Best Software Writing, in a piece by Bruce Eckel; go read this if you haven't (only takes a minute). Back already?

Ok, so the argument is that you're already writing tests (right?), and they already check all of the things that the type system checks, and more, so why bother with static typing? Good point, certainly. But, this seems to rely on 2 basic facts, at least 1 of which must be true.

  • Using a language with static typing costs something.
  • Dynamic typing saves that same something (time, or money, or whatever).

Hopefully the above (points 1 through 3) has convinced that, while the first bit can be true, it doesn't have to be. As for the second bit, it's predicated on the assumption that you can't have a statically typed language that saves you the same something in most cases; we'll see about that!

So, if you take all my claims as true, you might be wondering why I went through all that trouble only to basically show that static and dynamic typing are more or less equivalent. Because that's the result of point 4 above, right? Well, here's where I'm going out on a limb to give static typing the edge (under certain conditions, but don't worry, dynamic typing gets to win, too; we're all winners here). In my personal experience, most of the features of dynamic languages that I use regularly could (probably) be incorporated in a sbuitably designed static type system (of course, things like eval aren't in the "most" I'm talking about; if you need stuff like that then dynamic takes the game).

Not much content here, but maybe if you were on the fence before you'll hear me out going forward.

No comments:

Post a Comment