Update: It seems that accidentally typing <?p> will confuse MT's parser, but it won't tell you that the page didn't render correctly when it's actually rendering the thing. Fixed now.
Static typing has taken a lot of stick lately, so I feel the irresistable urge to put forth my views on the subject. That's what blogging's about, after all, inflicting your opinions on the world. (Unless you're a sixteen-year-old goth girl, in which case you should be posting really bad angsty poetry to your Livejournal instead)
Firstly, I agree with Bruce Eckel. Static typing is a form of testing. As a form of testing, it's particularly restrictive on the programmer, and forces the programmer to test all sorts of things they probably shouldn't have to: remembering the unit testing adage that you should only test those things that could possibly break.
There are difficulties, however, with going from that premise, to the conclusion that testing can give you the same benefits as strong typing, but without the disadvantages. The difficulties lie in the difference between testing-through-static-typing, and testing-through-writing-tests.
I'd like to put my theories into practice. While my pre-Java background was in scripting languages, I haven't really put together a significant application in a dynamically-typed language. I've done enough programming to understand and experience many of the benefits of dynamic typing in making the code smaller and more flexible, but I'm not really speaking from a wealth of experience with the alternatives here. I just have my doubts that they're as fantastic as I've heard.
One place where dynamic typing has truly 0wned me, however, has been the Cocoa framework for OS X. Cocoa have shown me that programming a GUI doesn't have to be an exercise in banging my head against a brick wall, it can actually be fun. A lot of the flexibility of Cocoa comes from the dynamic nature of Objective-C. If you've got a Mac and you haven't learned Cocoa yet, set aside a week to go through a tutorial or two. You won't be disappointed.
Anyway, back to my defense of static typing. You knew it was coming.
Static typing is declarative. Testing is procedural. Thus, when your program fails through types, the exact location of the error can be immediately ascertained: it's the point at which your type declaration becomes untrue. When your program fails a regular test, you only find the point at which the testing procedure detects the resulting misbehaviour.
To Java programmers, think of chasing down NullPointerExceptions. Usually it's quite easy, but because the error (dereferencing null) can happen a long way from the actual bug (assigning the value to null in the first place), it can take a lot of time to track down the cause.
This isn't really so much of a problem in the normal course of writing an application. Assigning null to a variable is far more common than assigning the wrong type entirely. To paraphrase someone whose identity I have forgotten, who was arguing against the usefulness of generics in Java, “I find I almost never put an orange in a bag of apples anyway”. Where it becomes important is during refactoring. When changing method signatures or moving behaviour between classes, it's very nice to have immediate feedback on exactly which lines of the program are effected by the changes.
The other reason I tend to steer towards statically typed languages for my own projects puts me in agreement with Carlos. In a dynamically typed program, it's easy for a human to tell what type something is likely to be, but no way for a machine to say for sure what type something is. Thus searches, code-assistance and refactoring tools for dynamically typed languages must, at some point, guess. These are all tools I rely on frequently, and want to work with as little of my interference as possible.
I'm aware the Refactoring Browser originated in Smalltalk. What I fail to understand is how truly automatic refactoring is possible when types are indeterminate.
Being able to discover precisely where (or if) a type or method is referenced is invaluable. A text-search can help, but you must sift through the false-positives yourself. This requires a certain familiarity with the code, and as the code-base gets bigger (or your familiarity with it wanes for some other reason), that sifting takes longer and longer.
I work on my own, personal projects maybe one or two days a week. I tend to have four or five hanging around, so some will go months without me looking at them. When I return to a project after that amount of time, the information that the IDE can glean from the type system is invaluable.
On the other hand, my couple of Ruby projects languish far longer, because it ends up being a lot harder for me to pick them up after a long absence, because I have forgotten all the type information that is implicit in the program.
The IDE's understanding of types can also cause it to save me at least as many keystrokes as the type information causes me to endure. For example, when auto-completing a method, Eclipse will check the local scope for objects of the same type as the arguments, and include them in the completion. Similar guesswork is performed when using macros to generate loops. IDEA has similar features. It will even recommend simple variable names for me based on their type.
It's also amazing how quickly you can remember the workings of a half-forgotten API with a sketchy glance at the documentation and an IDE with type-informative code-completion.
As far as I'm concerned, the more things I can make the IDE remember or do for me, the more my mind is able to concentrate on more important things that it can't do, like writing the program itself.