There's also two different (popular) typing approaches: inheritance and structural typing. Each gives you different ways of reasoning about functions and data.
Most of the hangups with static typing seem to come from three problems: Excessive boilerplate, excessive "type purity", and excessive compilation time. I would also argue that a lot of the hangups with static typing come from Java.
Java requires a lot of boilerplate to manage class constructors, etc. However, this is greatly reduced in new languages thanks to type inference.
Java is supposed to be about "pure" OOP, making it very difficult (and slow) to invoke any sort of dynamic method. It can't even type arbitrary methods, once again due to its object-centric focus. However, newer languages are offering more ways of dealing with different type systems, and/or dodging typing altogether in certain cases.
The last problem is with compilation time, which can eat into development time the same way that testing does.
There's newer static-typed languages that are making big improvements across all of these problems. Scala, Haxe, Dart, and Typescript are ways of making development easier for pre-existing platforms... either by relaxing type issues on the jvm, or providing type features for dynamic runtimes (js).
On the other hand, dynamic languages are starting to get very sophisticated linters that are catching classes of errors that are typically found by static typing.
So, in a way, both camps are addressing problems in their own way. I'm primarily in the static camp, but I develop using a lot of dynamic languages, and have been impressed with the tooling and resources available there. However, I see more improvements coming from the new static languages.
My sweet spot these days is Kotlin, which checks on all three points (I use both Scala and Kotlin in IDEA and it's not even close in compilation times).
Most of the hangups with static typing seem to come from three problems: Excessive boilerplate, excessive "type purity", and excessive compilation time. I would also argue that a lot of the hangups with static typing come from Java.
Java requires a lot of boilerplate to manage class constructors, etc. However, this is greatly reduced in new languages thanks to type inference.
Java is supposed to be about "pure" OOP, making it very difficult (and slow) to invoke any sort of dynamic method. It can't even type arbitrary methods, once again due to its object-centric focus. However, newer languages are offering more ways of dealing with different type systems, and/or dodging typing altogether in certain cases.
The last problem is with compilation time, which can eat into development time the same way that testing does.
There's newer static-typed languages that are making big improvements across all of these problems. Scala, Haxe, Dart, and Typescript are ways of making development easier for pre-existing platforms... either by relaxing type issues on the jvm, or providing type features for dynamic runtimes (js).
On the other hand, dynamic languages are starting to get very sophisticated linters that are catching classes of errors that are typically found by static typing.
So, in a way, both camps are addressing problems in their own way. I'm primarily in the static camp, but I develop using a lot of dynamic languages, and have been impressed with the tooling and resources available there. However, I see more improvements coming from the new static languages.