The most widely influential programming languages are often not the most widely used. Concepts from less-popular languages often influence more-mainstream languages, and very often a popular language begins life as a simplified version of a research or domain-specific language.
In this series, we'll take a look at some of the languages that have influenced the current crop of popular languages. Part 1 of this series examined ALGOL, whose derivatives account for a significant fraction of all software. This week, we'll look at Simula, which also influenced a lot of languages, including C++, Java, C#, and so on.
As the name would imply, Simula was designed for writing simulations. Simulating complex systems typically involves simulating simple components and their interactions. Often, simulations involve a lot of similar components that communicate via a well-defined interface.
Simula was the language that introduced three very important concepts:
- Subclassing (inheritance)
- Virtual functions
Classes in Simula were designed to implement abstract data types. Prior programming languages had included support for records (groups of primitive data types). Classes allowed you to combine data with operations on that data. This combination was possible in other languages, using records that contained function pointers, but Simula was the first to provide explicit language support for it. This development was very important in software engineering because it allowed for creating isolated software components that communicated with each other only via a well-defined interface.
The connection between data and operations was a key development for Simula. In theoretical computer science, this grouping is very common; types are usually defined by the operations that they support. The same rule is true for primitive types in a lot of programming languages. Most don't specify how integers are stored; instead, they merely specify the behavior of operations such as add, subtract, multiply, and so on. Often these operations impose some constraints on the implementation (for example, by requiring either fixed or minimum numbers of bits to represent the required range), but the precise implementation isn't usually exposed to the programmer.
Simula extended this connection to user-defined types. With languages like ALGOL, you could define records (what C programmers would call structures), and you could define functions that operated on those records. In the simplest case, Simula classes were little more than some syntactic sugar to make clearer which operations were supported on specific types.