textlize pricing account
Casey Muratori – The Big OOPs: Anatomy of a Thirty-five-year Mistake – BSC 2025
Cover

02:27:33

The Big OOPs: Tracing a 35-Year Architectural Mistake

This talk dissects the history of a prevalent software architecture pattern—compile-time hierarchies that mirror the domain model—and argues that its widespread adoption, despite early evidence of a superior alternative, represents a significant 35-year mistake in software design.

Core Insight

The central argument is that the encapsulation boundaries in object-oriented programming (OOP) were often placed incorrectly. The popular model drew boundaries around objects (like a 'Mech' class) to encapsulate all their data and behavior. However, a more powerful approach, first demonstrated in the 1963 program Sketchpad and later in the 1998 game Thief: The Dark Project, is to draw boundaries around systems (like a 'Physics' or 'Combat' system).

This alternative architecture, now often called an Entity Component System (ECS), prioritizes system-level logic and data locality over object-level inheritance, leading to more flexible and performant designs, particularly for complex, interactive software like games and simulations.

The Spark: Looking Glass and Thief (1998)

The story begins with Looking Glass Studios, an influential game developer known for titles like Ultima Underworld and System Shock. For years, their approach to in-game entities used what the speaker calls "fat structs": large, singular data structures containing data for many types of entities, differentiated by type fields or flags.

During the development of Thief: The Dark Project (1998), they radically changed their approach. Instead of fat structs or the then-popular deep inheritance hierarchies, they created a system where an entity was merely an ID. This ID was used to look up and aggregate data from discrete, system-specific data stores (e.g., a Physics system, a Combat system).

This was arguably the first commercially released Entity Component System (ECS). The crucial difference was the placement of encapsulation boundaries: not around domain-model objects, but around architectural systems.

The Prevailing Model: Compile-Time Hierarchies

In contrast, the dominant OOP style encouraged a direct translation of the domain model into a compile-time inheritance hierarchy. A classic example, used in early papers by Bjarne Stroustrup and others, is a Shape class with derived classes like Circle and Triangle.

The speaker clarifies that the critique is not of OOP as a whole, but specifically of this practice of building deep, compile-time inheritance trees that tightly couple the software's architecture to its domain model. This model makes certain types of changes and system-level optimizations difficult.

Tracing the History: From C++ to Simula

To understand how the hierarchy model became dominant, the talk delves into its origins:

  • Bjarne Stroustrup and C++: Stroustrup's positive experience with the class system in Simula while writing a distributed systems simulator in the late 1970s was a key influence. He valued the type safety and error checking it provided. However, his initial attempt to use Simula failed due to terrible build times and slow performance (largely from primitive garbage collection), forcing a rewrite in a non-OOP language. This experience directly led to his goal for C++: to add Simula-like classes to the C language, prioritizing performance and avoiding garbage collection.
  • Kristen Nygaard and Ole-Johan Dahl (Simula, 1967): The creators of Simula, which introduced the class and inheritance concepts. Their goal was code reuse for simulation software. Their famous example involved a Car class with Truck and Bus subclasses, and they also used inheritance for utility purposes (e.g., deriving from a Link class to get linked-list functionality).

The Original Idea: Tony Hoare's Record Handling

Nygaard and Dahl credited their subclassing idea to a 1966 paper by Tony Hoare (of Quicksort fame) on "record handling." Hoare's paper proposed a solution for working with records (structs) that could be of different types. He suggested using a tagged (or discriminated) union—a struct with a type field and a union of possible sub-types.

To use this structure safely, Hoare proposed a conditional statement (a switch on the type field) that would allow the compiler to know which part of the union was in use within each branch, ensuring type safety. This is a powerful and often preferable alternative to inheritance-based polymorphism.

Simula 67 originally included this concept (an inspect statement), but it was lost when the language's concepts were translated into C++. The talk argues that we ended up with a less effective version of what Hoare had already described.

The True Origin: The Plex and Sketchpad (1960s)

The history goes back even further to the work of Douglas T. Ross at MIT's Servo Mechanisms Laboratory in the 1950s. Ross was working on early Computer-Aided Design (CAD) and manufacturing systems.

He invented the "plex," a sophisticated data structure that was a precursor to modern structs/records. A plex could contain:

  • Data members (e.g., coordinates)
  • Pointer members to link to other plexes (creating complex data graphs)
  • Flags (booleans to control behavior)
  • Function pointers (essentially virtual functions)

Ross's plex was a "fat struct" that could be processed by system routines. This idea directly influenced Ivan Sutherland, creator of the groundbreaking Sketchpad system (1963), often called the origin of interactive computer graphics and CAD.

Sutherland used a plex-like structure to represent drawings. The revolutionary insight was that constraints (e.g., "these lines are perpendicular") were implemented by system-level solvers that operated across the data components of multiple objects. The architecture was not built around encapsulating objects but around systems that could introspect and manipulate the entire data graph. This is the true forerunner of the ECS architecture.

Why the Mistake Persisted

Despite the existence of this powerful alternative, the compile-time hierarchy model prevailed. The talk suggests several reasons:

  • Natural Bias: Hierarchical classification is a natural human tendency (e.g., biological taxonomy). Mapping the domain model directly to code feels intuitive.
  • Championing and Implementation: Figures like Stroustrup and Alan Kay (Smalltalk) effectively championed and implemented the hierarchy/virtual function model into influential languages like C++ and Smalltalk.
  • Misidentification of the "Cool Part": Key figures like Alan Kay admired Sketchpad but attributed its power to its use of virtual function-like dispatch for display routines, rather than its system-level, omniscient constraint solver architecture. Their own backgrounds (e.g., Kay's in biology, Stroustrup's in distributed systems) predisposed them to favor models based on small, encapsulated, message-passing units rather than large, system-level processing.

The resulting "35-year mistake" was the promotion of an architectural model that simplifies the problem space rather than engaging with the hardest architectural challenges of complex software.

A Personal Illustration

The speaker illustrates the practical impact with a personal story from 1997. While building a metaball-based level editor, they encountered the limitations of the hierarchy model when trying to create a unified interaction system for multi-selected objects. The solution involved creating a parallel hierarchy of callback objects, which was complex and brittle.

Years later, they realized this was an accidental, poorly-implemented version of an ECS. The better solution was the same one Sutherland used in 1963: a system-centric architecture where properties are stored in systems and queried by entity ID.

Conclusion and Lessons

The talk concludes by arguing that the key to good software architecture is the intentional placement of encapsulation boundaries. The mistake was not OOP itself, but the procrustean application of a single, domain-model-bound hierarchy to all problems.

The powerful alternative, evident in Sketchpad and modern ECS, is to place boundaries around systems. This approach offers greater flexibility, performance, and is better suited for solving complex computational problems. The goal for developers should be to understand these architectural choices deeply rather than following a single, prescribed model.

© 2025 textlize.com. all rights reserved. terms of services privacy policy