I like people that heartily dislike a programing language paradigm. First, this means they think about how programming is done, rather than about programs only. Second, as far as hate go, hating a paradigm is much better than, say, hating people for being born with the wrong skin color, faith or sexual preference. You can trust me on this one – I’m from the middle east.
But if one is to hate a programing language paradigm, one should do it in an informed way. Case in point: @Loup’s recent post, “the repeated deaths of OOP” (@Greptilian sent me a link to this post not long ago, which was quite nice of him). While this post has some interesting ideas, presented with an envy-inducing eloquence, I’d like to constructively disagree on a few issues. Before I do, let me stress that some of the mistakes in the post are very common, which might have misinformed the fact-checking stage of it. This is the reason I write a post of my own, rather than just an internal answer email. And thanks @Greptilian for suggesting that I write one. Quite nice of you.
OK. Let’s start. (Or, to quote Pascal language,
The post begins by stating that “Current mainstream programming languages all support OOP — except maybe C, and it is no longer that mainstream”. There’s some echo chamber effect in the PL blogosphere, and we should be aware of it. C is very mainstream. It’s currently #2 in the TIOBE index. It has more than double the rating of language #3 – C++. It is true, however, that it is not mainstream while writing web applications. I guess it’s just harder to blog when you have a daytime job (note to self: revisit this statement once I get a daytime job).
The post continues by stating that the it is unclear what “OOP” means, and then describes the eight “fundamental building blocks”, constructed from a survey done by Deborah J. Armstrong. That’s a classic straw-man argument. Why would a survey of a population that can’t agree on anything end up in a definition coherent enough to base a very successful programming paradigm on?
When I learned OOP – Based on Timothy Budd’s “An Introduction to Object Oriented Programming” (current edition), we were presented with four blocks that make sense, instead of eight that don’t. It was argued that an object is a 4-tuple:
- structure – what the object looks like in memory
- state – the values the object currently holds
- protocol – the set of messages a given object can “understand”
- behavior – what said object does when it gets a message from its protocol
Note the lack of classes and inheritance, which are a way of code reuse within an object oriented context. Abstraction, encapsulation and polymorphism naturally flow from these four principles. Budd’s book is pretty popular and I assume I’m not the only one that remembers his presentation on the subject (and the cute Platypus on the cover). At any event, when looking for a definition, it’s better to go to the books rather than the allegedly confused public. I mean, imagine how monads would look if we applied this approach to them (here’s Gilad Bracha on this subject).
“Then Java came. It was presented as an “easier C++”. Same syntax, similar abstractions, garbage collection… At that point Smalltalk was hardly used any more, and “OOP” basically meant Java and C++.”
One does not simply conflate C++’s version of OOP – multiple inheritance, supermarket principle, no GC – with Java’s. Java has a direct influence from SmallTalk and Objective-C, and the original staff hated C++. And played hockey with Scott McNealy. Here’s Patrick Naughton, a member of the original team that worked on Java (“Oak”, at the time):
… I thought Objective-C was the coolest thing since sliced bread, and I hated C++.
So, naturally when I stayed to start the (eventually) Java project, Obj-C
had a big influence. James Gosling, being much older than I was, he had
lots of experience with SmallTalk and Simula68, which we also borrowed
It is important to stress that the garbage collection is key in an object-oriented language, rather than a utility that makes life easier. With no garbage collector, any object creation has to be matched with precisely one object destruction (and of the same object as well). This means objects are not “first class citizens” in the language – the programmer cannot create anonymous ones. Java has to have garbage collection, because of the exact same reasons LISP has to have it when it allows programmers to create anonymous functions.
C++, on the other hand, is governed by the “supermarket principle” – the language accommodates many programming styles (including OOP, modular, procedural, and to some extent, functional. See Bjarne Stroustrup’s introduction to “The C++ Programming Language“), but you only pay for what you use. Garbage collection runs against this principle, as it has a heavy price tag.
Onward, to the second death.
“suddenly we hardly needed Object any more.”
Dude, you realize where
equals() and come from, right?
Onward – I’m skipping the “third death”, as I disagree that the grim reaper operates on a programming paradigm by adding more languages that support it.
“Lambdas are everywhere…”
A lambda is an object with a single method. Since it’s a single method, it does not need to have a name. When the need to name it rises, it is commonly called “apply”. In fact, OOP is a generalization of FP – FP only allows objects with a single method; OOP allows many methods. FP objects – “lambdas” or, more accurately, “closures” – can even have state: captured values from the internal calculations that created said closure. That state may even be mutable, e.g when it contains box values. So, yay FP, but FP and OOP are not mutually exclusive. You can do both. At the same time. In the same language. We’ll get to that.
Yet from a popular perspective, first class functions are not OO at all: they come from functional programming. Yet they managed to invade every single mainstream OOP language.
They didn’t invade. They where there at the beginning. SmallTalk had them. And again, FP was one of the two main influences on SmallTalk. Here’s Alan Kay, reflecting on his work (from ACM Queue)
We had two ideas, really. One of them we got from *Lisp*: late binding. The other one was the idea of objects.
By the way – this is a really good read. Long – but good.
“There is an easier way: don’t mutate state. Always construct new stuff, never throw away anything. Then let your smart pointers or your garbage collector take care of unreachable references.”
And I assume the garbage collector does everything in O(1), and was sent by to us from the heavens? More to the point – I think we can turn the hubris knob down ever so slightly, and construct the following argument from the above quote (at the risk of being accused of constructing a straw man myself):
“Application programming can be done with no mutable state. Code that mutates state is inherently low-level, and can be left to system programmers, the same way we treat assembly code today”
Now that’s a statement I see the merit of. I don’t agree, though – garbage collection has a real cost, and sometimes it does make sense to minimize it. There are programming models that accommodate mutability, while being safe and simple even in concurrent contexts. The actor model is probably the most popular, but there are others (shameless plug – my ongoing PhD thesis works with behavioral programming, developed by Harel, Marron and Weiss, which also offers that, in its very experimental way).
I agree that Entity-component-systems (ECS) is an interesting approach. Also, indeed, relational databases and OOP don’t mesh well, once OOP starts to use stateful inheritance. I guess this impedance contributes to the growing popularity of NoSQL databases (should ECS support that?).
Functional Reactive Programming is very interesting too. But do note that, at least in the web context (Elm, React) it is used to change the DOM, which is one of the poster boys of OOP (inheritance, composite design pattern, the works). This may actually be a good case for the aforementioned statement, where higher level programming is done in FP, while the underlying layer is done in OOP.
So is OOP not dead yet?
Oh, and regarding the game industry leaving OOP – I have no idea if the game industry is indeed leaving OOP. Some hard numbers are in order. But even if that’s true, and even if we accept that “games are simulations” – they are simulations that have to be done fast enough to be rendered, smoke, explosions, blood, gore, background music and all. In real time. And at least partially on GPUs, rather than CPUs. I’m not sure how strong a classifier the game industry is, given these traits. But hey, interesting development nonetheless (if true. Braaaaains! I mean, Nuuuuuuuumbers!).