Simula
Simula is a family of simulation programming languages, Simula I and Simula 67, developed in the 1960s at the Norwegian Computing Center in Oslo by Ole-Johan Dahl and Kristen Nygaard, recognized as the first object-oriented programming language for introducing foundational concepts like classes, objects, inheritance, and dynamic simulation processes.[1][2][3]
The development of Simula originated in spring 1961 at the Norwegian Computing Center (NCC), driven by the need for a specialized language to model complex systems in operational research, particularly Monte Carlo simulations and discrete event networks.[1][2] Nygaard's prior experience with nuclear reactor simulations in 1948 influenced the design, leading to Simula I's initial concepts documented on January 5, 1962, and its compiler completed in January 1965 for systems like the UNIVAC 1100.[2] Simula I extended ALGOL 60 with features for quasi-parallel process execution and set-based process management, enabling efficient simulation of dynamic systems.[1] By 1965–1966, the project evolved into Simula 67, a general-purpose language with its Common Base defined in June 1967 and finalized in May 1968, incorporating input-output hierarchies, string handling, and implementations on platforms like IBM 360/370 and Control Data systems.[1][4]
Simula's innovations profoundly shaped modern programming by pioneering object-oriented paradigms, where classes served as templates for objects modeling real-world entities with encapsulated data and procedures, supporting inheritance through subclass prefixing and virtual mechanisms for polymorphic behavior.[2][1] These concepts emphasized procedural abstraction, modularity, and type safety via static and dynamic checks, facilitating code reuse and error reduction in large-scale software.[2] The language's influence extended to subsequent systems like Smalltalk in 1972, which refined Simula's ideas into pure object-orientation, and later languages such as Java and C++, embedding OOP as a dominant paradigm in software engineering.[2] For their contributions, Dahl and Nygaard received the 2001 ACM A.M. Turing Award, often called the "Nobel Prize of computing," and the 2002 IEEE John von Neumann Medal.[3][2] Simula also inspired follow-on projects like the DELTA and BETA languages in the 1970s, and it remains relevant in academic contexts for teaching simulation and OOP principles.[4]
History
Development origins
Simula's development originated at the Norwegian Computing Center (NCC) in Oslo, Norway, where the project was initiated in spring 1961 to address pressing needs in simulation programming for operations research. The primary motivation stemmed from the challenges of modeling complex systems, particularly in industrial and economic contexts, where existing tools fell short in handling discrete event simulations efficiently.[5] This effort was driven by the recognition that simulation languages required more flexible structures for describing dynamic processes, building on the limitations observed in earlier Monte Carlo methods and general-purpose languages.[4]
The language was conceived as an extension of ALGOL 60, leveraging its block structure and programming security to ensure compatibility and broad appeal among European researchers. The initial focus centered on discrete event simulation, enabling the modeling of sequential processes in areas like production planning and resource allocation, which were critical for operations research applications in industry and economics. This approach allowed Simula to go beyond mere numerical computation, incorporating concepts for system description that facilitated both simulation and analysis of real-world scenarios.[1]
Early prototypes emerged as Simula I between 1964 and 1965, initially implemented under a contract for the UNIVAC 1100 series to support simulation tasks. This version marked the first operational form of the language, emphasizing its utility in process simulations for control and planning. A notable early application occurred in 1965, when Simula I was used for shipyard planning simulations, demonstrating its practical effectiveness in optimizing industrial workflows through discrete event modeling.[5]
Key contributors and milestones
The development of Simula was primarily led by Ole-Johan Dahl and Kristen Nygaard at the Norwegian Computing Center (NCC) in Oslo, where they conceived and designed the language as an extension of ALGOL 60 for simulation purposes.[3] Dahl, who joined NCC in 1963 after earlier work in software development at the Norwegian Defence Research Establishment (NDRE), focused on implementing core concepts like the process mechanism, while Nygaard joined NCC in 1960 and became its Director of Research in 1962, driving the initial vision for a simulation language.[4] Their collaboration built on foundational influences from Jan V. Garwick, a pioneer in Norwegian informatics who mentored both at NDRE in the 1950s, contributing early ideas on computing systems and garbage collection that informed Simula's runtime features.[4]
A key milestone occurred in early 1965, when the first Simula I compiler was completed for the Univac 1107 system, enabling practical use in simulation modeling.[4] This culminated in the public demonstration of Simula I at the IFIP Congress in New York from May 24 to 29, 1965, where Dahl and Nygaard presented results from a real-life simulation model, marking the language's debut and gaining international attention for its innovative approach to discrete event simulation.[4]
Building on Simula I, the team advanced to Simula 67 in 1966–1967, generalizing the language into a full programming system with class concepts for broader applicability.[4] Simula 67 was officially introduced by Dahl and Nygaard at the IFIP TC 2 Working Conference on Simulation Languages in Lysebu, near Oslo, from May 22 to 26, 1967, followed by the publication of the "SIMULA 67 Common Base Proposal" report in May 1967, which outlined the standardized core features required for all implementations.[6] This report, issued by the Norwegian Computing Center, established Simula 67 as a portable, extensible language and laid the groundwork for the formal Common Base definition later refined in 1968.[4]
In recognition of their pioneering work on Simula, which introduced fundamental object-oriented programming concepts such as classes, objects, and inheritance, Dahl and Nygaard received the A.M. Turing Award in 2001 from the Association for Computing Machinery.[3] The award citation specifically credited their design of Simula I and Simula 67 for ideas essential to the emergence of object-oriented programming.[7]
Standardization as Simula 67
The development of Simula 67 marked a pivotal transition from the earlier Simula I, which was primarily a simulation language implemented between 1963 and 1965 on the UNIVAC 1107 at the Norwegian Computing Center (NCC). Starting in 1965, efforts focused on refining the language to address limitations such as inefficient storage management and cumbersome element-set interactions, evolving it into a general-purpose programming language with full object-oriented capabilities. By 1967, the introduction of the class concept enabled the definition of objects encapsulating both data and procedures, supporting inheritance through subclasses and establishing Simula as the first language to implement comprehensive object-oriented programming (OOP).[4]
This standardization culminated in the official report "SIMULA 67 Common Base Language," authored by Ole-Johan Dahl, Bjørn Myhrhaug, and Kristen Nygaard at the NCC, with the initial definition finalized in June 1967 following the Simula 67 Common Base Conference held June 5 to 9 at the NCC. The report precisely defined the language's grammar and semantics, serving as the foundational specification for all subsequent implementations and ensuring portability across diverse systems. Established by the newly formed SIMULA Standards Group (SSG) in June 1967, with the Common Base formally approved at its first meeting in February 1968, it underwent minor revisions, such as the addition of string handling and input/output facilities by April 1968, to broaden its applicability beyond simulation.[4][8]
Key refinements in Simula 67 included the integration of coroutines to facilitate discrete-event simulation, achieved through statements like "detach" and "resume" that allowed quasi-parallel execution of independent processes within a simulation environment. Additionally, prefix notation was introduced for blocks and classes, enabling concise hierarchical declarations—such as prefixing a "block" with a class to inherit its properties—while maintaining ALGOL 60 compatibility for control structures. These changes enhanced modularity and expressiveness, with coroutines supporting dynamic process activation and prefixing promoting reusable abstractions without altering the core block structure.[8][4]
Adoption accelerated following the SSG's inaugural meeting in February 1968, where the Common Base was formally frozen, leading to implementations on major systems like the CDC 6600 and IBM 360 by 1968. The group, initially comprising NCC representatives and international collaborators such as those from Control Data Corporation, oversaw compliance and extensions, fostering widespread use in Nordic research projects and early software engineering efforts. By 1968, user communities began forming, exemplified by the SSG's role in coordinating the Nordic Simula Users Group, which promoted the language through conferences and shared resources.[4][8]
Design principles
Object-oriented foundations
Simula introduced the class as the foundational construct in programming languages, serving as a unified mechanism that encapsulates both data attributes and associated procedures, now commonly referred to as methods. This innovation allowed for the creation of modular, self-contained units that model real-world entities by bundling state and behavior, marking a departure from purely procedural paradigms like ALGOL 60. In Simula 67, a class declaration defines a blueprint specifying local data (via type declarations) and procedures that operate on that data, enabling the construction of complex systems through composition rather than global variables and separate functions.[5]
Classes in Simula function as templates for generating objects, where each object is an independent instance with its own data space. Instantiation occurs dynamically using the new keyword, which allocates memory for the object and initializes it according to the class specification, returning a reference to the newly created entity. This approach supports runtime creation of multiple objects from the same class, each maintaining autonomy while sharing the common structure and behavior defined in the template. The mechanism ensures that objects can be referenced and manipulated indirectly, facilitating flexible program architectures without fixed compile-time structures.[5][1]
To achieve polymorphism, Simula incorporated virtual procedures, which enable late binding of method calls based on the actual type of the object at runtime rather than the reference type. A procedure declared as virtual within a class allows subclasses to override it, ensuring that the appropriate implementation is invoked dynamically during execution. This semi-dynamic binding resolves the procedure call to the version defined in the object's specific class, promoting extensibility and reuse across class hierarchies. Virtual procedures thus provide the core enabler for polymorphic behavior, where objects of different classes can be treated uniformly through a common interface.[5][1]
The prefix form in Simula's class activation further supports nested hierarchies by allowing one class to be prefixed to another, effectively creating a subclass that inherits all data and procedures from the prefix class while adding or modifying its own. This prefixing mechanism activates the base class's context during the subclass's definition and instantiation, enabling layered abstractions where inner classes operate within the scope of outer ones. Such nesting facilitates the construction of deep, organized class structures, with each level building upon the previous to form increasingly specialized object types. For instance, inheritance via prefixing allows brief extensions of base classes, as explored in subsequent examples of class definitions.[5]
Simulation-oriented features
Simula's simulation-oriented features were designed to facilitate discrete event simulation and process modeling, enabling the representation of dynamic systems through interacting entities without requiring true hardware parallelism. Central to this is the use of coroutines, implemented via the Process class, which allows multiple processes to execute quasi-concurrently by interleaving their active phases. A process object can detach from the main execution chain using the detach statement, suspending its execution until reactivated, thus simulating concurrent activities in a single-threaded environment. This coroutine mechanism supports the modeling of independent yet interacting components, such as in system dynamics where processes represent entities like customers or machines.[8][4]
Discrete event simulation in Simula advances time through event-driven mechanisms, primarily the hold and wait statements within the Process class. The hold(T) statement passivates the current process and schedules its resumption after a delay of T time units along the simulation's time axis, effectively advancing the global simulation time to the next event. Meanwhile, wait(S) passivates the process and inserts it into an ordered set S, typically a queue representing a resource contention point, where it remains until explicitly reactivated via an activate or resume statement. These statements ensure that simulation time progresses only when events occur, avoiding unnecessary computation during idle periods.[8][1]
The built-in Simulation and Process classes provide foundational support for event management and resource handling. The Simulation class, which extends the Simset class for two-way linked lists, establishes a global time axis and the sequencing set (SQS)—an event queue implemented as a priority-ordered Simset where event notices are ranked by their EVTIME attribute. The Process class, defined as a subclass of link within the Simulation class and incorporating coroutine capabilities, equips objects with properties for managing active phases, event notices, and states (active, passive, suspended, or terminated). Together, they enable efficient event queue operations, such as inserting and extracting processes based on simulation time, facilitating resource management through queue-like structures.[8]
These features found practical application in modeling system dynamics, particularly in industrial simulations involving queues, servers, and entity interactions. For instance, in simulations of manufacturing environments, such as ASEA's job shop models or paper mill lumber yards, processes could represent jobs or materials queuing for servers (resources), using wait to handle contention and hold to model processing times, thereby analyzing throughput and bottlenecks with high fidelity. This approach allowed for scalable representations of complex interactions, influencing subsequent simulation languages and tools in operations research.[4][1]
Innovative mechanisms like call-by-name
One of Simula's key innovations in parameter passing is the support for call-by-name, an optional mechanism for procedure parameters that evaluates the actual argument only when the formal parameter is referenced during procedure execution.[8] This approach, inherited and adapted from ALGOL 60, performs a textual substitution of the actual parameter expression into the procedure body, allowing it to be re-evaluated dynamically each time it is used, which contrasts with call-by-value where the argument is evaluated once at the point of the call and a copy is passed.[8] In practice, this enables lazy evaluation, where computations are deferred until necessary, and facilitates higher-order functions by treating expressions as substitutable units rather than fixed values.[9]
The implementation of call-by-name in Simula relies on generating thunks—small procedures that encapsulate the actual argument expression and its evaluation environment—for each formal parameter specified in this mode.[10] Upon each reference to the formal parameter within the procedure, the corresponding thunk is invoked to compute and return the current value of the expression, ensuring that side effects or changes in the caller's context are reflected accurately.[10] This thunk-based mechanism, while computationally expensive due to repeated evaluations and the overhead of thunk creation and invocation, provides significant flexibility for expressing complex simulation scenarios where parameters might represent dynamic conditions or event-driven computations.[11]
Beyond parameter passing, Simula introduced detached tasks as a mechanism for independent process execution, allowing objects instantiated from classes to operate in a quasi-parallel manner decoupled from the main control flow.[4] A task becomes detached via the detach statement, transitioning to an autonomous state managed by its local sequence control, while the overall simulation progresses through a central event queue; resumption occurs explicitly with resume on the object reference, enabling coroutine-like behavior for modeling concurrent activities without true parallelism.[4] This feature supports flexible simulation expressions by permitting tasks to suspend, resume, and interact via shared data structures, though it introduces overhead in storage management and sequencing to maintain block-structured scoping.[1]
Language syntax and semantics
Basic program structure
Simula programs are organized using a block structure inherited from ALGOL 60, where the main program forms a primary block consisting of a declaration section followed by a statement sequence.[8] This structure allows for modular decomposition, with blocks serving as self-contained units that encapsulate local declarations and executable statements, supporting nested hierarchies for complex programs.[12] The main block typically operates at the system level, initiating execution as a detached object in a quasi-parallel environment.[8]
The outer block syntax employs the keywords begin and end to delimit the scope of declarations and statements, ensuring clear boundaries for visibility and execution.[12] Declarations precede statements within the block head, including type specifications for variables such as integers or references, while the body contains the sequence of statements to be executed sequentially.[8] Blocks may be prefixed by class declarations to integrate predefined functionality, such as input/output handling via the BasicIO class.[12]
For control flow, Simula provides labels—defined as identifiers followed by a colon—and unconditional go to statements, which transfer execution to a labeled point within the same block instance.[8] However, these unstructured mechanisms are discouraged in favor of structured alternatives like conditional statements and loops, aligning with the language's foundational role in promoting disciplined programming practices.[13]
Compilation units in Simula consist of separate blocks or class definitions that can be compiled independently, with the main program block linked to external classes via declarations such as external class.[12] This modularity allows programs to incorporate reusable components, such as simulation classes, while maintaining the overall structure as a cohesive prefixed block, often enclosed within a standard prefix like BASICIO for runtime support.[8]
Data types and control flow
Simula supports a set of primitive data types that form the foundation for its expressions and variables, including integer, real, Boolean, and text types. The integer type represents whole numbers, including positive, negative, and zero values, with an optional short integer subtype that may be implemented as a subrange of the full integer type depending on the compiler. Real numbers are handled by the real type for standard floating-point values, with an optional long real subtype for higher precision, also implementation-defined. The Boolean type accommodates only the values true and false, serving as the basis for logical operations and conditions. Text, used for character strings, is an ordered sequence of characters that can be empty, with attributes like length accessible via dot notation (e.g., T.length), and initialized to notext.[8][14]
Arrays in Simula are declared with a specified type and bounds, enabling multi-dimensional subscripted variables, such as [integer](/page/Integer) array A(1:10), where bounds checking occurs at runtime to prevent access errors outside the defined range. References, functioning as pointers to objects, are declared with a qualification like ref(ClassName), holding either a specific object or the special value none to indicate no object; they allow dynamic linking in simulations but require compatibility checks for assignments, such as ensuring subclass relationships. Simula employs static type checking where possible, enforcing strong typing by requiring exact type matches for assignments and operations, though implicit conversions are permitted among arithmetic types (e.g., integer to real) and explicit conversions via built-in procedures like entier for real to integer; references introduce some flexibility but trigger runtime errors for invalid assignments.[8][14]
Control flow in Simula is managed through standard conditional and iterative constructs derived from ALGOL influences, providing structured programming capabilities. The if-then-else statement evaluates a Boolean expression to selectively execute one of two statements, with syntax if Boolean-expression then statement [else statement], where the else clause is optional; for example, if x > 0 then y := 1 else y := 0. The while-do loop repeats a statement as long as a Boolean condition holds, equivalent to a labeled if-then-goto structure for implementation, as in while Boolean-expression do statement. For loops offer versatile iteration, assigning values to a simple variable via a for-right-part such as for i := 1 step 1 until n do statement, supporting value lists, steps, and until clauses for controlled repetition over ranges or collections.[8][14]
Switch statements facilitate selection based on an integer subscript, declared as switch switch-identifier := switch-list, where the list contains designational expressions (labels or procedure calls) indexed from 1, allowing goto-like transfers without direct labels; for instance, switch s := L1, L2, Q(5) selects based on s(2). Conditional expressions embed if-then-else logic within expressions, yielding a value of the common type between alternatives, such as if x > 0 then 1 else 0.0, with type promotion to long real if either branch requires it to ensure consistency. These mechanisms support precise control in simulation models, where loops and conditions often manage event sequencing.[8][14]
Procedures and expressions
In Simula, procedures are defined using a syntax that closely resembles that of ALGOL 60, with the declaration beginning with the keyword procedure followed by the procedure identifier and an optional formal parameter list, terminated by a semicolon, specifications for parameter types and modes, and the procedure body enclosed between begin and end.[8] For example, a simple procedure to compute the sum of two integers might be declared as procedure sum(a, b); integer a, b; sum := a + b; end;, where the specifications follow the parameter list to indicate types such as integer, real, boolean, text, or procedure.[14] This structure allows procedures to encapsulate reusable code blocks, functioning similarly to subprograms in earlier languages while integrating with Simula's block-oriented design.
Parameter transmission in Simula procedures supports multiple modes, with call-by-value as the default for value-type parameters like scalars (integers, reals, booleans), where a local copy of the actual parameter's value is created upon invocation, ensuring the original argument remains unchanged.[8] For non-value types such as arrays, switches, or labels, the default shifts to call-by-reference, passing a reference to the original data structure, which allows modifications to affect the caller's variables.[14] Call-by-name is an optional mode, explicitly specified for parameters that require textual substitution and re-evaluation each time the formal parameter is referenced within the procedure body; this mode, inherited from ALGOL 60, is particularly useful for passing expressions or procedure parameters but is restricted to non-value types to avoid implementation complexities.[8]
Expressions in Simula are evaluated according to rules derived from ALGOL 60, with arithmetic expressions using standard infix notation and operators such as + (addition), - (subtraction), * (multiplication), / (real division), // (integer division), and ** (exponentiation), processed from left to right subject to operator precedence where exponentiation has the highest priority, followed by multiplication and division, then addition and subtraction.[14] Procedure calls and certain constructs like conditional expressions employ prefix notation, where the operator or procedure name precedes its arguments, as in if boolean-expression then statement1 else statement2.[8] Boolean expressions combine relational operators (=, /=, <, <=, >, >=) and logical operators (and, or, not), evaluated similarly with short-circuiting not supported, ensuring all subexpressions are computed unless syntactically avoided.
Variables declared within a procedure have local scope, visible only inside that procedure's body and any nested blocks, promoting encapsulation and preventing unintended interactions.[14] Access to outer (global) variables is achieved through lexical scoping, where non-local identifiers retain their meaning from enclosing blocks unless shadowed by local declarations, enabling procedures to interact with program-wide state while maintaining modularity.[8] This scoping mechanism aligns with Simula's block structure, treating procedures as special cases of blocks for visibility rules.
Programming examples
Minimal executable program
The minimal executable program in Simula demonstrates the language's fundamental block structure, consisting of a simple declaration, assignment, and termination without any input/output operations or advanced features. This program compiles and runs successfully but produces no visible output, serving as a basic test of the compiler and runtime environment.[8]
Here is the simplest valid example:
Begin
Integer x;
x := 1;
End
Begin
Integer x;
x := 1;
End
In this program, the Begin keyword initiates a block, which is the core organizational unit in Simula for enclosing declarations and statements.[8] The declaration [Integer](/page/Integer) x; introduces a simple integer variable named x, adhering to Simula's type-specific declaration syntax where the type precedes the identifier.[8] The assignment x := 1; uses the := operator to bind the value 1 to the variable x, performing a basic value assignment without side effects.[8] Finally, the End keyword terminates the block, completing the program's execution.[8]
The purpose of this minimal program is to illustrate Simula's essential syntax for variable handling and block scoping, derived from its ALGOL 60 heritage, while avoiding any simulation or object-oriented constructs.[8] It highlights the language's procedural foundation, where programs are structured as nested blocks that can be prefixed with classes like Direct or Simulation for more complex applications, though such prefixes are optional for this basic case.[8]
A variation to verify compilation and execution involves adding a basic output statement, such as OutInteger(x);, which would display the value 1 if the program is prefixed with the BasicIO class, but this extends beyond the pure minimal structure.[8]
Hello world demonstration
A canonical demonstration of basic output in Simula is the "Hello, World!" program, which utilizes the language's standard input/output facilities to display a simple text message on the console.[15]
The following code exemplifies this:
simula
Begin
OutText("Hello, World!");
OutImage;
End
Begin
OutText("Hello, World!");
OutImage;
End
This program follows the basic structure of a main block enclosed by Begin and End statements.[15] The OutText procedure, part of Simula's standard I/O library, accepts a string literal (enclosed in double quotes) as its argument and transfers the contents to the output buffer by sequentially retrieving and writing each character using low-level operations like getchar.[15] If the buffer position would overflow due to the text length, OutText automatically invokes OutImage to flush the current line before continuing.[15] The explicit call to OutImage then flushes the accumulated output from the internal image buffer (a text frame) to the standard output stream (Sysout), ensuring the message is displayed, followed by a newline.[16][15]
Simula's text handling relies on the built-in text type, which represents dynamic sequences of characters managed through frames with attributes like length, pos (position), and methods such as setpos, getchar, and more for traversal.[15] Procedures like OutText and its counterpart InText (for input) were integral to Simula since its development in the 1960s, enabling formatted reporting of simulation results and data interchange in early computing environments.[17][15]
For extended output, Simula provides procedures like OutInt to format and display integer values alongside text; for instance, OutInt(42, 5); OutImage; would output the number 42 right-justified in a field of width 5.[17] This allows simple mixed-type demonstrations while adhering to the language's buffered, file-oriented I/O model.[16]
In Simula, classes are defined using the class keyword followed by an optional prefix for inheritance, formal parameters, attribute declarations, and a body containing procedures and statements. This structure encapsulates data and behavior into reusable units, forming the basis for object creation. The language employs a block-structured syntax inherited from ALGOL 60, where the class body is delimited by begin and end.[8]
A representative example is a Point class representing a two-dimensional point with coordinates:
simula
class Point (x, y); real x, y;
begin
virtual: procedure Move (dx, dy); real dx, dy;
begin
x := x + dx;
y := y + dy;
end;
end;
class Point (x, y); real x, y;
begin
virtual: procedure Move (dx, dy); real dx, dy;
begin
x := x + dx;
y := y + dy;
end;
end;
Here, x and y are attributes passed as formal parameters during instantiation, and Move is declared as a virtual procedure, enabling it to be overridden in subclasses for dynamic dispatch at runtime. Virtual procedures support polymorphism by resolving calls based on the actual object type rather than the reference type.[8][8]
Inheritance in Simula is achieved through prefixing, where a subclass declares the parent class before its own identifier, inheriting all attributes and procedures while allowing extensions or overrides. Simula implements a single inheritance model, permitting only one parent class per subclass to maintain a linear hierarchy. For instance, a Circle subclass can extend Point by adding a radius attribute and overriding the Move procedure to adjust the center:
simula
Point class Circle (x, y, radius); real x, y, radius;
begin
procedure Move (dx, dy); real dx, dy;
begin
! (inherited from Point);
OutText ("Circle moved to ("); OutReal (x, 3, 5); OutText (", ");
OutReal (y, 3, 5); OutText (") with radius "); OutReal (radius, 3, 5); OutImage;
end;
end;
Point class Circle (x, y, radius); real x, y, radius;
begin
procedure Move (dx, dy); real dx, dy;
begin
! (inherited from Point);
OutText ("Circle moved to ("); OutReal (x, 3, 5); OutText (", ");
OutReal (y, 3, 5); OutText (") with radius "); OutReal (radius, 3, 5); OutImage;
end;
end;
The ! notation invokes the parent's implementation before or after subclass-specific code, ensuring behavioral extension.[8][8]
Objects are instantiated using the new operator, which allocates memory and initializes attributes with provided actual parameters, returning a reference to the object. References are declared with the ref type qualifier. An example program demonstrating instantiation and method calls:
simula
begin
ref (Point) p; ref (Circle) c;
p := new Point (1.0, 2.0);
c := new Circle (3.0, 4.0, 5.0);
inspect p do Move (1.0, 1.0);
inspect c do Move (2.0, 2.0);
end;
begin
ref (Point) p; ref (Circle) c;
p := new Point (1.0, 2.0);
c := new Circle (3.0, 4.0, 5.0);
inspect p do Move (1.0, 1.0);
inspect c do Move (2.0, 2.0);
end;
The inspect statement provides scoped access to the object's attributes and methods, allowing calls like Move to invoke the appropriate virtual procedure dynamically— the base version for p and the overridden version for c. This mechanism exemplifies Simula's pioneering support for late binding in object-oriented programming.[8][8]
Discrete event simulation
Simula's discrete event simulation framework is centered on the Simulation class, which manages an ordered event list of processes scheduled by their activation time (EvTime), ensuring chronological execution of events. Core Simula provides basic simulation via the Simulation and Process classes, while extensions like DEMOS add advanced resource management and entity modeling.[8] Processes, defined as subclasses of the Process class, represent active entities like customers or servers, and can be suspended and rescheduled using statements such as Hold, Activate, and Passivate.[8] The Hold mechanism advances the global simulation clock by a specified duration, suspending the current process and reinserting it into the event list at the future time, which models time progression in systems like queues.[18]
Random distributions are integrated for realistic modeling of stochastic elements, such as arrival and service times. The NegExp function generates values from a negative exponential distribution, suitable for Poisson processes in queueing models, where the mean inter-arrival time determines the rate parameter.[18] Other distributions like Normal or Uniform can be used similarly with Hold to vary service durations.[18]
A representative queueing model in Simula simulates a simple single-server system, such as a barber shop, where customers arrive, are served, and depart. This can be implemented using the DEMOS extension for resource management and event scheduling, treating the server as a resource with capacity 1.[18] The following code snippet, adapted from standard single-server queue examples in Simula literature, defines the core components (assuming DEMOS is loaded as an external class):
external class Demos = 'demos'; ! Path to DEMOS library
Demos begin
ref(res) [server](/page/Server);
server :- new res('server', 1);
entity [class](/page/Class) Customer;
begin
server.[acquire](/page/Acquire)(1);
Hold(15.0); ! Fixed service time of 15 units
server.[release](/page/Kylie_Live_in_New_York)(1);
end***Customer***;
! Schedule customers and run [simulation](/page/Simulation)
new Customer('c1').schedule(0.0);
Hold(65.0); ! Run for 65 time units
end;
external class Demos = 'demos'; ! Path to DEMOS library
Demos begin
ref(res) [server](/page/Server);
server :- new res('server', 1);
entity [class](/page/Class) Customer;
begin
server.[acquire](/page/Acquire)(1);
Hold(15.0); ! Fixed service time of 15 units
server.[release](/page/Kylie_Live_in_New_York)(1);
end***Customer***;
! Schedule customers and run [simulation](/page/Simulation)
new Customer('c1').schedule(0.0);
Hold(65.0); ! Run for 65 time units
end;
In this setup, the event list is maintained by DEMOS, ordering activations by EvTime and handling resource waits via internal queues.[18] The acquire and release operations manage the server's availability, suspending customers if occupied.
To gather output statistics, users implement counters within processes or leverage DEMOS reporting facilities. For stochastic models with exponential arrivals (mean 5 units) and service (mean 4 units) over 100 time units, the system utilization is ρ = 0.8; expected throughput is around 20 customers, with average wait time in queue approximately 16 units per the M/M/1 formula Wq = ρ / (μ (1 - ρ)).[18] These metrics provide insights into queue performance, such as the probability of idle server time or maximum queue length.[18]
Historical compilers
The first Simula compiler was developed in 1965 at the Norwegian Computing Center for the UNIVAC 1107, implemented as an extension of the UNIVAC ALGOL 60 compiler under a contract with Sperry Rand Corporation.[19] This implementation rendered Simula I fully operational by January 1965, enabling initial simulation applications on the UNIVAC hardware.[20]
Subsequent ports expanded Simula's reach. In 1968, the compiler was adapted for the UNIVAC 1108, transitioning from the original 1107 system while maintaining compatibility with the ALGOL base. An implementation for the IBM System/360, known as SIMULA/IBM, was also developed during this period, supporting the growing adoption of IBM mainframes for Simula programs.
In the Nordic region, specialized implementations facilitated local use. SSIMULA targeted Univac systems, while DSIMULA was created for DEC hardware, reflecting efforts to tailor Simula to prevalent regional computing environments. Additionally, an agreement in 1967 between Control Data A/S Norway and the Norwegian Computing Center led to a Simula 67 compiler for CDC systems, including the 6600, broadening availability on high-performance machines.[21]
These early compilers were inherently machine-specific, with implementations tied closely to particular hardware architectures and lacking a unified standard runtime environment, which hindered cross-platform portability until later standardization efforts. The Simula 67 standard, formalized in 1967, provided a reference for these developments but did not immediately resolve runtime inconsistencies.[21]
Modern interpreters and extensions
In the 21st century, efforts to revive Simula have focused on open-source implementations that enhance accessibility and portability, primarily through Java-based tools and web environments. The Portable Simula Revisited project, initiated around 2017 following a lecture by James Gosling at Simula's 50th anniversary celebration, provides an open-source Simula compiler written in pure Java.[22] This compiler adheres to the 1985 Simula Standard, which extends Simula 67 with features like constant declarations and advanced text manipulation (e.g., the Start procedure and concatenation operator &), while maintaining core concepts such as classes, inheritance, and discrete event simulation via the SIMULATION class.[23] It compiles Simula source code directly to Java class files using the Java Class File API, enabling execution on the Java Virtual Machine without additional runtime dependencies beyond Java 25 or higher (updated as of April 2025).[24]
Portable Simula integrates seamlessly with modern Java ecosystems, leveraging features like virtual threads from Project Loom to optimize performance in large-scale simulations; for instance, it reduces execution time for process-heavy programs like PrimeUnder with one million instances.[22] This allows Simula code to benefit from Java's garbage collection and multithreading, effectively bridging legacy simulation logic with contemporary hardware. Additionally, it reconstructs and supports legacy code from the 1979 S-Port Simula system, originally developed by the Norwegian Computing Center, ensuring compatibility for historical programs by handling older syntax and runtime behaviors through an optional Simula Virtual Machine backend.[22]
Complementing these, GNU Cim serves as another open-source compiler for Simula, translating source code to C for compilation with standard C tools, and remains available on platforms like Linux distributions as of 2025, though its last major update was in 2009.[25] Active forks, such as Cim-Open and the GitHub repository by sergev, provide maintained alternatives with ongoing development.[26] For educational purposes, web-based environments have emerged, including the Tutorials Point Online Simula Compiler, which allows browser-based editing, compilation, and execution of Simula code without local setup.[27] Similarly, Try It Online (TIO) supports Simula via GNU Cim integration, facilitating quick testing and sharing of programs in an online REPL-like interface.[28] These tools provide partial support for Simula 67 constructs in research and teaching contexts, such as class hierarchies and coroutines, often within Java bindings that expose Simula objects as Java classes for hybrid applications.[23]
Overall, these modern implementations prioritize compatibility with legacy Simula code for historical simulations and research, while extending usability through Java interoperability and web accessibility, without altering the language's foundational object-oriented and simulation paradigms.[22]
Availability and compatibility
Simula remains accessible today through several modern platforms and tools, enabling users to experiment with the language without historical hardware. Web-based compilers, such as the online Simula compiler at Tutorials Point, allow users to write, compile, and execute Simula code directly in a web browser, supporting basic program development and testing.[27]
For local installation, the GNU Cim compiler provides a free, open-source implementation of Simula 67 with extensions to the 1986 standard, which can be built from source on Linux and other Unix-like systems using standard GNU tools like Autoconf and Automake.[25] This approach supports execution on contemporary hardware, though users may need to manage dependencies manually. Additionally, emulators for vintage systems, such as the UNIVAC 1100 series emulator available on GitHub, enable running original Simula binaries from the 1960s and 1970s on modern machines.[29] For the CDC 6000 series, historical emulation documentation from 1977 exists, but modern open-source emulators are limited.[30]
Compatibility with modern environments is constrained by Simula's design roots in 1960s computing. Implementations adhere to the ISO character set, supporting primarily ASCII characters (codes 32–126) for source code and output, with no full Unicode support; non-ASCII characters, including most control codes (0–31 except format effectors like TAB and LF), are illegal and trigger compiler errors.[31] As a superset of ALGOL 60, Simula offers broad compatibility with ALGOL syntax and semantics, but some implementations provide only partial support for the full ALGOL subset due to Simula-specific extensions like classes and coroutines, potentially requiring adjustments for pure ALGOL code.[8]
Educational resources facilitate learning and historical exploration, including comprehensive tutorials like "An Introduction to Programming in Simula," which covers the 1985 standard with examples and exercises.[23] The Montreal SIMULA Site offers online references, sample programs, and tools for beginners, while virtual machines and emulators—such as those for UNIVAC hardware—allow execution of original binaries to study legacy simulations.[32] Modern interpreters, detailed elsewhere, further enhance cross-platform access.
Legacy and influence
Impact on object-oriented programming
Simula 67, released in 1967, is widely recognized as the first programming language to incorporate classes and objects as fundamental constructs, predating Smalltalk's development in the early 1970s.[33][34] Developed by Ole-Johan Dahl and Kristen Nygaard at the Norwegian Computing Center, it extended ALGOL 60 to support these features primarily for simulation purposes, but their generality enabled broader application in structured programming.[5] This introduction marked Simula as the birthplace of object-oriented programming (OOP) in computing history, earning Dahl and Nygaard the 2001 ACM A.M. Turing Award for pioneering OOP concepts that revolutionized software design.[33]
Simula exported core OOP principles that became foundational to the paradigm, including encapsulation through class-defined data and procedures, inheritance via class prefixing to share common attributes and behaviors, and polymorphism achieved with virtual procedures for dynamic binding at runtime.[5][35] These mechanisms allowed objects to act as autonomous units with internal state and operations, promoting modularity and reusability in complex systems like discrete event simulations.[34] For instance, virtual procedures enabled subclasses to override parent behaviors without altering the original class structure, a flexibility that addressed limitations in earlier procedural languages.[5]
The academic influence of Simula is evident in the seminal papers by Dahl and Nygaard, such as their 1966 Communications of the ACM article on Simula as a simulation language and the 1968 paper on classes and co-routines, which articulated OOP's theoretical underpinnings and directly informed subsequent research. These works shaped OOP textbooks and curricula, providing the conceptual framework for encapsulation, inheritance, and late binding that educators and researchers adopted to teach object orientation as a paradigm for modeling real-world entities.[33] By the 1980s, Simula's ideas had permeated computer science education, establishing OOP as a dominant approach in software engineering and influencing the design of languages that prioritized abstraction and extensibility.[5]
Influence on subsequent languages
Simula's innovations in object-oriented programming profoundly shaped subsequent languages, both directly and indirectly. One direct successor was the BETA programming language, developed in the 1980s at the University of Aarhus in Denmark by researchers including Ole Lehrmann Madsen, Birger Møller-Pedersen, and Kristen Nygaard. BETA extended Simula's class-based model with a more unified approach to objects, incorporating nested classes, patterns for dynamic instantiation, and improved support for concurrent programming while retaining strong static typing.[36][37]
Indirectly, Simula influenced Smalltalk, pioneered by Alan Kay at Xerox PARC in the 1970s. Kay explicitly credited Simula as a major inspiration for Smalltalk's object-oriented design, particularly its use of classes and inheritance to model dynamic systems, as noted in his 1990 interview where he described demonstrating Smalltalk to Simula co-creator Kristen Nygaard, who recognized the conceptual lineage immediately.[38] This influence helped evolve OOP from simulation tools to a general paradigm emphasizing message-passing and encapsulation.
Simula's class-inheritance model also informed C++, created by Bjarne Stroustrup starting in 1979 at Bell Labs. Stroustrup, who had used Simula 67 for simulations during his PhD, designed C++ to integrate Simula's facilities for program organization—such as classes, inheritance, and virtual functions—with C's efficiency for systems programming. He stated that "C++ was designed to provide Simula’s facilities for program organization together with C’s efficiency and flexibility," directly adopting Simula's approach to type-safe polymorphism while prioritizing performance.[39]
Similarly, Java, developed by James Gosling and his team at Sun Microsystems in the early 1990s, drew heavily from Simula's OOP foundations. Gosling, who first encountered Simula as a student and later described falling in love with its elegant class and inheritance mechanisms, incorporated these into Java's design to enable platform-independent, robust object-oriented development. He acknowledged Simula as a major influence during a 2017 lecture at Simula's 50th anniversary, highlighting how its concepts shaped Java's emphasis on classes, interfaces, and inheritance.[40]
Beyond OOP, Simula's call-by-name parameter passing, inherited from ALGOL 60 but refined for object contexts, prefigured lazy evaluation strategies in functional languages.
Contemporary applications and research
Despite its historical roots, Simula maintains niche applications in legacy simulations for shipping and operations research, where modern interpreters enable the execution of original codebases for validation and analysis. For instance, Portable Simula Revisited, an open-source Java-based implementation, allows researchers to run and study classic Simula programs from the 1960s and 1970s designed for shipyard process modeling and discrete event simulations in industrial operations.[41]
In academic research, Simula continues to be a focal point in studies on the history of object-oriented programming (OOP), highlighting its pioneering role in introducing classes, objects, and inheritance. Recent analyses, such as those exploring Simula's original intent for problem-oriented simulation versus contemporary OOP paradigms, underscore its enduring conceptual influence while critiquing modern deviations from its simulation-focused design principles.[42] These studies often draw on archival code and documentation to trace how Simula's coroutines and dynamic binding shaped subsequent paradigms, with over 50 years of scholarship affirming its foundational status.[43]
The language has seen revival in education through online tools and interpreters like Portable Simula Revisited, which facilitate teaching OOP concepts and simulation techniques to students without requiring obsolete hardware. Initiated following a 2000 lecture by Simula co-creator Ole-Johan Dahl at the University of Oslo, this project provides a portable environment for compiling and executing Simula code, enabling interactive exploration of historical programs in modern curricula focused on programming language evolution.[41] Educational applications emphasize hands-on simulation exercises, bridging theoretical history with practical coding to illustrate early OOP mechanics. Ongoing open-source projects, such as a C++ and Qt-based parser, code model, LuaJIT compiler, and IDE for Simula 67 initiated around 2019 and active as of 2025, further support educational and research exploration of the language.[44]
Modern projects include extensions for parallel simulation, building on Simula's process-oriented model to support distributed discrete event simulations. For example, research into parallelizing Simula-based applications proposes methodologies for concurrent execution on multiprocessor systems, adapting the language's inherent simulation structures for contemporary high-performance computing needs.[45] Additionally, inspired implementations like the Simulus Python library extend Simula's concepts to parallel and distributed environments, allowing process interactions in multi-simulator setups for scalable modeling.[46]
Challenges in maintaining Simula codebases persist, particularly in industries with long-standing simulation dependencies, where compatibility issues with modern systems necessitate ongoing porting efforts using tools like Portable Simula. In Norway, where Simula originated, legacy code from early industrial applications requires specialized expertise to ensure reliability in operational contexts.[47]