Skip to content
Part IA Easter Term

Programming vs Software Engineering: The Engineering Mindset

The Software Crisis (1968)

In 1968 NATO held a conference in Garmisch, Germany, that marked the birth of the term Software Engineering. The participants — leading computer scientists and practitioners — recognised that software was fundamentally different from hardware. Projects routinely ran over budget and over time; delivered systems had massive inefficiencies; code was unmaintainable and broke frequently. The term “Software Engineering” was deliberately provocative: it demanded that code creation adopt the rigour, discipline, and systematic approach of traditional engineering disciplines.

The distinction between programming and software engineering is not simply one of scale — it is one of kind:

DimensionProgrammingSoftware Engineering
Team sizeSingle developerTeams of developers
ScaleSmall (< 1,000 lines)Massive (1,000,000+ lines)
LifespanDays or weeksYears or decades
Primary metric”Does it work today?”Maintainability, security, extensibility over decades
ValidationManual “does this look right?”Automated test suites, CI/CD, formal review

Brooks’s Law and The Mythical Man-Month

In 1975, Fred Brooks published The Mythical Man-Month, which introduced what became known as Brooks’s Law:

Adding manpower to a late software project makes it later.

The reason is twofold:

Training overhead. Senior engineers must stop coding to mentor new hires. The skilled engineers who were delivering features become full-time trainers, and their productive output plummets. The new hires themselves contribute nothing useful for weeks or months while they learn the codebase.

Communication overhead. As team size nn grows, the number of communication paths grows quadratically:

Communication paths=n(n1)2\text{Communication paths} = \frac{n(n-1)}{2}

A team of 5 people has (52)=10\binom{5}{2} = 10 communication paths. Add 5 more people and the paths jump to (102)=45\binom{10}{2} = 45 — not double, but 4.5 times the coordination overhead. Every path represents a potential channel for miscommunication, a merge conflict, or a misaligned design assumption. Software is highly interdependent: unlike digging a ditch (which can be partitioned perfectly among diggers with minimal coordination), code modules constantly interact and assumptions made in one module propagate to others.

The myth of the man-month is the belief that effort and time are interchangeable — that if one person takes 10 months, 10 people can do it in 1 month. In software, sequential constraints, inter-module dependencies, and communication costs make this false.

Communication paths grow quadratically with team size: 5 people → 10 paths, 10 people → 45 paths

The Complexity of Discrete State

Physical structures have continuous stress limits. A bridge degrades gradually: cracks appear, stress concentrates, and engineers can inspect and measure the remaining margin of safety. A bridge tested to withstand 100 tonnes of load can be trusted (within its design margin) to withstand 90.

Software state is discrete. A single flipped bit — one wrong branch in a conditional, one off-by-one loop index — can move a system instantly from a perfectly safe state to catastrophic failure. There is no gradual warning, no “the paint is peeling” equivalent. The system is fine, and then it is not.

The state space of a non-trivial programme is combinatorially vast. Even a simple function with two 32-bit integer inputs has (232)2=2641.8×1019(2^{32})^{2} = 2^{64} \approx 1.8 \times 10^{19} possible input combinations. Exhaustive testing of all possible states is mathematically impossible for any real system. This is why software risk profiles differ fundamentally from those of physical engineering, and why engineering process — requirements, specifications, testing strategies, code review — is necessary to manage something that can never be fully enumerated.

Moore’s Law vs Human Cognition

Moore’s Law (Gordon Moore, 1965) observed that transistor density on integrated circuits doubled roughly every two years. Hardware capability exploded exponentially over the following decades.

The critical point for software engineering is this: as hardware capacity exploded, the ambition of the software we build on top of it exploded too. But human cognitive ability to manage complexity did not scale at the same rate. We have the same brains our predecessors had in 1968.

The widening gap between what hardware can do and what humans can safely programme and verify is precisely the space in which engineering processes become necessary. Requirements elicitation, version control, testing, and continuous integration are not optional bureaucracy — they are the only tools we have to manage complexity beyond what a single human mind can track.

Systems and Emergent Behaviour

Software rarely exists in a vacuum. It is built from components — databases, front ends, APIs, sensors, network layers, message queues — that combine into systems. A system can exhibit emergent behaviour: behaviour not present in any individual component, arising from their interactions.

Emergent behaviour can be:

  • Positive: combining a user-authentication module and an e-commerce module produces a personalised shopping experience — a capability neither component alone possessed.
  • Negative: two independently well-written, tested components interacting produce a deadlock or a race condition that neither module’s tests covered. The Therac-25 disaster (covered in a later note) is a classic case of negative emergent behaviour.

Critically, when a system fails, the bug is often not localised to one function. It arises from the interaction between two perfectly correct components — each of which passes its own unit tests — because no one tested the combination.

Expected Learning

After this topic you should be able to:

  • Explain the difference between programming and software engineering in terms of scale, lifespan, and metrics of success.
  • State Brooks’s Law, calculate communication paths for a given team size, and explain why adding manpower to a late project is counterproductive.
  • Articulate why discrete state makes software risk qualitatively different from physical engineering risk, and why exhaustive testing is impossible.
  • Explain how Moore’s Law and the limits of human cognition drive the need for engineering processes.
  • Define emergent behaviour and give examples of how it can produce both capabilities and failures.

Past Paper Questions

2025 Paper 2 Question 5 (introductory context): The question sets a scenario of a “rapidly growing social media service” — the very kind of system where the distinction between “it works today” and “it works reliably for 10 million users” is the difference between programming and software engineering. The failure case studies from this section (Therac-25, MCO, LAS, Horizon, 737 MAX) directly inform the testing strategies and authentication design answers later in the question.