5 ms·
> which led them to break in very (very, very) ugly ways due to unrelated changes. Sounds more like a problem with tight coupling than a problem with types per
by goto11 4y ago
> which led them to break in very (very, very) ugly ways due to unrelated changes.
Sounds more like a problem with tight coupling than a problem with types per se. A function should not change behavior due to an "unrelated change", regardless of static or dynamic typing.
- Yoric 4y agoLet me give you a trivial example (with TypeScript-style syntax, but assuming no TypeScript-style type-checking): ``` function foo(config: {hasYakShaver: boolean}) { if (config.hasYakShaver) { // ... } else { // ... } } foo({hasChuckYeager: false}); ``` This will accidentally do what I want, but for bad reasons. And one day, quite possibly, a change that appears unrelated will break this. And that's me being nice. If I start using reflection to do complicated stuff, or if I'm using C++ and the reason for which my code works is memory corruption... well, when I need to figure out what suddenly broke the code, I'm going to be up for serious a moment of loneliness.
- goto11 4y agoSure, static typing will catch such issues. But there is still no guarantee that the foo function (or the function calling foo) works correctly just because it passes the type checker. If you have unit tests (or other types of automated testing) you have a much bigger chance of catching logical errors and it will also catch trivial error like misspelling an identifier.
- Yoric 4y agoI was responding to > Testing for the correct behavior should be enough. Also, in my experience, automated tests tend to catch many bugs, static typing also catches many bugs and defensive programming catches many bugs, too. There is an intersection between all three, but it's by no mean 100%. So I use all three of these. And of course, let's not discount monitoring, fuzzing, etc.