Static type checking, regardless of language, requires thinking about programs in a particular way because one possible mode of failure is prioritized over all other modes. It does so regardless of whether absolute type safety deserves to be prioritized given the purpose of a particular program and it does so regardless of whether absolute type safety is an appropriate concern at a particular stage of the program's development.
Static typing can make "how do I get this to compile?" a design criterion Consider year 2038 problem. In MySQL, various date types are coerced to the timestamp type by design. Otherwise the program would not compile. Compilation takes precedence over problem solving.
I've personally found that static typing is an aid to comprehension and thought. I spend more time fiddling with untyped code than typed code. I also disagree that static typing prioritizes a particular mode of failure—the notion of failing to typecheck is a rather general one.
There are two contexts in which one can think about data types. The first choosing among or constructing data types as abstractions. The data type as metaphor is useful regardless of language. An important property of this context is it's not just useful externally via an automobile class in a used car lot application but internally with ports and pipes for I/O and threads and locks and semaphores for processes and so on.
But the other context in which we select and choose and construct data types is because a language insists upon it. Here our choices are not based on how to best represent the world, but by how to package our metaphor into a pre-existing schema. The very first time we compile our code, we have been forced by the compiler to crystallize our code based on an early guess.
When a flat roofed building uses scuppers to provide emergency overflow drainage, it is good if water passing through them makes a mess of the plantings below and perhaps stains the facade. It indicates that the primary drains are clogged before the roof collapses. Likewise, runtime type errors might be preferable to zeros silently inserted into a database.
Static and dynamic typing each catch some types of errors at runtime at the expense of masking other types of errors at runtime.
I think runtime errors are a fine way of detecting such failings. I don't understand why typing is at odds with that.
I think types make us write out the why next to the what. That why might be a domain model justification, or something much more trivial. It's also completely possible to encode an untyped regime in a type system. You're always crystallizing your design, you just can either provide good information to understand its failings and be more prepared to fix them. Or not and chase logic errors throughout an undocumented, dynamic system.
The holy grail of type theory is to write propositions as types and have proofs fall out of those propositions naturally. Those proofs comprise your program. So-called dynamic typing throws that all out the window and just says "I'll permit any program you want to write and bail out at the first opportunity". It's a proposition that is trivially true and thus it's not useful at all.
Static typing can make "how do I get this to compile?" a design criterion Consider year 2038 problem. In MySQL, various date types are coerced to the timestamp type by design. Otherwise the program would not compile. Compilation takes precedence over problem solving.
http://dev.mysql.com/doc/refman/5.0/en/datetime.html