Reclaiming Software Engineering (2010)
zerobanana.com
zerobanana.com
This conclusion is far from inexorable.
There are kinds of making other than engineering. Carpentry is not engineering. Cooking is not engineering. Gardening is not engineering. Sewing is not engineering.
All of these things involve making artefacts for users other than their designers, within a social context no less. All of them require specialist knowledge and tools, involve the application of judgment learned from years of experience, and give rise to communities of practice which codify their agreed knowledge in books. They even have formal certifications.
Before you can declare that making software is (or can be) engineering, you have to be able to explain why those things aren't.
My tentative theory is that engineering has rigorous ways to check whether a design will work before it is manufactured, and even before it is drawn in detail. A civil engineer can use known formulae to check if a bridge span of given dimensions is even possible before sitting down to design it. A chemical engineer can use known formula to check if a reaction is plausible. A mechanical engineer might need to draw a detailed design, but can then check it rigorously with finite element methods. When we make software, in practice, we have to construct the software and test the artefact, hoping that our tests are adequate. We can't do meaningful checks on the design itself, let alone on any sketch which prefigures the design.
True enough. But the piece argues (I am the author) that software engineering is not making, it's designing.
> Carpentry is not engineering. Cooking is not engineering.
Carpentry is a craft, but furniture design can be engineering. Cooking dinner is a craft, but designing the menu and production process for a chain restaurant is definitely engineering.
> Before you can declare that making software is (or can be) engineering, you have to be able to explain why those things aren't.
My position is that they are (or can be), when analysed in an analogous way. You've asserted that they self-evidently are not, even in the absence of a rationale for why. I simply don't agree.
> My tentative theory is that engineering has rigorous ways to check whether a design will work before it is manufactured
I appreciate you sharing your theory! However, I believe you'll find the history of engineering has largely been one of people doing stuff first and then later finding ways to reduce the cost by doing analysis. I highly recommend watching one of Glenn Vanderburg's "Real Software Engineering" talks for a more in-depth treatment of that subject: http://vanderburg.org/speaking/
> A mechanical engineer might need to draw a detailed design, but can then check it rigorously with finite element methods.
That's great, but finite element analysis won't tell you e.g. where water might pool causing a structure to deteriorate, or that a machine can't be properly maintained because a part is too difficult to access. If you worked in any of these fields I think you'd quite quickly be disabused of the notion that they consist of just plugging designs into known formulae until the computer accepts one. Similarly, we have plenty of similar tools in software (e.g. Big-O analysis), but we don't kid ourselves that using them is the be all and end all of developing software.
> When we make software, in practice, we have to construct the software and test the artefact, hoping that our tests are adequate.
We do that in practice because it's more efficient. I can't accept a definition of engineering that holds that we could claim to be doing engineering only if we did things inefficiently, because it's self-contradictory. That's the opposite of engineering.
But we can do meaningful checks on the design beforehand, and we can create high-level sketches of a design. We have tools from computability theory, complexity theory, automata theory, graph theory, etc. We have tools for formal specification and verification. We have tools and principles for designing software components and their interactions. We have experiences from past projects that we can draw upon. We can do research, and we can readily discuss issues with other engineers all over the world.
I (and I suspect that I'm far from unique in this) do these things in the early stages of every project. My boss will come to me with a list of requirements, and some requirement(s) will invariably be intractable in terms of computational complexity, and I'll have to sit down with him and work on a compromise (most often, it's a case of the client trying to describe the solution they invision rather than the problem they need solved, and once we've determined the rationale for a requirement, we can come up with an alternative that fits the bill easily enough).
After all of the requirements are both computationally possible and tractable, I come up with a design sketch to illustrate the architecture of the application at a high level. I identify the major components and how they relate to each other, and I identify the flow of data for each her case and what happens to it at each step. I describe what extension points we'll need in order to accommodate the addition of functionality that didn't make the cut for the first iteration, but that we already know to be needed in a future iteration.
"Breaking the build" has become a really cheap mistake these days.
Reliability of software is not like reliability of a machine, or building.
Machines and buildings are made of matter, and so have uncontrollable variation, and wear out over time. Everything made of matter fails eventually; it's part of the engineer's job to trade off reliability and cost.
Software is made of bits. The only reason it fails (cosmic rays and other negligible intrusions of matter aside) is defects in design.
Do you really get mechanical or civil engineers saying "yeah, we expect there are a few fatal flaws in the design, that's just how it goes, we'll build it anyway and ship a fix if customers complain"? Apart from on Kickstarter, I mean.
> Do you really get mechanical or civil engineers saying "yeah, we expect there are a few fatal flaws in the design, that's just how it goes, we'll build it anyway and ship a fix if customers complain"?
Heck yes! (Well, not fatal flaws.) Any product you can think of that has been popular enough to get a second production run probably has had some design flaws corrected. Some of which were probably already known by the time that the first version shipped, and some of which were probably only discovered after real users had it in their hands for a while.
> it's part of the engineer's job to trade off reliability and cost.
Correct. But the cost includes not only the cost of the artefact but also the cost of the design. The difference with software is that design costs dominate in a way that isn't often the case with physical artefacts.
Is the bug list empty, with bugs fixed rather quickly once they are reported? Then the code quality is probably good, because that is hard to reasonably achieve with a moderately-sized (or larger) lousy codebase.
They got many bugs, but nothing one or two bugfix-only sprints couldn't get under control.
JWZ seems to be of the notion that it is better to hammer away at a known codebase than keep trying to reset the clock, while certain big name FOSS projects seems to reset the clock at every generational changing of the guard.
I'm not entirely sure what you are trying to say here.
I've noticed that poor codebases tend to suck up more and more developer time, and may even trigger the formation of "maintenance teams".
Lots of software I have worked on has probably been in "technical bankruptcy", but nobody sat down and figured that out (or it didn't matter because there was some persistent political reason for the system to exist and for it not to be able to be effectively designed and delivered).