I used to feel this way, but the benefits of a good type system far outweigh the drawbacks IMO. A lot of runtime errors caused by dynamic types get pushed back to compile time, which is a much safer and easier time to deal with them. Nowadays writing code without type checking feels like building a house on quicksand.
There's also the self-documenting aspect of strongly typed languages: for instance, if I look up the documentation on a javascript API, I have to hope function parameters have been specified well, otherwise I just have to guess what should be passed in or dig through the source. With a strongly typed language I probably get that information as part of the autocomplete hint.
And good type systems can be powerful tools. In Swift for example, the protocol system is powerful enough that I'm sure it results in writing less code overall, not more.
>But why don't they? Aren't the problems nearly the same? And if not, how?
Concrete example: Common Lisp is very strongly typed. So it almost never automatically converts from type to another, except when it makes total sense (i.e. the square root of -1 will return a complex number).
So, if there is a type mismatch, it will be caught (at runtime) raising an exception. Now, you would think "yeah but my statically typed language will check this BEFORE the code runs". Yes, but in Lisp, the exception doesn't terminate the execution, it enters a mode in which the system asks you what to do next.
Thus, what you do is, you go back to the source code, to the function with the error, you correct that specific function, compile that specific function (which happens almost instantly), and then resume execution of your program. This means that the previously "invalid operation" will be run again but with the new definition of your function, thus the code will continue running without said bug.
Python has the dynamic typing problems, but is better because it has a somewhat strong type system. It will tell you when it's wrong, but often too late (oh this function only gets called wrong once every 100h on my server, thank you for telling me now that it went wrong). And sometimes different types can duck into the same function (e.g. string and list are both iterable).
So yeah, Python suffers from the same issues when you want to scale your code, but it's A LOT less bad than JavaScript.
There's also the self-documenting aspect of strongly typed languages: for instance, if I look up the documentation on a javascript API, I have to hope function parameters have been specified well, otherwise I just have to guess what should be passed in or dig through the source. With a strongly typed language I probably get that information as part of the autocomplete hint.
And good type systems can be powerful tools. In Swift for example, the protocol system is powerful enough that I'm sure it results in writing less code overall, not more.