> It’s interesting to ask how we can bring development costs down without compromising quality; in my world, it’s not at all interesting to talk about strategically reducing quality.
You have some level of quality ya'll are used to, that was already achieved by compromise, and you'd like to stay there. How was that original standard established?
On an exponential graph of safety vs effort (where effort goes up a lot for small safety gains) you are willing to put in a lot more points of effort than general industry to achieve a few more points of safety.
> You have some level of quality ya'll are used to, that was already achieved by compromise, and you'd like to stay there. How was that original standard established?
Safety-critical code for aviation co-evolved with the use of digital systems; the first few generations were directly inspired by the analog computers they replaced, and many early systems used analog computers as fallbacks on failures of the digital systems. These systems were low enough complexity that team sizes were small and quality was maintained mostly through discipline. As complexity went up, and team sizes went up, and criticality went up (losing those analog fallbacks), people died; so regulations and guidelines were written to try to capture best practices learned both within the domain, and from across the developing fields of software and systems engineering. Every once in a while a bunch more people would die, and we'd learn a bit more, and add more processes to control a new class of defect. The big philosophical question is how much of a washout filter you apply to process accumulation; if you only ever add, you end up with mitigations for almost every class of defects we've discovered so far, but you also end up fossilized; if you allow processes to age out, you open yourself to make the same mistakes again. To make it a less trivial decision, the rest of software engineering has evolved (slowly, and with crazy priorities) at the same time, so some of the classes of defect that certain processes were put in to eliminate are now prevented in practice by more modern tooling and approaches. We now have lockstep processors, and MPUs, and verified compilers, and static analysis tools, and formal verification (within limited areas)... all of which add more process and time, but give the potential for removing previous processes that used humans instead of tooling to give equivalent assurances.
Thanks for writing this (just a generally interesting window into a rare industry). As you point out, you can't only ever add. If there was a study suggesting that static types don't add enough safety to justify tradeoffs, you might consider phasing them out. In your industry, they are currently acceptable, there's consensus on their value. You probably have to prioritize procedure over individual developers' clarity of perception (because people differ too much and stakes are too high). That's fair, but also a rare requirement. Stakes are usually lower.
> If there was a study suggesting that static types don't add enough safety to justify tradeoffs, you might consider phasing them out.
Perhaps. Speaking personally now (instead of trying to generalize for the industry), I feel like almost all of the success stories about increasing code quality per unit time have been stories about putting defect detection and/or elimination left in the development process -- that is, towards more and deeper static analysis of both requirements and code. (The standout exception to this in my mind is the adoption of automatic HIL testing, which one can twist as moving testing activity left a bit, but really stands alone as adding an activity that massively reduced manual testing effort.) The only thing that I can see removing static types is formal proofs over value sets (which, of course, can be construed as types) giving more confidence up front, at the cost of more developer effort to provide the proofs (and write the code in a way amenable to proving) than simple type proofs do.
The most important ingredient by far is competent people. Those people will then probably introduce some static analysis to find problems earlier and easier. But static analysis can never fix the wrong architecture and fix the wrong vision.
In the industries I've worked, it's not a huge problem if you have a bug. It's a problem if you can't iterate quickly, try out different approaches quickly, bring results quickly. A few bugs are acceptable as long as they can be fixed. I've even worked at a medical device startup for a bit and it wasn't different, other than at some point there need to happen some ISO compliance things. But the important thing is to get something off the ground in the first place.
> The most important ingredient by far is competent people.
Having competent people is a huge time (cost) savings. But if you don't have a process that avoids shipping software even when people make mistakes (or are just bad engineers), you don't have a process that maintains quality. A bad enough team with good processes will cause a project to fail by infinite delays, but that's a minor failure mode compared to shipping bad software. People are human, mostly, and if your quality process depends on competence (or worse, on perfection), you'll eventually slip.
You'll slip and regain your footing a few hours later without much loss in most industries.
Right, but I hope you also understand that nobody's arguing for removing static types in your situation. In a highly fluid, multiple deployment per day, low stakes environment, I'd rather push a fix than subject the entire development process to the extra overhead of static types. That's gotta be at least 80% of all software.