Skip to content
Tech HistoryDeep Dive Published Updated 8 min readViews unavailable

Simula 67: When Simulation Concepts Became a General Programming Language

Explore how Dahl, Myhrhaug, and Nygaard extended a simulation language with classes, objects, and processes, while standardizing a portable common base.

Simula 67 began as an effort to model systems in which many activities proceed concurrently: a ship queue, a production line, a traffic network, or another process whose future depends on the order and timing of events. The language’s lasting importance is that the modeling tools became useful beyond simulation. Classes, objects, subclasses, and process-like behavior offered ways to structure general programs, not merely to calculate the next event in a simulation. The language emerged from a practical problem and expanded through a standards process that tried to keep independently built compilers compatible.

The history has two related stages. Simula I, developed at the Norwegian Computing Center (Norsk Regnesentral) in the early 1960s, extended ALGOL 60 to describe discrete-event systems. Simula 67 generalized the language and introduced the common-base definition developed by Ole-Johan Dahl, Bjørn Myhrhaug, and Kristen Nygaard. The names can be confused because Simula 67 was a successor, not simply another label for the first language.

The simulation problem: model events, not every clock tick

A discrete-event simulation represents a system as state plus events that change that state. In a queueing model, an arrival can create a customer, a service completion can release a resource, and an event scheduler can select which scheduled event occurs next. The simulated clock advances from one event time to another instead of calculating every possible instant. This approach is efficient when meaningful changes are sparse relative to the simulated time interval.

The software needs representations for entities that have identity and behavior over time. A customer might enter a queue, wait, receive service, and leave. Two customers can have the same data fields but remain separate entities with different arrival times and histories. Procedures alone can describe these transitions, but the model becomes awkward if data, behavior, and lifetime are scattered across global structures.

Simula’s designers developed concepts that let programmers describe reusable categories of simulated entities and create individual instances. This was a response to a modeling problem, not a marketing effort to invent a fashionable programming paradigm. The language’s structure reflected how researchers wanted to express systems with many interacting components.

From Simula I to the 1967 language

Simula I was first implemented in the 1960s as an ALGOL-based simulation language. The authors’ later history describes how the language was used in practical simulation work and how its limitations motivated extensions. A key design change was to generalize the idea of a process and create language mechanisms that could support different application domains.

The 1967 redesign went beyond a special-purpose simulation vocabulary. The Common Base defined the facilities that an implementation had to provide to be called a compatible Simula 67 compiler. It was intended to be a common minimum, with more detailed manuals and implementation work developing alongside it. The three authorship names mattered: Myhrhaug contributed to string and input/output design and was formally a co-author of the common-base language, while Dahl and Nygaard were central to the earlier conceptual work.

This evolution is why it is misleading to say simply that “Simula invented object-oriented programming in one moment.” Ideas developed across multiple years, prototypes, papers, implementations, and discussions. Simula 67 made a particular package of concepts available as a documented general-purpose language; later languages adopted, modified, or independently developed related ideas.

Class, object, and subclass as modeling tools

A class in Simula defines the structure and behavior of a kind of entity. Creating an instance produces an object with its own state. A class can be extended by a subclass that reuses or specializes the original definition. These mechanisms provide a way to model categories and individual actors in the simulated world. They also support program decomposition: a subsystem can be described once and instantiated many times.

The class/object distinction is important. A class is a description or construction rule; an object is a particular runtime entity created from it. In a warehouse simulation, a Truck class might define how trucks arrive and load, while each truck object has its own current location and schedule. Subclassing can express a more specialized type, such as a refrigerated truck, without duplicating every common operation.

Simula’s objects were not identical to the object model in every later language. Concepts such as inheritance, method dispatch, access control, and type checking differ across designs and versions. Describing Simula as “the ancestor of all modern object-oriented languages” suggests a direct, simple lineage that historical influence does not support. A more precise claim is that Simula 67 established influential language constructs that helped make object-based program organization explicit.

