5 ms·
Say you have a python function that expects a dictionary, but instead a string gets passed in. At some point in the function the python function may or may not
by mey 4y ago
Say you have a python function that expects a dictionary, but instead a string gets passed in. At some point in the function the python function may or may not explode at runtime depending on how it's written. If your functional tests doesn't cover this scenario and you haven't guarded for invalid data types in your python code, you may never see this issue until it hits production or a refactoring of the code base is done.
Ok, now that entire scenario goes away with a language that has a compilation phase and has type enforcement. It's boiler plate inside the function for type validation your don't have to do inside the python function (or blame the caller) and a testing scenario(s) you don't have to write. That's the work I'm talking about.
- ReflectedImage 4y agoIn practice, the function will be called indirectly via an API with types and there will be at least 1 unit test. Therefore the scenario is ridiculously unlikely and lives in the realm of fantasy.
- goto11 4y agoThe bug is in the function which passes a string instead of a dictionary. Presumably this function will work incorrectly, right? So the unit tests of that function will find the error. Unit tests which verifies a function has the correct behavior gives you "type checking" for free. You just have to shift the mindset to testing behavior instead of testing types.
- int_19h 4y agoThe problem is that the function may work incorrectly by e.g. quietly causing an invalid state change. For example, that string that was passed instead of an integer gets stored somewhere. Nothing visibly breaks; it's just that later - possibly much later, and in code much removed from where the bug actually is - you reach for what you expect to be an int, but get a string instead. Good luck debugging where it went wrong.
- goto11 4y agoYou can also have bugs in statically typed languages. Perhaps not the trivial bug of passing a string instead of a number, but you still can have the (more likely) issue of passing the wrong number, i.e. a logical error. Lets say `add(a, b)` contains a bug. Perhaps it doesn't handle negative values or overflow correctly or something else. But it still returns a number, just the wrong number. This kind of bug is much more likely. If this wrong number is stored somewhere you also might get obscure errors down the line and a static type system will not discover it. And this bug will be much more insidious and harder to track down. So you need unit tests anyway to protect against logical errors. If a unit tests verifies the behavior of a function it will also implicitly verify the types without any extra work.
- int_19h 4y agoThe case you describe is handled by some form of checked types. In Ada, I'd just declare the range and let the compiler handle it. In a more conventional OO language, I can have a wrapper type for that number which enforces all constraints in the constructor. Either way, the point is that things blow up as soon as possible. Broadly speaking, this is the contract-based approach: at every data flow boundary, explicitly describe your contract, so that any violation can be detected immediately instead of propagating and poisoning derived state. Eager type checking is just a subset of that, true. That means that static typing is not enough, not that it's unnecessary. OTOH unit tests cannot fully express contracts, because even with parametrization you can only test so many of the possible inputs.
- goto11 4y agoHow do you define a contract which guarantee that the result of `add(a, b)` is correct? Not just that the result is a number, but that it is the correct number? Of course `add()`is a silly example since this is already a built-in in any language, but consider a function `calculateSalesTax(product)` - how do you define the contract which guarantees the result is the correct number?
- 4y ago