4 ms·
The only thing I disagree with in this article is the leeway given to supposedly legendary programmers who can somehow write bug-free code without tests, specif
by agentultra 9y ago
The only thing I disagree with in this article is the leeway given to supposedly legendary programmers who can somehow write bug-free code without tests, specifications, or an inkling of communication with others.
First, it's probably not true. Linus Torvalds is not a legendary human being who can write critical systems without a single flaw. He relies on legions of human beings to carefully check and review every line of code before he even looks at it. There are discussions on mailing lists. There are arguments and disagreements. There's a process there. He doesn't just flit his fingers across the keyboard and output amazing, error free code. It probably has tonnes of errors.
Linus' philosophy is that errors aren't the end of the world and someone will patch them when they are uncovered.
For some use cases that's fine. However there are plenty of applications where a more proactive approach to correctness is necessary: real-time systems, safety critical systems, and yes... even security.
Maybe TDD is a misnomer. I think we should call it specification driven development. Unit tests and integration tests are just a weak form of specification. They provide theorems in the form of examples that we try to prove with an implementation. Property based tests give us more examples to quantify assertions over. Model checking can test liveness as well as safety in our high-level designs... how much you need to specify and how thoroughly really should be a factor of the risk and complexity present in the requirements of the system.
To use an analogy: blueprints. If you're just building a shed or a small footpath then it's enough to sketch your idea on a napkin. If you're building a house you need to have a more specific and detailed plan that passes by a civil engineer. And if you're building a sky scraper then you need to be thorough and able to convince others of the validity of your designs.
(credit for the analogy should go to Leslie Lamport).
I think most software projects are at the house level in terms of risk. You could get by with using a dynamic language and a few unit tests if you value productivity more than correctness. That just means you're willing to accept that you will have higher reported error rates and are comfortable with potentially losing customer data or a higher risk for security vulnerabilities. You can lower your risk if the project requires more sensitivity to data consistency or security by using a sound type system and encoding your assertions at the type level, add some property-based tests, and more integration and unit tests. It's a spectrum one should consider.
I know we all like to write code and sometimes we even hear ourselves saying, "Well if you wrote the perfect specification you might as well have written the software," but don't be fooled.
"Software engineering is the part of computer science which is too difficult for the computer scientist." -- Friedrich Bauer
- hwayne 9y ago> The only thing I disagree with in this article is the leeway given to supposedly legendary programmers who can somehow write bug-free code without tests, specifications, or an inkling of communication with others. I absolutely agree with your disagreement here.
- pwm 9y agoNot disagreeing with your overall message, just want to point out something that bugs me and you're not the first one I heard saying something like this: "They provide theorems in the form of examples". This is incorrect. Theorems are deductive while test are experimental and this is a crucial difference in my opinion. To give and example: say we have our function isDAG :: Graph -> Bool, which determines whether a graph is a DAG, and we want to _prove_ that it works then no amount of experimental test cases will be sufficient. In real life, however, most of us (including me) settles for having _some_ confidence in the correctness of our code by utilising tests.
- agentultra 9y agoYou're absolutely right. Thanks for pointing that out. I was using theorem and proof as an analogy to illustrate the separation of specification and implementation. A useful distinction as you get further along in writing formal specifications. Update: typo.
- AnimalMuppet 9y agoI think it's more than just "specification driven development". The question is, does your code match the specification? What is your objective evidence that it does? (Yes, I know, a test is not perfectly objective evidence. It's better than "looks like it should work", though.)