A computer can perform calculations at extraordinary speed and still be difficult to redirect toward a different task. The ability to compute and the ability to change what a machine computes are related, but they are not the same capability.
Early electronic computers made this distinction visible. ENIAC, completed in the 1940s, used electronic circuitry to perform calculations far faster than earlier electromechanical systems. Yet configuring it for a different calculation could involve switches, cables and plugboards. The machine's physical arrangement remained closely tied to the procedure it was meant to execute.
This was not a failure of engineering. ENIAC represented a major achievement within the constraints of its time. Nor was the history of early computing a simple progression from primitive machines to modern software. Different systems explored different ways of expressing instructions, controlling operations and changing procedures.
The underlying challenge was more specific: how could a machine retain its computational capabilities while the procedure governing its behaviour changed?
A physical configuration can embody a procedure, but changing that configuration imposes costs. It requires time, specialized knowledge and, in some cases, physical intervention. A more flexible arrangement would allow instructions to be represented within the computational system itself, so that changing the task could increasingly mean changing information rather than rebuilding the machine.
That separation became one of the foundations of software.
Instructions become information
The stored-program concept offered a way to separate the physical computer from the sequence of operations it performed. Instructions could be represented in a form that memory retained, then retrieved and interpreted by the machine as it executed a procedure.
The First Draft of a Report on the EDVAC, circulated by John von Neumann in 1945, became an influential description of this approach. It was part of a wider body of work involving researchers, engineers and several early computing projects. The development of stored-program computing should not be reduced to a single document or inventor.
The important shift was that a procedure could be represented within the computer rather than being embodied entirely in its physical wiring or external configuration. The hardware provided operations, memory and control; the stored program specified a sequence of operations. A different program could direct the same system toward a different problem, subject to the machine’s capabilities and constraints.
This separation was not absolute. Hardware architecture continued to shape which instructions were available and how efficiently they could be executed, while programs depended on the memory and input/output facilities a machine provided. The stored-program approach made flexible instruction storage practical; the history of programmability is about what people built on that possibility.
From principle to working machine
The Manchester Small-Scale Experimental Machine, widely known as the Manchester Baby, executed a program held in electronic memory on 21 June 1948. It was an experimental system designed to demonstrate the feasibility of stored-program computing, rather than a finished general-purpose computer in the modern sense.
Its significance lay in what the demonstration established. Instructions could be encoded, retained electronically and executed by the machine. The program was no longer merely an external plan for operating a computer. It could be represented within the system and used to direct its behaviour.
The memory technology was part of the achievement. The Baby used a Williams-Kilburn Tube, a form of electronic storage based on a cathode-ray tube. The ability to store instructions depended on a physical mechanism capable of retaining and retrieving the required states reliably enough for execution.
The experiment therefore connected two developments: the architecture of the stored-program computer and the practical engineering of memory. Neither could deliver the intended capability alone.
The Baby showed that a principle could work. The next challenge was to turn that principle into a useful computing service, where programs could be developed and executed as part of sustained scientific and institutional work.
EDSAC and the beginning of reusable practice
EDSAC, completed at the University of Cambridge in 1949, helped move stored-program computing from experimental demonstration toward practical service. It was designed to support real computational work, and its development encouraged the creation of methods for expressing and reusing procedures.
A programmable computer is useful only when people can communicate tasks to it in a form the machine can execute. The stored-program architecture created the possibility, but programming practice had to develop around it. Programmers needed ways to express operations, organize instructions, manage input and output, and reduce the work required to solve recurring problems.
Subroutine libraries were an important step. Common operations could be prepared as reusable routines and incorporated into larger programs. Instead of reconstructing every sequence of instructions for each new calculation, a programmer could draw on procedures that had already been written and tested.
This was more than convenience. A useful routine could persist beyond the original problem. It could be reused, corrected, improved and combined with other routines. The knowledge invested in one procedure could contribute to many later tasks.
Programmability was therefore beginning to create a form of accumulation. In manufacturing, controlled processes made it possible to reproduce physical objects and capabilities. In programming, stored procedures made it possible to reproduce parts of a computational method through information.
The two forms of reproducibility were different. A manufactured component had to be produced through a physical process. A program could be copied and executed on a compatible machine without recreating the original act of development. The physical computer remained necessary, but the procedure could circulate separately from it.
Memory takes on a new role
Memory was already essential to computation. A machine needed to retain data, intermediate results and other information while carrying out operations. Programmability extended this role: memory could also hold the instructions that governed those operations.
This changed the relationship between data and procedure. A computer needed information to work on, but it also needed information specifying how to work. When instructions and data could both be represented within a memory system, the machine could treat the procedure itself as something that could be stored and retrieved.
The historical details matter. Early memory technologies were physical systems with specific constraints. EDSAC, for example, used mercury delay lines, which stored information as pulses circulating through a medium. The stored program was not immaterial. It depended on physical devices capable of retaining and recovering information in a usable form.
Modern software can appear detached from the machinery that executes it because many layers now separate a program from the electronic operations beneath it. Historically, that separation had to be built. Memory, instruction formats and control mechanisms had to work together before a program could become a dependable object within the computer.
The larger point is that programmability did not remove the physical foundation of computation. It made the physical system capable of carrying procedures as information.
Reuse changes how computational knowledge accumulates
Once a procedure could be stored and used again, it could become part of a growing body of computational knowledge. Subroutines were an early expression of this change. Later, programming languages, libraries, operating systems and applications extended the range of capabilities programmers could inherit from earlier work.
A programmer could rely on an existing routine or operating-system facility and focus on the specific logic of a new task. Complex programs could be assembled from components whose behaviour had already been established and tested, rather than rebuilding every operation from the lowest level.
This accumulation was not automatic. Reusable software required maintenance, documentation, testing and compatible environments. A routine that depended on undocumented assumptions or a particular machine might not transfer easily to another system. Reuse became more valuable as methods for describing, organizing and distributing programs improved.
The change was that procedures could be preserved, copied, revised and combined. Hardware embodied reproducible computational capability; software embodied reusable ways of directing that capability. The two forms of progress were related, but they accumulated through different processes.
Abstraction moves the work upward
As programming developed, people needed ways to express increasingly complex procedures without writing every operation in the machine's native instruction format.
Assembly languages introduced symbolic representations for machine instructions. Assemblers translated those representations into instructions a processor could execute. Higher-level languages enabled programmers to describe computations in forms less tightly bound to a particular machine's instruction set. Compilers and interpreters provided different mechanisms for translating or executing these representations.
These developments did not appear all at once, and they did not eliminate the need to understand hardware. They created layers of abstraction, each providing a more manageable way to express and organize computation.
Abstraction works when the layer beneath it provides sufficiently dependable behaviour. A programming language can offer a clearer way to describe a procedure because other software translates that description into operations the machine can perform. An operating system can offer common services because it coordinates access to underlying resources. A library can provide a reusable operation because its implementation follows an interface that other programs can rely on.
Each layer reduces the amount of detail a programmer must manage directly. It also creates a dependency on the reliability and compatibility of the layers below.
This is why software is not simply a collection of instructions. It is an organized structure of representations, interfaces, tools and established expectations. Programmability became more powerful as the work of developing software moved upward through those layers.
Software requires institutions as well as machines
A stored program can be executed by a computer, but a software ecosystem requires much more than the ability to run instructions.
Programs must be written, tested, documented, corrected and distributed. Programming languages need implementations. Operating systems coordinate resources and provide common services. Standards and file formats allow information to be exchanged. Development communities and institutions preserve knowledge that would otherwise remain with individual programmers.
Compatibility becomes increasingly important as software travels between machines and organizations. A program may depend on a particular instruction set, operating system, data format or service. Its usefulness therefore depends not only on its internal logic but also on the environment in which it is expected to run.
The development of software involved organizational choices as well as technical ones. Different institutions adopted different systems, languages and conventions. Some software was developed for specific machines or organizations; other forms became more portable and widely distributed. These paths shaped which procedures could be reused and by whom.
The ability to copy a program did not guarantee that it would run everywhere. Reuse required compatible hardware or translation mechanisms, stable interfaces and sufficient knowledge to operate and maintain the software. As programs became more complex, testing, versioning, documentation and long-term support became increasingly important.
The software layer thus developed alongside an institutional layer. The machine made execution possible. Programming methods made procedures expressible. Institutions and shared conventions helped those procedures become durable, transferable and useful beyond their original setting.
The machine becomes a platform
When a computer can execute different programs, it can provide a foundation on which many capabilities are built. The platform relationship developed through the interaction of hardware, operating systems, programming languages, libraries and applications. Software organized machine resources into services that other programs could use.
This did not make all computers interchangeable. Architectures, operating systems, performance constraints and proprietary interfaces continued to shape what software could do and where it could run. Portability was an achievement that had to be engineered, not an automatic property of programs.
A shared software layer could nevertheless benefit many applications. A library could serve different projects, a language could support many kinds of work, and an operating system could provide common services to programs with different purposes. A new application could begin from these established capabilities instead of recreating them independently.
The platform therefore gave programmability an institutional and technical setting. Reuse depended not only on storing instructions but also on the interfaces, conventions and maintained software that allowed other people to build on them.
The Programmability Shift
From Physical Configuration to Reusable Procedure
Programmability separates the machine's general computational capabilities from the instructions that direct their use.
The procedure remains closely tied to switches, wiring or other machine arrangements.
The machine can retain and retrieve instructions as information.
Procedures can be preserved, tested and combined across tasks.
Languages, libraries and operating systems let programmers work above machine instructions.
Reusable procedures accumulate through tools, standards and shared practice.
What programmability did not solve
Separating instructions from physical configuration made computers more flexible, but it did not remove the constraints of computing.
Programs still had to be written correctly, and a machine could execute an incorrect procedure with the same mechanical consistency as a correct one. Software could contain errors, depend on faulty assumptions or fail when the surrounding environment changed. Abstraction reduced some forms of complexity while introducing dependencies between layers.
Nor did programmability make a computer learn. A conventional program executes instructions supplied by its designers or developers. Its behaviour can be highly complex, but the procedure is still specified through code and the mechanisms provided by the system.
Machine learning introduces a different approach. Instead of defining every relevant rule directly, a learning system uses data and a training process to derive a model whose behaviour reflects patterns in examples. That process depends on computation and software, but it changes how the system's behaviour is produced.
The distinction is important for the larger argument of Beneath Intelligence. Computation made general-purpose information processing possible. Programmability made procedures reusable and allowed software to accumulate above the hardware. Neither development alone explains how a machine can derive a model from data.
Before reaching learning, another transition must be understood. Programmable computers increasingly exchanged information, shared resources and became components of systems that extended beyond individual machines. That transformation changed the reach of computing.
What lies beneath programmability?
The visible artifact of programmability is a program: instructions represented in a form that can be stored, executed, revised and reused. Beneath it lies a chain of capabilities. The computer must represent and retrieve instructions; its control mechanisms must execute them; and its architecture must provide the operations the program requires.
Those capabilities remain physically grounded. Electronic components depend on semiconductor fabrication, precision manufacturing, measurement, materials and energy. Languages, libraries and operating systems add further layers that make procedures easier to express and combine, but those layers still rely on the behaviour of the system beneath them.
Programmability therefore adds a layer to the technological stack rather than escaping it. The important change is where capability can accumulate: procedures can be preserved as information and applied repeatedly on compatible systems without reproducing the physical machine on which they were first developed.
That flexibility does not make software independent of institutions, hardware or engineering. It makes the relationship between a procedure and a particular machine more adaptable, creating the basis for the connected computing systems considered next.
Programmability separated capability from task
The stored-program concept established a consequential separation between a computer’s physical capabilities and the instructions governing their use. The Manchester Baby demonstrated that a program could be stored in electronic memory and executed. EDSAC helped move the principle toward practical computing service, while reusable routines and higher-level programming methods allowed procedures to become accumulated knowledge.
The deeper transformation was not simply that computers could accept instructions. Procedures could increasingly be preserved, copied, corrected and combined, then used as a starting point for later work. Software became a growing body of capability above the physical machine, although its usefulness continued to depend on compatibility, maintenance and the systems that executed it.
Article 04 explained how computation became a general-purpose mechanism. This essay has examined how its procedures became reusable. The next transition extends the story beyond the individual computer, toward systems that connect machines and coordinate the movement of information between them.
This essay draws on institutional histories of stored-program computing, the Manchester Baby, EDSAC and the development of software and programming languages. These sources situate programmability as a cumulative engineering and institutional development rather than a single invention.
Computer History Museum: The Silicon Engine Computer History Museum: Timeline of Computer History Computer History Museum: Software and Languages Computer History Museum: Early Stored-Program Computing University of Cambridge: EDSAC History