I’m thrilled to have my Twitter friend Paul Burt contribute his thoughts on the cousin of OOP — OOO.
“Ugh, prototype might’ve been right,” I thought, crowded shoulder to shoulder at a party, in an apartment already bursting at its seams.
“Oh, you’re a programmer right? What do you think about Object Oriented Ontology (OOO).” A quizzical look on my face prompted more explanation. “My wife is an architect and she says it’s a big idea for them, and in the arts. You know, it’s just really cool Category Theory.”
A book recommendation and purchase later and now here we are. I’m convinced OOO is an idea that we should all have in our pocket. Why should you care about OOO? Because, as technologists it’s a theory that contends with complexity, state change, and a whole lot of other things that we wrestle with daily.
Different objects and objectives
Object Oriented Programming (OOP) and OOO are similar in name, but as the author of my recommended read (Graham Harman) is careful to note, the name is about it when it comes to what one borrows from the other. Object Oriented Ontology is true to its philosophical roots, and strives to be a theory of everything.
So, how does that help us in the world of programming? “I think, therefore I am,” is a classic bit of Ontology, but it won’t help us construct more elegant classes, or draw cleaner boundaries between our apps. What OOO does deliver is a clear language for communicating complexity and change.
As developers we regularly discuss the importance of composition, and loose coupling. We agonize over how to manage state and the importance of events, and transactions. OOO is useful to us, because it connects all of the disparate bits of wisdom floating around in our profession.
Concretely, OOO is valuable anytime we need to discuss complexity or change. OOO can help explain why seemingly simple changes to pixels on a page are occasionally more complicated than they seem. It explains why some of us are excited about new tech like Serverless, and others find it exhausting. It explains why some devs think we ought to know the intricate details of the Node.js runtime, and why they’re only sometimes right.
Importantly, its ideas are approachable and general enough that even the folks working on the non-code side of tech ought to be able to get it. That universality, I believe, is why it’s valuable.
No, you’re an Ontology
What’s ontology? You might be familiar with the classic example of Plato’s Cave. A prisoner in a cave is only able to see objects cast shadows on the cave wall as they pass. As the allegory goes, the same way a shadow is an incomplete representation of an object, so too are our observations incomplete representations of objects. Plato encourages us to see the “real” objects, and not be fooled by the shadow. Hella deep, Plato.
To OOO, there’s no need to discriminate. Shadows are more than just false or misleading things. Every shadow, and really every representation is as important as the abstract ideal they’re stamped from. Hence my, “Oh, prototypes,” thought at the start of this article. This might be blasphemy to Plato, hardcore JS devs, and many other classical thinkers, but that distinction is why OOO winds up being so handy to us when we turn to the world of software.
You might have a fuzzy sense of what OOO, monadic functions, and ontology are at this point. The bad news is, almost everyone who understands monads seems to be completely incapable of explaining them clearly. So, that’s just kind of a line you’re gonna have to cross yourself. For OOO on the other hand, we could write an entire book on the subject. And, hey! There’s even a great book already written by Dr. Harman that you should check out.
One of my goals while writing this, however, is not to assign 100 pages of homework. I think OOO can be summed up as an inclusive theory. Combine two objects? Decent chance new and interesting qualities appear that makes it worthy of its own object-hood. What about abstract stuff like art, lies, and politics? Shadowy as they are, still totally all objects. In short, OOO is about composition in the same way React and other modern UI libraries are.
When you combine two objects, there’s a chance new and interesting qualities appear. OOO is about realizing how much more common this emergence is, than we’d like to think.
Dr. Harman notes early on in the book that there are four pitfalls that competing philosophies tend to fall into. These four pitfalls are physicalism, anti-fictionalism, smallism, and literalism. Figuring out what the heck OOO really is might take a bit more reading, but since my goal isn’t to force feed you everything in a single article, these four seem like a great subset for us to focus on.
Physicalism & Anti-fictionalism
Everything that exists must be physical. Everything that exists must be real.
Developing a theory of everything is an enormous task. In order to simplify the task, it’s common to narrow the focus to a specific area. “I think, therefore I am” focuses on what we can experience, Plato’s Cave focuses on representations of physical objects, and so it goes for a lot of the classic approaches.
We do this sort of narrowing and focusing all the time as developers. No where is it more relevant than the world of UI frameworks. Every framework has a scope, and that results in an often not-so-clear set of tradeoffs. That’s why it’s refreshing when projects like Vue.js clearly lay it out.
Most projects make these tradeoffs even if they rarely ever clearly state it. Take, for instance, NoSQL databases. The MEAN stack is (or was) a common trend, and the marketing for them focused on how easy they are to get up and running. No need to specify schemas! That’s great and all, but as our databases grew we quickly discovered that schemas still exist, now they’re just specified implicitly by every connected app. Most of us learned that keeping a database tidy is much simpler than doing the same for each app.
When we develop our own solutions, it’s essential that we are clear about when we’re narrowing and focusing scope. Not to turn this into a PSA about how the abused often become abusers, but translating customer feedback or business requirements into code shouldn’t be a dark art. We should be clear with our stakeholders about our perceived requirements, and what we need to intentionally forego in order to make things work.
The same way “everything” is a term that needs a little more definition when talking about ontology, establishing clear requirements and scope usually results in some silly sounding inquiries about what otherwise perfectly clear words actually mean.
As an example, a few years ago I had to rebuild and reorganize the documentation site for a product I worked on. I organized meetings with various stakeholders and gathered requirements. One particularly frustrating meeting was with a VP who was adamant that I need to, “make it enterprise.” Sure, initially I looked like a little foolish asking what the hell enterprise means, but it’s better I do that than exit the meeting with only vague notions and gut feelings. Had I known about OOO then, I’d have felt much better knowing I’m not the only schlub who needs to ask these kinds of questions.
Similarly, as devs we need to demand clarity when we stumble upon new projects that describe themselves as blazing fast, real time, or any other smorgasbord of adjectives. What is the project’s focus? Is there a particular context it’s designed for? This has to be communicated for any of those adjectives to mean anything. We should be skeptical of unqualified descriptors.
Everything that exists must be basic and simple.
There’s a tendency to overvalue simplicity. It’s something that’s easy to feel when a coworker calls your favorite editor bloated, and suggests you give ACME a try instead. To be fair, there’s a good bit of wisdom in striving to stay small (eg the Unix Philosophy). After installing ACME and suffering its monk-like asceticism for a few days, you’ll likely reach for your old editor. We love the bloat. We need the bloat. What’s up with that?
First the wisdom: Yes, small component programs are nice, because they encourage composition and reuse. It’s clear that they also suck, because straightforward tasks require inordinate amounts of piping and gluing. Want to create a GIF? Your first instinct is probably to reach for a tool like ImageMagick. Oh, don’t want to cobble together pipes and feed a line into FFMPEG? I can’t blame you.
In theory, there is no difference between theory and practice. But, in practice, there is. — Jan L. A. van de Snepscheut
What smallism gets wrong is emergence. In pop wisdom, we usually substitute the emergence with phrasing like, “it’s more than the sum of its parts.” As programmers, noticing something is more than the sum of its parts often indicates an increase in complexity. That’s complexity we’d rather avoid. You know, loosely couple your microservices and all that.
As programmers we also know that some complexity is unavoidable. Fred Brooks won a Turing award for telling us as much in his paper No Silver Bullet. No matter how hard we try, some of our code will always be necessarily and unavoidably complex.
Take for instance, CAP theorem. Almost everyone working in the cloud has to deal with CAP tradeoffs. As much as we’d like to pretend we can simply avoid catastrophe, CAP theorem says we must decide between consistency (the C) and availability (the A) when things eventually do go bad. CAP theorem’s author has said that part of the reason he thought he needed to spell out CAP theorem was the effort so many of us wasted trying to contort ourselves around this constraint.
“In fact, the original point of the CAP theorem was to get designers to take this tradeoff seriously.” — Eric Brewer
The tendency for smallism also leads to design decisions like Unix’s maxim: everything is a file. That legacy lives on in our
/dev (device) and
/proc (process) directories today. You can view the processes running on your system by looking at files! Ok, cool, but how often do any of us reach for that over
ps? Emergence can bring ugly complexities, but sometimes it brings a vastly improved experience, too.
The positive parts of emergence are important to keep in mind when exploring new ideas. Serverless? That’s just bash scripts and process isolation. Containers? They’re just Linux syscalls. The “That’s just” song is one we all sing any time we think we’ve spotted the seams on anything claiming to be new.
The positives of emergence are also why wasm (ie web assembly) might be worthy of all of the early hype. There’re an enormous number of ways wasm might be combined with modern tech. Emergence makes it difficult to predict which combination is going to lead to the new webdev paradise. We’ll just have to try various compositions, and see.
One of my favorite ideas is that the most valuable book on my shelf is the one I haven’t read yet. Why? I’ve already integrated and applied the knowledge from books I’ve read. I am the product of that learning. It’s the unread books that contain new ideas, and it’s there that I’ll find something that changes how I view the world.
Similarly, when I think about smallism and emergence, it changes how I view new technology. If I’m hoping to grow as a developer, it’s less likely I’ll find that growth building my 57th React app. It’s far more likely I find growth by trying Angular, or any other framework I’ve yet to explore.
Everything that exists must be able to be stated accurately in literal propositional language.
Software is more than just code.
If you need convincing, look to Conway’s law. It says that the software reflects the communication structures of the organization building it. This isn’t just a bogeyman managers roll out when it’s time for a reorg. The evidence suggests it’s a real effect. The classic example that’s used for illustration is if you assign four teams to build a compiler, you’ll get a four pass compiler.
It’s more than just code, because software is a reflection of the people who make it. Software is also documentation. Try working on a project without it. Software is ideology, and ethical decisions, and a whole lot more. Which is why it’s sad when we become dismissive of discussions about community health, codes of conduct, and etc.
There’re a whole boatload of non-code related things that get dragged along for the ride. It’s silly for philosophers to believe they can perfectly describe every object in the universe. So too, is it silly for us to believe that everything important about software can be described as code.
I do recommend you give the OOO book a read. That said, the concepts aren’t at all unique. On a recent jaunt through Youtube I was pleased to find that Dr. Robert Sapolsky explores all of these ideas in his Stanford course on Human Behavioral Biology. Complexity and change are problems everywhere, it seems.
I find the ubiquity of all of this comforting. Consider snap judgements like: This project should be simple, why is it taking so long? Ew, you actually enjoy writing JS? These used to sting when I didn’t have anyway to reply other than some version of, “You don’t understand.”
Now, if I think there’s a chance they might understand, I have ways to communicate. I can talk about emergence, overvaluing the small, or how we might’ve picked too narrow a scope to accomplish our goal. If they’re stubborn, I have self-confidence.
In other areas, I find some of the fatigue of learning new technology has been replaced by excitement again. “Why would you do that?” has turned into, “Cool, I wonder what’s new?”