Let me argue the following standpoint: programming is hard, algorithms are hard, and compile time type checks are not much more than spell correctors.<p>Any algoritm operates and creates state. It is nice your statically typed language prevented you to add your socket file descriptor to an int. So you fix your 'typo' and add the index of the file descriptor (assuming your open sockets live in an array, or similar scenario). But what if your algoritm requires you to do a subtraction? You still have a bug.<p>No type check can check runtime dependent data. You pass in a List but the list requires to be at least of length 2? (Actually you some languages can tackle this too, but these sort of requirements become arbitrary complex.) You will deref the list out of bounds and you have a bug.<p>So now I just sketched two scenario's where you still need to actually run your program to catch bugs. And your type system did nothing.<p>A very certain kind of bug -- mostly typo's or slightly higher level mistake -- are caught by a static type systems. The question is, is this worth the restricted semantics of the language?<p>The advantage of a static type system is clear; these mistakes are caught where and when they are introduced, not where their result is used.<p>The disadvantage is also clear: restricted semantics. How would macro's look for lisp if it had type checks?<p>Without types, your language is better at creating macro-like abstractions. You can capture patterns with these, and prevent a lot of typos that way. (And a write a lot more concise code.)<p>And even more, think about Java's performance hit on ArrayStoreException ... So even such statically typed languages need to do runtime type checking more often then you would like.