Error Checking with Dynamic Typing
Since the types of variables isn’t known until you’re actually running the program, you won’t know ahead of time if you called a function with the wrong number of arguments or if you tried to take the square root of a string.
The problem with this argument is that even when using a statically typed language (like C++), there are still all kinds of problems that won’t be discovered until run-time. For instance an off-by-one error in a loop, using an uninitialized variable, or any type of logical error. So while compile time reporting of type errors is helpful, it’s not sufficient.
The way to catch these types of problems at “compile time” is to have a suite of unit and functional tests that exercise all of the code’s features. These tests can be run every time you compile, check-in or make a refactoring to ensure that the code is working properly.
Writing unit tests takes programming time, while static type checking happens automatically. Fortunately, you don’t need to write explicit type checking tests, since the functional tests will do this implicitly.