People always say this and it baffles me. Bugs like that should be caught immediately by your test cases. You shouldn't rely on the compiler to catch them for you.
I worked on a small Python project some years ago and we had a type error in production despite having tests.
We traced it back to a call to a third party library. It was supposed to return a list of results, and all of the test cases around it worked and always got a list back. In production however we encountered an error because if there was only one value to return, the library would not return a list of one element, as we expected, but a scalar value. So the rest of the code was expecting a list and when it encountered a scalar it blew up.
You can blame it on us for having insufficient test cases, or not coding defensively enough, or not reading the source code of the library we used, or the author of the library for bad design, but ultimately, this bug would not have been possible in a statically typed language.
So just saying "have test cases" is not good enough. Your test cases can be not exhaustive, but a good static type system and type checker is.
That's the whole point: as it's often said "type checking keeps you honest"
I stumbled time and time again upon badly designed libraries... With a static type system, the painfulness will be obvious and felt the first time you'll try to build your code
with dynamic types, the pain might not be felt at all, until a crazy bit of code will be invoked, sometimes at the most unfortunate of times
That's the one. That's a damned stupid decision.
By adding sanity checking asserts in a dynamically typed language you can achieve more or less the same result.
Yes. We call that 'typing'.
I see all too often, java bad, just look at how many lines you need to write to get "hello world". Who cares, the IDE generates that for you, but if you don't understand static void main as a beginner... again who cares, just put it in and ignore it until you need to understand it. Also read that dynamic languages are so productive, but they never mention you need to then write tests to detect what the compiler would catch for free. Yes good code needs tests, but the compiler IMO is a damn good built in test suite for catching many classes of errors
What's wrong with relying on the compiler? Bugs like that will be caught immediately by a good static type system, so you don't have to rely on your test cases to catch them for you.
Relying on a test suite to verify basic properties that could be enforced automatically through a type system means you're only checking some cases instead of all cases. It also means you're cluttering your test suite with boilerplate about language mechanics instead of writing high value tests that verify the real operational behaviour of your system.
There are pros and cons to static vs. dynamic typing in general, but in this particular respect, static typing is strictly more powerful, less verbose and more efficient.