Do you know any principles or patterns or useful design activities to apply in your work as a software engineer?
Chances are the things you know are superstitions, personal opinions, and catchy slogans that came out of the ’90s and ’00s generations of software engineers. I know, because I’m the same way. I can tell you about solid, tdd, agile development and so on.
Some of these things are good, but do you know what’s freaky? Most of the good stuff was known already in the ’60s and ’70s, only under different names. The early software engineers discovered patterns after patterns of useful approaches to software engineering.
In the ’60s and ’70s, they realised that this software development thing is actually really hard. So they figured out how to make software more modular, more reliable, and cost less. Some of the work is really well-reasoned and rigorous.
Why we had to ignore that and re-discover it 30 years later I don’t know.
My recommendation to any practising software engineer is to go back and read the stuff discovered by the early software engineers. There’s a lot we can learn from ourselves, if we only take the time to.
Start with the nato Software Engineering Conference reports. Then read the papers by David Parnas on software modularity and designing for contraction and extension. Read things by Ward Cunningham, Alan Perlis, Edsger Dijkstra, Douglas McIlrouy, Brian Randell, Peter Naur, and so on.
They Used Waterfall and Other Misconceptions
Yes. The Waterfall methodology sucks. And they knew that. In fact, the inventor of the term “waterfall methodology” only showed it to illustrate something that does not work.
Other things they knew about in 1968:
- Most letters of solid. Everything except the L11 The L, as in Liskov substitution, was discovered only in the ’80s. in solid is really about the same thing: divide software into modules with high cohesion and low coupling – which were well known good principles.
- Agile development. Software should be developed in small increments with tight feedback loops from actual users.
- tdd. Software should be written in parallel with its tests. These tests should first be written against simulations (as they called mocks and other test doubles at the time), and then these simulations can be swapped out for real implementations.
- Project estimation is nearly impossible to get right, unless you repeat work you have done before (they didn’t make crud web sites, but they wrote compilers for new kinds of hardware.) If you have to meet a deadline, you have to cut features, not “work harder”.
- Small teams work and communicate more effectively than big teams.
- Managers frequently forget how to write code (if they ever knew it) and this makes them ill suited to take part in technical decisions. Ideally, managers should do regular shifts writing actual code.
- Code review should be done – similar to how engineering drawings are signed by the draughtsman and then reviewed and signed by their supervisor.
I’m struck by how much they solve the same problems we do. Why do we keep reinventing these wheels?
What Has Changed?
Inevitably, some things must have changed since 1968. So what has changed?
I didn’t expect this list to be as sad as it is. I’ve noticed three significant changes between 1968 and 2020:
- We have better and more general hardware. They had to re-write things for new machines, and deal with the latencies inherent in core and drum memory.
- High-level languages are now more available. They frequently discuss program development in terms of assembly language, and speculate that some day we may see wider adoption of conversational languages, as they call it. These increase programmer comprehension and reduce the occurrence of trivial bugs.
- Version control was invented! They do discuss something like version control, but only in very hypothetical terms, and nobody is really sure how it will affect the day-to-day work of software developers.
That’s it. Those are the great improvements in software engineering since 1968. All other solutions they discuss are things we keep rediscovering.
What’s worse is the hardware and high-level language improvement are only improvements to accidental complexity – these things don’t actually help us with the inherent complexity of our jobs. Meaning we still fail at the hard parts.
And that is why we have a lot to learn from these ’60s and ’70s software engineers.