I feel like I haven't pissed anybody off in a while, so it is time to write another "controversial" post. This time we'll revisit the old dynamic vs. static typing debate, mainly because I was walking around and it popped into my head (this is how many blog posts get written).
This time though, I won't pick on any specific languages. Instead let's take language S which is statically typed and language D which is dynamically typed (ignore the fact that there are actual languages with these names, just pretend those don't exist for a moment). Let's also say that these two languages are identical in all respects except for this single fact - the argument of whether or not this is possible can be saved for another day, so again I ask that you pretend that it is possible. Also assume that they are both strongly typed.
In this situation I would argue that S is a better language than D. Why? Well, because static typing gives you tests for free. The compiler will check to see if all the types match up like they are supposed to, so that you don't end up adding an integer with a network socket or something ridiculous like that. In D the check will also be done, but it will be done when the code is executed instead of at compile-time. This is normally a bad thing, so we write automated testing suites to catch this kind of bug.
All this is obvious so far (or at least it is to me). Why am I talking about it? It's because sometimes when I talk to dynamic-typing enthusiasts they tell me that the compiler-check is overrated and that if you have a good testing suite then you're just as well off. Sometimes they even say that the testing approach is even better, since you should be writing tests anyway.
The problem with this argument is that it ignores the human factor. Writing tests is optional, making the code pass a static-type check is not. Therefore writing tests requires programmers to have discipline. This is not a good thing, because many times the programmers don't have the discipline, or they get lazy, or they have a deadline to meet and the thing that gets scrapped is the test suite. Therefore you can have typing errors sneak in which would have otherwise been caught by the compiler.
So what is the problem with my argument? I'm still assuming that S and D are identical in all respects except for the nature of their typing. This is a bit of an idealized scenario (I blame it on the fact that I'm back in school, where "real world issues" sorta fade into the background and you get a nice clean thought-experiment environment where unexpected things don't happen). In real life, there aren't many languages that are equal in all respects, so we can't really compare two languages on their type systems alone. Instead you would have to have some sort of empirical analysis to measure productivity based on the typing systems of the languages, while accounting for other technical factors like expressiveness, presence of a REPL, available tools, etc. and human factors like ability, team size, etc. (I'll be posting another stats article on omitted variable bias/confounding soon which will address a major issue in statistical analysis).
Anyway I deviated a bit from the main point that I want to get across. Testing is not a replacement for a static type check because it requires programmer discipline/effort/time to implement it, and it is optional. Therefore there will be times when it will not get done where a static type check will always be done (in a statically typed language anyway). So if you want to argue that dynamic language D' is better than static language S', you'll have to argue other features of D' than the typing system (from my anecdotal experience, I believe that it is the expressiveness of the dynamic languages I've used that make them more productive than the statically-typed languages I've used, not the type system - using Scala seems to confirm this, since a lot of my Scala code seems to be about as long as my Ruby/Python code).