6 ms·
> The two examples are human errors easily avoidable by reading the documentation. Okay, but that doesn't answer the question. We're in dynamic typing world; m
by mjr00 4y ago
> The two examples are human errors easily avoidable by reading the documentation.
Okay, but that doesn't answer the question. We're in dynamic typing world; my method accepts any data type by design. What's the expected behavior when it doesn't receive the expected type? Do I add assertions and fail with an assertion error? Let the runtime fail for me? Silently convert the type? In any case, I need to add a test for that.
If your answer is "humans shouldn't make a mistake when calling the method," that's arguing for static typing, not against, because that's exactly what static typing prevents: a human making a mistake. Turns out static typing makes for a really good baseline level of documentation, as well.
> And some mechanism that uses types like method overload should be transparent from a behavior perspective.
Your method might work today for both a dict and a dataframe because it's only using simple accessors. But what if someone wants to go back and change it and they use something that's only on dictionaries, like the * operator? Your code would fine, your unit test cases probably all use dictionaries so they're fine, and it's only when you deploy to production and find out that someone's code elsewhere was incorrectly passing in a Dataframe that just happened to work, no longer does.
Static typing has a solution for behavior-based types too, they're called interfaces. Even better in languages like Go and Python (with Protocols) that use structural type checking for interfaces, rather than explicit interface implementations.
- skydhash 4y ago> In any case, I need to add a test for that. You don’t test types. If you have a ‘trim’ method that accepts a string, you don’t unit test it with an array, unless you plan to add a test for every possible types. Static typing can help prevent a human calling it with the wrong type, but won’t prevent calling it with the wrong runtime values, like after casting an Any to string. Static typing do syntax check, not runtime check. When I’m talking about testing behavior, it’s about testing that the code does what it’s supposed to. Not what the arguments is. So you test that ‘trim’ works on all strings, including empty. What static typing helps in checking assumptions when programming, but every bet is off when executing. Especially when interacting with the outside world. If someone changes the code, it’s on them to notify everyone about breaking changes. If the documentation says that the method accept dict, and you call it with dataframes, it’s on you to check that it will continue to work with dataframes, not on me to ensure that someone is calling it with dataframes if I use specific code related to dict.
- mjr00 4y ago> If someone changes the code, it’s on them to notify everyone about breaking changes. If the documentation says that the method accept dict, and you call it with dataframes, it’s on you to check that it will continue to work with dataframes, not on me to ensure that someone is calling it with dataframes if I use specific code related to dict. This is equivalent to re-implementing static types and a compiler with human processes. This isn't scalable.
- skydhash 4y agoMaybe, but using static types is not a panacea either. It only make it easier to assume that someone have correctly constructed the value and that all manipulation have been correct so far. The type checker helps by checking that if the assumption is true, everything down the line is also true. But only in the context of the code, not in the context of the process itself, where the assumption may be incorrect, or the chain is broken somewhere due to bad logic (that’s when off-by-one errors arise). Nothing is a silver bullet. Static types can make life easier by preventing some meaningless code, but they don’t ensure correct programs.