Processes and quasi-parallel activities

Simulation also needs a way to represent activities that suspend and resume. A process can execute until it reaches a point where another event or activity should proceed, then later continue from its suspended state. This is a natural fit for describing a customer waiting for service or a machine alternating between idle and working states.

That execution model differs from starting a modern operating-system thread for every simulated entity. A simulation process is a language-level control abstraction managed by the runtime; it need not be a concurrently executing hardware thread. The scheduler can coordinate many process objects deterministically by simulated event time. The term “quasi-parallel” is useful because it captures independent-looking activities without implying simultaneous execution on multiple CPUs.

Process abstraction reduced the burden of manually encoding every state transition as a large collection of flags. A process could preserve its continuation and resume at a meaningful point. This made the model closer to the scenario being studied, and it helped explain why Simula’s contribution extended beyond the specific simulation applications that motivated it.

A common base was a portability strategy

A language definition can be elegant yet fail to travel if compilers disagree about syntax and runtime behavior. The Norwegian Computing Center’s Common Base gave implementers a shared specification. The goal was not to dictate every optimization or every user-library convention; it was to define a core that could be implemented on different machines and still behave recognizably as Simula 67.

The standardization process itself involved feedback between language designers and implementation teams. The authors’ history describes a period in 1967 when the common base was frozen except for string handling and input/output, and where proposals were discussed with compiler implementers. This is an early example of standards work being shaped by both language design and real implementation constraints.

Portability did not mean identical performance. One compiler might use different data layouts, runtime mechanisms, or code-generation strategies from another. The common base established language-level expectations so programs could be moved with less rewriting. A standard is a contract about behavior, not a promise that all hardware runs the same instructions or has the same speed.

Why Simula’s general-purpose turn mattered

Once the class, object, and process mechanisms could be used outside a simulation, they provided a vocabulary for ordinary software. A program could organize data and operations around the concepts it modeled. This approach contrasted with systems built entirely from global records and procedural routines, although procedural programming remained powerful and widely used.

The language also influenced later discussions about modularity and abstraction. Designers could debate whether a module should hide representation, how subclasses should inherit behavior, and how objects should communicate. These questions did not have one final answer; Simula made them concrete in a working language and encouraged researchers to investigate them.

Simula 67 did not immediately dominate commercial computing. Compiler availability, machine performance, training, and institutional demand all shaped adoption. It was significant in research and in the intellectual history of programming-language design, but it was not a universal replacement for FORTRAN, COBOL, or assembly. The influence of a language’s ideas may be much broader than the number of production systems built directly in that language.

Reading the origin without an “invented OOP” shortcut

The founders’ retrospective accounts are valuable because they can explain why a concept entered a design. They are still recollections written after the fact and should be read with the original reports and language definitions. The 1968 Common Base provides a primary specification; the authors’ HOPL paper provides a detailed narrative; Norwegian Computing Center records preserve institutional context.

The phrase “object-oriented programming” became common later than the design work that produced Simula 67. It is more accurate to describe the language using its documented features than to assume the terminology used today had the same meaning in 1967. Simula’s history is not a competition to award an isolated first. It is a story of a language whose simulation roots led to programming abstractions that proved useful in many other domains.

The durable lesson

Simula’s path from simulation to general programming shows how a domain-specific need can reveal a broader abstraction. The language’s designers needed entities with identity, behavior, and lifetimes; a reusable class and instance model helped express that structure. They needed activities to pause and resume; process mechanisms made time-dependent behavior manageable. A common base then offered a way to carry the language across machines.

Those innovations did not make every later program object-oriented, nor did they settle how software should be modularized. They created a practical, formal example that other researchers could study and extend. Simula 67 deserves attention as both a simulation language and an influential general-purpose language, with its origins and scope stated clearly rather than reduced to a slogan.

Related:

Sources:

Comments