3 ms·
We want to identify and fix problems as early as possible; ideally, before we even write them. Problems cost exponentially more to fix the later you catch them,
by feoren 3y ago
We want to identify and fix problems as early as possible; ideally, before we even write them. Problems cost exponentially more to fix the later you catch them, and the damage they can cause only grows with time. Static typing lets you identify problems earlier than dynamic typing, full stop. In fact I'd rather have strong static typing and 0% test coverage than dynamic typing and 100% test coverage -- in the latter case, I'm catching problems much later, and I have the maintenance burden of all those tests, 70% of which are only there to catch what static typing would have already found.
The best mix for me is to lean heavily on the type system and only lightly on tests, trying to write code that is simple and "obviously correct". Obviously-correct code has already had its problems ironed out in the first 6 or so bullets below, and there is very little room for further bugs to hide. Of course even "obviously correct code" can actually have bugs or be subtly incorrect -- a better definition is that any surprises in such code would also be surprises to the tests. The tests are nothing more than mirror images of the code, and therefore are not helpful or necessary. Static typing helps me think about the problem clearly, and helps me write "obviously correct" code.
Here's my working list, in order of preference of when I'd like to find the problem. Every time you drop down this list, the cost to fix the problem gets multiplied by some small factor ~1.5 to 3.
- Initial ideation ["Facebook for dogs? That idea sucks."]
- Requirements analysis ["That's not actually how we calculate that metric."]
- Conceptual system design ["Wait, these parts don't fit together like that."]
- Low-level design ["Crap, a loop won't work here, I need a different flow."]
- Brain-to-fingers typing ["Whoops I almost typed 'elesif'"]
- Immediately post-typing [Red squiggly line under 'elesif']
- Re-reading ["Wait that should be i-1, not i"]
- Compile time ["SYNTAX ERROR: Unknown identifier 'elesif'"]
- Unit test time ["Assertion failed: expected 7, got 8"]
- Code review time ["You didn't handle the case where N is negative"]
- Merge / integration test time ["Oh crap, David's commit broke my commit! How the hell do I merge this?"]
- Internal manual testing time ["You need to tighten up the graphics on level 3"]
- Production ["The users say the application keeps crashing when they run this report! Fix it!"]
- Years later/never ["It turns out that the analysis code we've used for the last 10 years had a major bug in it the whole time and we've been giving wrong numbers to a regulatory agency that has the power to shut down our company."]
- boxed 3y ago> Problems cost exponentially more to fix the later you catch them, and the damage they can cause only grows with time. Citation needed. This is ENORMOUSLY context dependent. Enough to invalidate the entire point. My day job is writing code that runs on a server I control. Mistakes there are super cheap to fix. I get a nice crash in sentry with stack and variables for all frames, I fix it, deploy. Done. If I was shipping code to Mars, well that's the opposite situation. CONTEXT MATTERS
- feoren 3y ago>> Problems cost exponentially more to fix the later you catch them, and the damage they can cause only grows with time. > Citation needed. Really? Isn't this one of the most clear and repeatedly demonstrated facts in all of software engineering? We don't have a whole lot of clear-cut demonstrable facts in this industry, but this is absolutely one of them. How about this 2002 NIST report, Table 1-5 on page 1-13 is "Relative Costs to Repair Defects when Found at Different Stages of the Life-Cycle" and shows 1X at "Requirements", 90X at "System Testing", 440X at "acceptance testing", and up to 880X at "operation and maintenance". (Warning: 300-page PDF) https://www.nist.gov/system/files/documents/director/planning/report02-3.pdf https://www.nist.gov/system/files/documents/director/plannin... You can find thousands of people saying the same thing from their personal experience with a quick Google. On the list of uncontroversial statements about software engineering, this is right at the top. Is our discipline so immature that we can't even agree on this extremely basic fact? Another (okay, they don't say "exponential" here, or try to quantify it at all): > The cost of finding and fixing bugs or defects is the largest single expense element in the software lifecycle. ... The earlier in the development lifecycle defects are found, the more economical the overall delivery will be. The Cost of Poor Software Quality in the US: A 2020 Report, Consortium for Information & Software Quality https://www.it-cisq.org/cisq-files/pdf/CPSQ-2020-report.pdf https://www.it-cisq.org/cisq-files/pdf/CPSQ-2020-report.pdf > My day job is writing code that runs on a server I control. Mistakes there are super cheap to fix. That's good to hear, but mistakes caught before they get to your server are even cheaper still. Perhaps your exponential factors are smaller than NASA's, but it still clearly costs you much more to fix a problem that made it to your production server (and possibly impacted your users) than to fix it immediately after typing it because your IDE showed you a red squiggly line.