3 ms·
A counterpoint to your second point is Gall's law: > A complex system that works is invariably found to have evolved from a simple system that worked. A comple
by nordsieck 3y ago
A counterpoint to your second point is Gall's law:
> A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.
https://en.wikipedia.org/wiki/John_Gall_(author) https://en.wikipedia.org/wiki/John_Gall_(author)
At some point, problems are just too complex for any person, no matter how brilliant, to think through ahead of time. The only practical way to make progress on such problems is to implement a simplified version of a solution and then evolve it towards full function. Techniques like test driven development really embrace this idea.
- rramadass 3y agoI don't think this is actually contrary to my point (although it is just a heuristic). People completely misunderstand terms like "upfront design"/"waterfall model" nowadays. It does not mean that every facet of the system is nailed down "completely" before implementation. What it means is that the overall structure of the system is sufficiently clear with proper separation of concerns and modular boundaries to begin implementation. The design is "exact" at a high level but the details would be worked out iteratively. Top-down design and Bottom-up implementation. Dijkstra himself says this w.r.t. "Program Correctness" in his EWD288 "Concern for Correctness as a Guiding Principle for Program Composition". The same idea applies to design (replace "correctness proof" with "design" in the following excerpt). Finally, a word or two about a wide-spread superstition, viz. that correctness proofs can only be given if you know exactly what your program has to do, that in real life it is often not completely known what the program has to do and that, therefore, in real life correctness proofs are impractical. The fallacy in this argument is to be found in the confusion between "exact" and "complete": although the program requirements may still be "incomplete", a certain number of broad characteristics will be "exactly" known. The abstract program can see to it that these broad specifications are exactly met, while more detailed aspects of the problem specification are catered for in the lower levels.
- nordsieck 3y ago> What it means is that the overall structure of the system is sufficiently clear with proper separation of concerns and modular boundaries to begin implementation. The design is "exact" at a high level but the details would be worked out iteratively. Top-down design and Bottom-up implementation. With a complex enough problem, that doesn't work as well as you imply. The architecture that you come up with initially gets compromised by practical considerations. Which is the reason why re-implementations (often caused by changing languages for unrelated reasons) often result in substantially smaller code sizes because the second time around, the architecture is informed by the experience of implementation.
- rramadass 3y ago> With a complex enough problem, that doesn't work as well as you imply. No, the approach of breaking down a problem into smaller manageable pieces and attacking each piece separately in the same manner is universal. This of course will be guided by one's prior knowledge, experience and techniques to manage Risk. See for example the classic; The Spiral Model of Software Development - https://en.wikipedia.org/wiki/Spiral_model https://en.wikipedia.org/wiki/Spiral_model > Which is the reason why re-implementations ... because the second time around, the architecture is informed by the experience of implementation. True; but you don't get to do a re-implementation every time. Hence one has to evolve the system architecture carefully with the the same approach mentioned above.