* Tags:: #🗞️Articles , [[Software Architecture]], [[My engineering management principles, values, and practices]] * Author:: [[Frederic P. Brooks, Jr.]] * Link:: [No Silver Bullet Essence and Accidents of Software Engineering | IEEE Journals & Magazine | IEEE Xplore](https://ieeexplore.ieee.org/document/1663532). Probably easier to read in the [[📖 The Mythical Man-Month. Essays on Software Engineering, Anniversary Edition]] compilation. * Source date:: [[1986-01-01]] * Read date:: [[2020-08-10]] ## Summary >How much of what software engineers now do is still devoted to the accidental, as opposed to the essential? (p. 180) Brooks thinks that most work comes from the essential complexity (problem specification), and because of that, he believes that in the decade to come, there will be no single development responsible for an order of magnitude improvement in development productivity. 10 year later, in 1995, in his review of these ideas, he still thinks there are no breakthroughs around the corner. So, he quotes [[R. L. Grass]] (1988): >It is time for the practitioner to examine evolutionary improvements rather than to wait—or hope— for revolutionary ones. (p. 226) ## Essential difficulties ### Complexity [[No code]] nor GPT-3 ([[✍️ GPT-3 me va a quitar el trabajo, pero yo tengo que estar entrenando algoritmia de bajo nivel]]) will help us with it: >The essence of a software entity is a construct of interlocking concepts: **data sets, relationships among data items, algorithms, and invocations of functions.** This essence is abstract, in that the conceptual construct is the same under many different representations. It is nonetheless highly precise and richly detailed. I believe **the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it** and testing the fidelity of the representation (p. 182) >The complexity of software is an essential property, not an accidental one. **Hence descriptions of a software entity that abstract away its complexity often abstract away its essence** (p. 183) >Many of the classical problems of developing software products derive from this essential complexity and its **nonlinear increases with size** \[e.g., communication, enumeration of all possible states...\]. (...) This complexity makes **overview hard, thus impeding conceptual integrity.** (...) It creates the tremendous learning and understanding burden that makes personnel turnover a disaster. (p. 183-184) ^4481b0 ### Conformity Unlike science, with some underlying principles to learn: >Much of the complexity (...) is arbitrary complexity, forced without rhyme or reason **by the many human institutions and systems to which his interfaces must conform.** (p. 184) Your program is complex because your process is complex: maybe you should fix that instead. ### Changeability > Partly this is because the software in a system embodies its function, and the function is the part that most feels the pressures of change. Partly it is because software can be changed more easily—it is **pure though-stuff, infinitely malleable.** (p. 184) ### Invisibility [[Which advancements are there regarding IDEs help with understanding code]]: >In spite of progress in restricting and simplyfing the structures of software, they remain inherently unvisualizable. (p. 186) There is a very interesting anecdote in the review of these ideas he will do 10 years later: >I have long enjoyed asking candidate programmers, **"Where is next November?"** If the question is too cryptic, then "Tell me about your [[Mental models|mental model]] of the calendar." The really good programmers have strong spatial senses; they usually have geometric models of time; and they quite often understand the first question without elaboration. (p. 217) ## Past breakthorughs and current hopes solve accidental difficulties. High-level languages, computation speed, IDEs, object-oriented programming, or \[automated\] program verification don't help in the task of designing a complete and consistent specification. About Artificial Intelligence, he cites [[D. L. Parnas]] (1985): >In short, automatic programming always has been a euphemism for programming with a higher-level language than was presently available to the programmer. He does not dismiss however its impact in development: > A tool that disseminates good practice would be important (p. 193) About Graphical Programming (which would be [[No code]]), he says: >... the flow chart is a very poor abstraction of software structure (...) it has proved to be essentially useless as a design tool —programmers draw flow charts after, not before, writing the programs they describe. (p. 194) >...**software is very difficult to visualize**. Whether we diagram control flow, variable scope nesting, variable cross-references, data flow, hierarchical data structures, or whatever, we feel only one dimension of the intricately interlocked software elephant. If we superimpose all the diagrams generated by the many relevant views, it is difficult to extract any global overview. (p. 195) ## Promisins Attacks on the Conceptual Essence ### Buy versus build This, which is SO hard to understand for the majority of devs ([[✍️ Refusing to stand on the shoulders of giants]]): >**The most radical possible solution for constructing software is not to construct it at all** (...) The development of the mass market is, I believe, the most profound long-run trend in software engineering (p. 197) Nowadays this is already on its way! And for data, a strong push towards Data Citizens (although [[🗞️ Good Data Citizenship Doesn’t Work]]): >I believe the single most powerful software productivity strategy for many organizations today is to equip the computer-naive intellectual workers on the firing line with personal computers and good generalized writing, drawing, file, and spreadsheet programs, and turn them loose. The same strategy, with generalized mathematical and statistical packages and some simple programming capabilities, will also work for hundreds of laboratory scientists. (p. 199) ### Requirements refinement and rapid prototyping Here is where [[No code]] tools (or [[Django]] for that matter) have a place: >...the most important function that software builders do for their clients is the iterative extraction and refinement of the product requirements. For the truth is, **the clients do not know what they want.** They usually do not know what questions must be answered, and they almost never have thought of the problem in the detail must be specified (...) **Complex software systems are, moreover, things that act, that move, that work. The dynamics of that action are hard to imagine** (...) it is really **impossible** for clients, even those working with software engineers, **to specify** completely, precisely, and correctly the exact requirements of a modern software product **before having built and tried some versions** of the product they are specifying (p. 199-200) ### Incremental development >If, as I believe, the conceptual structures we construct today are too complicated to be accurately specified in advanced, and too complex to be built faultlessly (...) Let us turn to nature and study complexity in living things (...) The secret is that it is grown, not built. (p. 201) This is the idea of [[Incremental design]], here attributed to [[Harlan Mills]]: > Some years ago Harlan Mills proposed that any software system should be grown by incremental development. That is, the system should first be made to run, even though it does nothing useful except call the proper set of dummy subprograms. Then, bit by bit it is fleshed out... (p. 201) ### Great designers He proposes to improve software curricula in general, but, in the nature vs. nurture debate... >...I do not believe we can make the next step upward in the same way. Whereas the difference between poor conceptual designs and good ones may lie in the soundness of design method, the difference between good designs and great ones surely does not. Great designs come from great designers. **Software construction is a creative process.** Sound methodology can empower and liberate the creative mind; it cannot enflame or inspire the drudge. The differences are not minor--**it is rather like Salieri and Mozart.** (p. 202) This in stark contrast to [[📖 Extreme Programming Explained]]: ![[📖 Extreme Programming Explained#^b9a679]] So he thinks we should work hard in identifying and growing people with innate ability. ## Other notes An interesting problem with developers and object-oriented programming, where one can see connections to [[📖 Domain Driven Design]] or the deep modules suggested in [[📖 A Philosophy of Software Design. 2nd Edition]]: >The problem is that programmers in O-O have been experimenting in incestuous applications and aiming low in abstraction, instead of high. For example, they have been building classes such as linked-list or set instead of classes such as user-interface or radiation beam or finite-element model (...) If we design large-grained classes that address concepts our clients are already working with, they can understand and question the design as it grows, and they can cooperate in the design of test cases. **My ophthalmology collaborators don't care about stacks**; they do care about Legendre polynomial shape descriptions of corneas. Small encapsulations yield small benefits.