Let's talk about this. First of all, every language has undefined behavior, unless you mean ML, which is fully defined. That's part of the reason the NICTA team proved that the assembly output from the compiler matched the specification. You might have a point there, but you'll need to say it more clearly.
Okay, let me rephrase: the less undefined behavior in a programming language specification, the better. Programming is already a complex task -- having to worry about the hundreds of undefined behaviors in the C family of languages is a nontrivial burden.
I'm referring to things like running off the end of an array and incorrectly set pointers resulting in damaged program state. This can be very hard to debug because often the system keeps running, and where you see the error can be far, far removed from the bad code that damaged program state in the first place.
Static typing because the compiler will error instead of errors at runtime.
Strong typing so that hidden promotions don't result in unexpected behavior -- the programmer will be more likely to stop for a moment and think about it.
In my experience, dynamically typed programming languages like Python don't scale (to large teams) or refactor well, and there's the ever present danger of runtime type failures.