Dialogue's Guiding Principles, or a Healthy Hatred of OOP article link

Dialogue is a framework for Lua5.2. It is an intersection of the Actor Model and an Entity Component System with a way to scope messages so that Actors may talk to one another.

The project was started because of a strong dislike for conventional object-oriented programming (OOP) principles. Objects just aren't supposed to be reaching into each other with 'getters' and 'setters' and messing with information. The concept of 'a message' has been morphed into 'a method'. Any principle about communication has been snuffed.

When learning about OOP for the first time, many get watered down snippets of Alan Kay, biological cells, and message passing and then move onto an "OOP language" such as Java or C++. When I started learning C++ I was shocked. Instead of using objects for compartmentalizing functionality, they were just used as a holding pen for loosely related functions. Instead of communicating between themselves, objects were operated on by some bigger parent object. I found it absurd and fought it for a long time.

Guiding Principles

Here are the principles of Dialogue and what I understood OOP to be before the culture-shock set in and I was forced to conform:

But these objects don't merely exist, they are written as part of a program. The unwritten principle wrung out of the above four is that objects are meant to work separately, yet together, unified by their messages.

Imagine modeling a baseball team using objects. Each object is a player which has a different position -- shortstop, catcher, pitcher, etc -- but they are unified to win despite being independent and having separate jobs.

A traditional OOP approach would have much of the functionality taken out of the player objects, using them simply to hold state. A traditional OOP approach uses shadowy architecture to remove the responsibility of an object, delegating that responsibility to some controller 'above' the objects (which is inevitably an object itself).

Here's a scenario using the baseball team: the batter hits the ball and runs toward first base but there is already a teammate on first base. Traditional OOP has some parent object, most likely named 'BaseballField', check the batter and the teammate on first-base for the conflict. It then calls run_to(2) on the teammate on first-base to resolve the conflict.

In Dialogue, the batter sends a running_to 1st message to every player in the game. The teammate on first will recognize the conflict and run to second. The opposing team's first-baseman might wait for a catch_ball message so it can score an out. And so on and so forth.

OOP, while using 'messages', has no inherent communication while Dialogue is pure communication. Traditional OOP is like moving chess pieces around on the board whereas Dialogue is like giving marching orders to a standing army.

I realized early that this communication can work, but doesn't scale well. A baseball game of 11 players (9 players plus the coaches) yields 11 messages for every interaction. This is probably fine, but when talking about a standing army we might be talking about 500 total soldiers.

I introduced scoping to alleviate the need for every object to know everything, reducing the amount of messages needed. This way objects can be compartmentalized in groups. The common military tree structure has an application in Dialogue -- with the root object (a general) sending commands, the objects near the bottom (foot soldiers) communicating amongst themselves, and the objects giving more specific commands (officers) in between.

These principles aren't hard-and-fast rules. There are parts of Dialogue which need to break these principles for reasons like behavior testing. But these are the foundations and guiding principles of Dialogue.

By The Hilt end mark logo