This episode reaches the end of the 1968 conference, discussing Alan Perlis’s keynote address and submitted papers by Doug McIlroy, Edgser Dijkstra, and more. I summarise the impact of the conference on software engineering, and get ready to investigate the 1969 conference in episode 61.
The episode is supported by members of the Chiron Codex Patreon (use this gift link for your first month free), so please do join the community or hit the Ko-Fi button to make a one-off donation.
Links
- The NATO Software Engineering conferences
- The Structure of the THE Multiprogramming System
- Byte Volume 6 Issue 8: Smalltalk
- Object-Oriented Software Construction
- Object-Oriented Programming: An Evolutionary Approach
- A History of CLU
- Masterpiece Engineering
- “Crisis, What Crisis?” Reconsidering the Software Crisis of the 1960s and the Origins of Software Engineering
Transcript
Hello, and welcome to Episode 60 of the Structure and Interpretation of Computer
Programmers podcast. I’m Graham Lee, and this episode is the fourth part in a
mini-series exploring the NATO Science Committee conferences on software
engineering. The episode is sponsored by you, the software engineering community.
In this episode, I’ll take us to the end of the report on the first conference
held in Garmisch, Bavaria in 1968, as there are just two sections left to cover.
The episode ends with a reflection on the whole conference so that you and I can
leave 1968 behind, ready to emerge blinking into the bright future of 1969 and
the second NATO Software Engineering Conference, which starts in the next
episode.
Section 8 of the report includes the keynote from Alan Perlis and another
invited talk. It might seem a bit weird to bury the keynote near the end of the
report when its purpose is to set the tone for the whole conference. You’d have
to take that up with Peter Naur and Brian Randell, the report editors. Not with
me. Randell, at least, is somewhere in the same country as me, but I wouldn’t be
able to point him out.
Perlis’s point can be summarised thus. Making complex software is hard, but we
will be asked to make more software of increasing complexity before we’re given
time to understand how to simplify it. What’s the cause? Software is an
imperfect embodiment of our ideas of what it should do. Or, to use his words,
“Such shortcomings in design are probably inevitable, even in the very best
systems, and are simply consequences of the inevitable disparity between the
degree of connectivity of human thought processes and those of a programmed
system””. There are some in the world who say that Jerry Weinberg was the first
to consider human factors in software engineering in his book “The Psychology of
Computer Programming”. I’d argue that Alan Perlis got there first.
In Perlis’s view, software is a linguistic exercise. We describe our problems
and our innovative approaches to solving them, and we describe them in a way
that instructs the computer to carry out the solution. Therefore, our problems
in software are caused by the ease with which we can explain complex things
linguistically, and our solutions need to be to create software tools that make
it easier to express complex things in the language of the computer.
Specifically, they need to make it easier to demonstrate equivalence. The
description of the solution as written and the solution as executed by the
computer need to be the same, and software engineers need the ability to
convince themselves that they are the same.
How to do that? Hierarchies of virtual machines. Perlis again. “The
establishment of relevant states, their transformations, the design of
communication channels, the nature and magnitude of storages, the natural sets
of operations, the I/O problem, etc.”
Those people who have followed my writing through my deep dive into the world of
small talk in about 2013, and subsequent publication of OOP The Easy Way, link
in show notes of course, are probably screaming, “this is object-oriented
programming!” at their Overcast app right now. Indeed it is, but only because
it’s structured programming, and OOP is also structured programming. Yes,
object-oriented programming is all about separate virtual computers running
isolated programs, and the ma, the interstices between these programs, realised
as messages that the computers send to each other. But go back to Dijkstra’s
description of hierarchical layers from the THE multiprocessing system that he
presents in section 9, which we’ll look at later in this podcast, you see the
same thing: independent programs that use the primitive operations available to
them to provide a different set of higher level operations, which higher level
programs use as their own collection of primitives.
Perlis concludes by summarising the idea that we’ve seen throughout this
conference, that the biggest problems come from the mismatch between the
ambitions of programmers, or customers, and the top end of the programmer’s
capability. He was vocal in the discussion of software engineering education
that we covered in the last episode, and he lays part of the blame for the
capability gap at the feet of “the unevenly trained personnel with which we
work”.
The other invited talk is from Doug McIlroy, and it’s about mass-produced
software components. This is a position and argument I know best from Brad Cox’s
1980s and 1990s writing on the “software industrial revolution” and “software
integrated circuits”, and it’s related to ideas that Joe Armstrong of Erlang
fame discussed too. But McIlroy makes it just as forcefully and coherently here,
and does so before the other two back in 1968.
The problem, as all three of those authors state it, is that software is a
cottage craft. We create systems from whole cloth every time, each being
idiosyncratic, wrong in different ways, and difficult to reuse, even where other
people are solving the same or similar problems. Much better would be to create
standardised catalogues of software components that have compatible interfaces.
You read the datasheets looking for the component category with the behaviour
you want—McIlroy uses the example of a sine function—and then you compare
specifications, I/O expectations, time memory trade-offs, data storage
requirements, and so on, to find the component that best suits your needs,
purchase one of those, and plug it in. As Nauer points out in the discussion,
this is a whole social shift as well as a technical one, and software creators
would need training to be component pluggers who make rational buy-build
decisions more than they’d need to know how to write low-level components.
My long-held belief is that the two innovations that made the most headway into
creating a software industrial revolution weren’t anything to do with design or
modularity techniques, or programming systems that provide reliable interfaces
like Eiffel, or generic interfaces like Ada. They were the web, and the
permissive open-source software licence. We still don’t have a
component-oriented marketplace in things like the Node Package Manager, Python
Package Index, or even Comprehensive Perl Archive Network. We have brand
loyalty, and components with unstable interfaces (recall the discussion on
semantic versioning in episode 59). But making discovery free and reuse free has
done more to shift the buy-build decision point than any other intervention.
Those then are the two invited talks. The remaining section of the report is a
subset of the submitted working papers at the conference. Most of these are
quite dry reading in 2026, even if they do provide a lens into what computer
programming looked like back in 1968. In episode 58, I covered the
“Classification of Subject Matter” paper, while I was trying to work out the
difference between software design and software production. What I didn’t cover
there and do here is a collection of asterisks used to indicate which activities
the working group considered the most important. This list is mostly interesting
for the things it skips rather than the things it covers. Estimation, capacity
planning and workforce allocation all aren’t given asterisks and nor is
configuration management. Nor is feedback to design, which we saw in episode 57,
was considered both critical and fatally lacking in the conference discussion.
The procedure for generating, maintaining and modifying the system does get an
asterisk, but the set of test cases and results did not. Even though an upcoming
working paper from Llewellyn and Wickens tells us how important and flawed were
contemporary approaches to customer acceptance testing.
Bemer submitted a “Checklist for Planning Software System Production”, produced
in August 1966. Even then, he considered certain computerised management systems
table stakes that aren’t even universally used today. Field reporting, by which
he means issue tracking, production control, automated software production,
customer roster, i.e. customer relationship management, file maintenance of
source programmes, by which he means version control.
He also suggests rotating programmers into field support or operations teams,
and promoting operations staff and other personnel to programming. This is one
way to get that feedback to design that so many software initiatives lack. I’ve
seen it work well at a number of places that I’ve worked, either through an
on-call rotation or fully seconding a programmer to the support team for a month
at a time. I’ve also seen it go very badly when the on-call has far too many
fires to fight, and that’s useful feedback for your design in itself. Another
interesting point on his checklist is the question, are hardware manuals
forbidden to exist separately for users, so that the system is described in
terms of the software system? These days that’s almost universally true unless
you’re in a hobbyist community like Arduino. Your manual for your phone tells
you where the power button is, and then how to use the operating system. It
doesn’t tell you which data lines the camera detector readout gets streamed to.
Next up is Dijkstra’s hierarchical approach to design, which we trailed earlier,
with the THE multi-processing system. This paper got critiqued in the discussion
on software production, covered in episode 58, for being more about proving the
design correct than actually about coming up with a design. It introduces the
hierarchical approach of designing systems that expose facilities for other
programs to talk to. Dijkstra defines the height of a subroutine as one more
than the highest other subroutine it talks to. But there’s no stricter layering
than that. A layer 2 routine can use operations from both layers 0 and 1. It
isn’t forced to only communicate with layer 1 programs. Dykstra wrote a longer
paper on the design itself, called “The Structure of the THE Multiprogramming
System”, link in show notes, and I have that on the backlog for a future episode.
Then we have Stanley Gill’s “Thoughts on the Sequence of Writing Software”,
which introduces the top-down and bottom-up approaches to design; the
distinction being discussed in episode 58. He considers that each module has two
views. The implementation view, which describes the facilities it uses from
lower layers, and the interface view, which describes the facilities it provides
to higher layers. In this, his approach parallels Dykstra’s, though without the
explicit layer cake division. Gill doesn’t make it clear that layer versions
aren’t allowed, and actually, Dijkstra only does that implicitly, through his
definition of how to count layers. Gill suggests that the interface between each
layer should be a programming language, which exposes the operations from the
below layers in ways that are easy to consume in the next layer. Imagine a
system in which the kernel is implemented in one language, operating system
services in another, foundational libraries in another, applications in another,
and graphical user interfaces in another. Actually, I suppose that is how web
applications really work, so clearly this design is workable.
A paper by report editor Brian Randell summarises these views on software design
and makes an important point that I hadn’t quite empathised with because it’s
not how software works to me in 2026. In 1968, you might be designing a
hardware/software system together, so you might choose whether certain
facilities are implemented in hardware or in software. Dijkstra’s approach to
design is bottom-up, insofar as the hardware system was already complete, so he
had to start with the hardware capabilities fully defined and work upwards to
the software he wanted.
In other cases, you might decide that you get better performance but higher cost
by implementing a feature in hardware, and then make a decision based on the
specific needs of the integrated system. For most modern software applications,
the design is so far abstracted from the hardware that you only design the
software system. Indeed, hardware manufacturers regularly, though perhaps
infrequently, change, processor architectures, component interfaces, and so on,
and the software carries on working. Software and hardware development are, in
many cases, so isolated from each other, and hardware capabilities make up for
so many of the shortfalls in software design, that many software project teams
accept the entire stack of processor, hypervisor, operating system, container
host, programming language, and networking framework, then designers start to
think about how to build the software from there.
A little thought experiment to test that assertion. If your project is a web
application, or what we used to call a “Rich Internet Application”, that is, a
native app that acts as a client to web services, have you ever considered
whether HTTP is actually the most efficient networking abstraction for your
data? Have you evaluated any alternatives?
Okay, I promised a paper on the shortfalls of acceptance testing, and here it
is. The authors come from the UK government, and their problem is one that still
broadly exists today. As a customer, you don’t get to decide whether the
software is correct or not until you get the software, by which time it’s very
expensive for everyone involved to make any changes. The solution we have in
AD2026 to address this problem is “continuous delivery of valuable software”.
And so now you see the opposite problem. Customers who complain they don’t have
time to continually accept and test early buggy versions of software, they just
want the working thing when it’s complete, thank you very much. There’s no
pleasing some people, and apparently those people use computers.
The solution as proposed then was a detailed collection of tests of different
artefacts as they were ready. So you can test the documentation to check whether
you’re going to get a system that does what you need, and that people can use
when you have the documentation, and without needing to have the software too.
When you get the software, you can test its behaviour against the accepted
documentation, rather than going all the way back to the spec. Performance
testing does need to wait until you have the actual software running on the
actual hardware. Although another working paper on software testing does point
out the value of simulation, at least for internal testing.
This is the advert break. It starts now.
This episode is brought to you by me, Graham Lee. But really, by you. Chiron
Codex is a community of people who are learning how to become better software
engineers by adopting AI augmentation in a thoughtful way. We aren’t outsourcing
our understanding to coding assistants like Claude or Codex, but becoming
software engineering centaurs by using AI tools to improve our knowledge and the
quality of our work. Join the community over on Patreon to find out about
interaction patterns that improve your work with AI coding tools, running LLMs
for software development locally, discussions of recent research in the field,
and more. If you’re a software engineer who’s interested in the promise of AI
tools, but sceptical about handing your skills over to the computer, this is the
community for you. Go to patreon.com slash Chiron Codex, that’s
C-H-I-R-O-N-C-O-D-E-X, now for more information and to join. Use the gift link
in the show notes to get your first month of insider access completely free.
Alternatively, you can show your appreciation by donating at Ko-fi, that’s
ko-fi.com slash Chiron Codex, K-O-F-I dot com. Direct support by my audience is
the only revenue I get for my work as a software engineer and communicator, so
your support really means a lot to me, and makes it possible for me to produce
this podcast. Thank you so much.
That was the advert break. It’s over now.
There you are, we made it. Okay, I didn’t read through the appendices, but we’ve
been through the whole of the body of the report into the 1968 NATO Science
Committee Conference on Software Engineering. We discovered that a lot of ideas
that later became mainstream parts of software engineering including continuous
feedback, testing early, and using testing as input into design were already
being talked about by the attendees at the conference.
For me, this is evidence that a conference wasn’t hugely influential. People
adopted the words software engineering and software engineer, but these are now
defined in a mutually tautological loop like the name of the herd operating
system. A software engineer is someone who does software engineering. Software
engineering is the thing that software engineers do. The calls for education
curricula and university-level standards of software education basically went
unheeded, and schools went down the route led by the ACM of defining computer
science curricula that are abstract mathematical studies, and only recently paid
more than token lip service to the construction of working software.
There definitely isn’t a NATO software engineering programme that can trace its
formation back to Garmisch 1968, or count any of the conference’s attendees
amongst its faculty. The only sizeable academic software engineering centre is
Carnegie Mellon’s Software Engineering Institute, which is indeed funded by the
federal United States Government’s Department of Defence, but which wasn’t
instituted until 1984. Hardly a continuation of the 1968 initiative, and more a
sign that NATO still hadn’t sorted out its software issues 16 years later. The
second conference, which is the topic of the upcoming episodes of the podcast
starting with episode 61, shows why there wasn’t an SEI any earlier.
The low rate at which the report is cited, and the low quality of those
citations, is further evidence for its limited impact. As Haigh argues, people
will typically invoke the conference as the source of the “software crisis”
narrative, even though the phrase “software crisis” doesn’t appear at all, and
the use of the word crisis is in the sense “most of the industry isn’t in
crisis”. As Haigh argues, this seems to have been mostly a one-man effort driven
by Dijkstra to formalise the mathematical basis of software construction, which
other people found beneficial to sell their cure-all solutions to the software
crisis.
That said, while the conference and its report might not have changed how most
people made software, I think there’s a range of different lifespans for the
ideas in the conference. The ones I mentioned earlier in this summary—test-first
development, continuous feedback, close collaboration with customers—these seem
to have fallen out of fashion and got rediscovered later, mostly by the people
who were working with Smalltalk in the 1990s.
Some of the others—hierarchical modules with clear interfaces, virtual machines
and bytecode interpreters, closed interfaces that permit extensibility in other
modules—these seem to have been evergreen ideas that were already accepted by
some of the attendees at the conference, and that had to break out of their
ivory towers to get broader adoption in the software industry.
Simula is mentioned in the report as an example of the object or Plex approach
to designing software, and its ideas were perpetually reused and rediscovered
until Smalltalk broke out in the famous Byte magazine issue, link in show notes.
The Eiffel approach to interface design, the first place where the open-closed
principle got formally written down as a design principle in its own right,
despite appearing a number of times in the conference report. While coincident
with the OO revolution, and definitely object-oriented in style, owes its
heritage not to Smalltalk, but to existing ideas in modularity, correctness and
fault isolation, following from work like Liskov’s on abstract data types in the
1970s, and Eiffel got a popularity fillip from the association with Objects in
the 1980s.
Episode 61 of the podcast will continue the NATO conference miniseries by
looking at the first sections of the report from the second conference, held in
1969 in Rome, Italy. As Brian Randell recalls, “In Rome, there was already a
slight tendency to talk as if the subject already existed, and it became clear
during the conference that the organisers had a hidden agenda, namely that of
persuading NATO to fund the setting up of an international software engineering
institute. However, things did not go according to their plan. The discussion
sections, which were meant to provide evidence of strong and extensive support
for this proposal, were instead marked by considerable scepticism, and led one
of the participants, Tom Simpson of IBM, to write a splendid short satire on
masterpiece engineering.” I’ve linked the masterpiece engineering piece in the
show notes, as it wasn’t included in the final conference report.
Join me again next time, and we’ll explore what went wrong. In the meantime, you
can leave your thoughts about this episode at the post on sicpers.info, or email
me, grahamlee at acm.org. Thanks so much for listening. If you enjoyed this
podcast, please share the link with your friends and colleagues, and consider
supporting the podcast on Patreon or Ko-fi. Take care, and we’ll talk soon.


Thank you