Static and dynamic languages compared

Most dynamic languages will error at runtime when types are used in incorrect ways (JavaScript is a notable exception; it tries to return a value for any expression, even when that value is nonsensical). When using dynamic languages, even a simple type error like "a" - 1 can occur in production. Static languages will prevent many such problems, though the degree of prevention depends on the power of the type system.

Static and dynamic languages have fundamentally different ideas about what it means for programs to be valid. In a dynamic language, "a" - 1 is a valid program: it will begin execution, then throw an error at runtime. However, in most static languages, "a" - 1 is not a program: it won't be compiled and it won't run. It's invalid code, just as the random string of punctuation !&%^@*&%^@* is invalid code. This extra notion of validity and invalidity has no equivalent in dynamic languages.

This is one section of The Programmer's Compendium's article on Types, which contains more details and context.