Here is the bottom line: static typing is getting much closer to the sweet spot by increasingly gaining dynamic typing advantages (e.g. type inference, which means less verbose sources) than dynamically typed languages are going in the other direction.
It's becoming increasingly hard to justify using a dynamically typed language these days.
There are far more compelling advantages to dynamic typing than fewer keystrokes.
Static type checking attempts to use compile time information to make claims about the runtime behavior of a program. This technique obviously fails to the extent that the runtime environment diverges from the compile time environment. Dynamic type checking, on the other hand, has no such limitation: it has perfect fidelity to the runtime environment because it occurs within that runtime environment. Even if the runtime environment itself changes at runtime!
Here's a concrete example. You compile a Haskell program that dynamically links a package. You then install a newer version of the package, which has an incompatible API change. Your program, which reported no type errors, now has a type error (a static typist may not agree this is a type error, but a dynamic typist would assert it is). And if your program starts at all, it will likely fall over and die, because GHC's codegen is brittle against such changes.
Fortunately, we do not suffer this fate on platforms like OS X or iOS, where binaries routinely run on multiple prior and future releases of the OS, with their accompanying shared libraries, while taking advantage of newer features whenever available. ObjC's dynamic typing is a big help here: it's simple to express "call this method, if it exists." And if you call a method that does not exist, you get a readable exception instead of being sent wildly through a random slot in a vtable.
(And oh yeah, having a stable ABI helps too.)
So this is one of the big strengths of dynamic typing: it works even if you don't know where exactly your program will run.
Sorry but claiming that executables written in a dynamically typed languages are resistant to invalid dynamic linking is not just bizarre, it's nonsense.
Either the code you are writing is 100% in the dynamically typed language and it couldn't care less about dynamic linking, or it's invoking functions in a dynamically linked library through an FFI, and it will fail like any other language.
What constitutes "invalid dynamic linking" is ABI and therefore language (and toolset) dependent. In C++, adding or removing a variable or virtual function from a class is an incompatible change: it will break binary compatibility with subclasses. In Haskell, adding a new entry to an algebraic data type also breaks binary compatibility. But in dynamically typed languages, these changes are usually benign.
The binary brittleness of C++ and Haskell is not a direct consequence of their lack of dynamic typing, but it is a consequence of the underlying assumption: that the compile time environment fully describes the runtime environment, and so no provisions need be made for their divergence.
I don't understand your second paragraph. Maybe you think that code written in dynamically typed languages cannot be compiled into shared objects? I work on a large Objective-C dynamic library, which is compiled to machine code and loaded by the dynamic linker, just like a C library. The dynamic aspects of ObjC pay us big dividends.
I've made language choices on quite a few projects. To be honest, I've never specifically evaluated static vs. dynamic typing as one of the major factors in the decision, and I've never seen static vs. dynamic typing become a major point of debate. The discussion typically revolves around pragmatic issues related to existing standards, compatibility with existing software, skills of the team, availability of programmers, etc...
Do you really think the use of dynamically typed languages is an important enough factor to require justification? I don't want to imply that the distinction isn't significant. I'm sure it is. I just haven't had any experiences where it came into play when making a language choice, and I'm curious whether you can elaborate on the need for justification.
> Do you really think the use of dynamically typed languages is an important enough factor to require justification?
Yes, because when you pick a dynamically typed language, you are giving up on important advantages that become crucial as your code base grows, among which:
- Type annotations, which make it easier for newcomers to understand the existing code base (and obviously, catching early errors by the compiler).
- Automatic refactorings, which guarantee that your technical debt remains at a reasonable level since it's so easy to evolve your code base as it grows. Even the simplest refactorings require human supervision in dynamically typed languages (here is a good explanation why: http://goo.gl/SKaos )
Those are consequences of not having static types; they are not consequences of having dynamic types. I have to stick up for ObjC, which has dynamic types, but enjoys the advantages you listed because it also has static types.
It's becoming increasingly hard to justify using a dynamically typed language these days.