A few weeks ago I watched Hillel Wayne’s recent talk “Are we really engineers?”, where he looked at the idea of whether software engineers get to call themselves “engineers” or not. (Spoiler: the answer is yes!)
During the Q&A, Wayne mentioned that while he had seen a lot of “philosophy of science”, there didn’t seem to be much “philosophy of engineering” out there. I remembered noticing the same thing, and on Twitter I asked for book recommendations on the topic. The always-reliable Lorin Hochstein obliged, and a week later I had some reading to do!
Just as a disclaimer: this post is very much in theme of “thinking out loud”, and got a little long. 🙂 This is mostly me discussing my experience of reading the book and some thoughts on software engineering I had after reading it. Very likely nothing here is at all original, and I am not an expert, but I wanted to get my ideas down in text after finishing the read. And having done so, I thought it might be worthwhile to share.
Ok, let’s dive in.
In What Engineers Know and How They Know It, Walter Vincenti examines the idea of “engineering knowledge” as a distinct area of knowledge, separate from simply being a form of “applied science”. He does this by examining several case studies in design from aeronautical engineering, and then generalizing from those to come up with a list of different types of engineering knowledge, as well as proposing a model for how it’s produced.
The five case studies are the major part of the book, and were the most enjoyable part of the book for me. These included:
- The story of a particular aerofoil design, the “Davis Wing”, and its impact on its field (chapter 2)
- The process by which the aeronautical engineering community incorporated pilot experience and flight quality standards into designs (chapter 3)
- The development of control-volume analysis (chapter 4)
- The production of a “catalog” of design data for aircraft propellers, which was widely used in the industry (chapter 5)
- The development of flush riveting as a technique throughout the entire aircraft industry, more-or-less simultaneously (chapter 6)
The last two chapters present some analysis based on these case studies. Chapter 7 attempts to break down a categorization of different types of engineering knowledge, and how they were produced. These broke down into six different areas: fundamental design concepts, specifications, theoretical tools, quantitative data, practical considerations, and design instrumentalities. Vincenti also categorizes the different ways engineering knowledge is produced, such as transfer from science, theoretical and experimental engineering research, production, operations, and so on. Chapter 8 then aims to provide a model for how engineering knowledge is produced in general, looking at how new variations in ideas are produced, and then tested against each other and selected for future use.
While this was at times a relatively slow and dense read, I found it really enjoyable and rewarding. The case studies were well-researched and often read smoothly as stories of the work being done, while still going into a great deal of detail. And while I’m not familiar enough with the field to critically evaluate the analysis Vincenti did in the last two chapters, he did an excellent job of explaining his ideas and gave me a lot to think about.
In particular, I appreciated the distinctions Vincenti made between scientific knowledge and engineering knowledge, and how they are both produced and used differently. As I did my initial degree in physics, I have definitely been susceptible to the idea that engineering was “only applied science”. But Vincenti does an excellent job of laying out the differences, especially in the chapter in control-volume analysis, where he explicitly discussed a form of theoretical thermodynamic analysis that is not found in any common physics texts, but which are essential for practical engineering work!
So how does this apply to software?
As I read through this book, and especially during the analysis chapters, I thought a lot about how Vincenti’s ideas applied to my own experience, as well as software engineering in general.
For a little perspective, I’ve mostly worked in operations, with job titles like “system administrator” and “production engineer”, and a lot of my work has fallen into the bucket generally thought of as site reliability engineering these days.
I’ve also mostly worked on large or distributed clusters for compute or storage, with mostly internal-facing customers, rather than producing hardware or software for external customers to use on their own systems. While I’ve been involved in some software development and design, it’s primarily been from the perspective of helping improve software that I’ve previously operated in production. So I found the design focus in this work really interesting.
Design vs production and operations
Vicenti explicitly focused his analysis on design activities in engineering, and specifically on normal design. While he mentions production and operations as important parts of engineering, he mostly doesn’t examine them too closely, and my impression was that these activities are generally fairly separate in aeronautical engineering. There is clearly feedback from the production floor to design (as in the riveting case study), as well as from aircraft operation (as in the piloting qualities case study). But these seem to mostly consist of overlapping-but-distinct groups of people communicating back to the design community.
I find this pretty interesting, because in my recent experience in software, these activities are much more tightly coupled. A lot of the discussion around SRE and DevOps focuses on having development teams work very closely with operations teams, and these teams are frequently merged! It’s not uncommon for the same team to write a software package, deploy it to production, and support it on call — indeed, this is generally considered the ideal case. It’s usually an anti-pattern for a team to “throw code over the wall” to an operations team that isn’t directly involved in development.
This is probably partly because of differences between working with external customers vs operating services. In Vincenti’s case studies, he’s mostly considering the design of airplanes which are produced by one company, for sale to another. A huge fraction of software today is operated as a service directly by the company developing it, including most of the largest software companies today (most of “FAANG”). This seems like a business model difference at its heart, but it clearly influences the engineering process!
I’ve also seen software teams get into trouble when going in the reverse direction: when an internal service is converted into an external product that is not operated by the development team, the design might need to change a lot to account for the different environment, and the documentation and tooling often needs a lot of improvement before it can be handed off.
As I’m hunting for follow-up reading, one thing I’ll be looking for is good case studies from other areas of engineering which examine the feedback from operations to design in more detail, and to try to find good non-software examples of design interacting with internal vs external operations.
“Normal design” applied to software
Another point I found really interesting was Vincenti’s notion of “normal design”, where new engineering artifacts are produced to solve slightly different constraints and make new improvements over a previous version. As I understood it, a normal design task in aeronautical engineering might be to design a new airplane with a longer range and higher capacity than a previous model; or to design a more efficient propeller based on a well-understood library of options. This process may still involve a lot of creativity and problem solving, but it doesn’t require dramatically new innovations of “radical design”, such as designing a jet engine for the first time.
My first thought is that “normal design” in the software field might consist of producing new applications where the problem is well-understood, and you can choose from a selection of existing components while adding new business logic. For example, “normal design” might be to produce a new web application with existing tools, selecting some combination of database, language, framework, and deployment. The components already exist, but they may need some adaptation, and the application is still a lot of work!
“Normal design” might also apply to the process of continuous development of a long-lived code base. A piece of software may go through very large changes over the course of its lifetime, but still retain an essential design and some continuity in its history — for example, PostgreSQL 12 is an improved version of PostgreSQL 11, and with some care, you can swap it into the same place in a larger system. This feels a lot to me like producing a newer and better version of some physical component, which may be used to upgrade a larger system, albeit with some adaptation.
Distributed collaboration and open source
Another theme I found interesting was the idea that engineering knowledge was produced by communities of engineers, working on the similar problems, observing each others’ solutions, and often collaborating. For example, in Vincenti’s chapter 5, the knowledge of what parameters to vary in propeller design were based on experiences throughout the engineering community, and the “catalog” of resulting parameters were published as part of a NACA-funded study. Similarly, in chapter 6, the change to flush riveting on aircraft occurred more or less simultaneously across the aircraft industry.
However, while this represents distributed collaboration on engineering knowledge, each independent company and organization was working on separate designs and artifacts. And while this is certainly the case for a large fraction of software “artifacts”, software engineers also frequently collaborate on the same distinct artifacts in the form of open source projects. It’s even common for engineers at competing companies to contribute to the same projects (and to try to steer those projects in favorable directions).
The analogous activity in physical engineering disciplines would seem to be standardization, where different organizations collaborate to ensure their final products are compatible with one another.
And while there’s standardization in software too, it often seems to me to be a less active activity — instead of standardizing, we all frequently seem to just work on the same open source projects, forking or re-inventing them if the disagreements become too great. I wonder if this collaboration model is, in fact, one of the reasons that standardization seems less active in software engineering?
As mentioned above: If you’re interested in the differences and similarities between software and other fields of engineering, I would definitely encourage you to follow @hillelogram on Twitter, watch his recent talk on engineering crossovers, and subscribe to his newsletter. While I’m mostly just doing some reading and rambling on the blog, he’s actually doing some interesting research, and I’m looking forward to
In the mean time, I’m going to go hunting for more reading! I read some of Samuel Florman’s writing a few years ago, and while I didn’t love it, I should give it another try. I’ve also got Henry Petroski’s To Engineer Is Human on my shelf — which again, I bounced off of years ago, but plan to read again now that I’ve been thinking about this more.