| This article is remarkably low on arguments, despite being so long. Just a few of its gems: > OOP is wrong because of its definition of an “object”, and its attempt of trying to fit everything into it. When that goes to the extreme, you arrive at the notion “everything is an object“. But this notion is wrong, because:
> There exists things that are not objects. Functions are not objects. This has two problems: 1. It's factually wrong. Smalltalk functions are first-class objects. 2. It fails to explain why that would be wrong (assuming it were, you know, true). The author does give the (poor) examples of Python and Scala, which -- in his opinion -- incorrectly call a function an object, because only the __call__ and apply are the "function objects" one is trying to define, but they were "kidnapped" and jailed into their wrapping objects. IMO, this is ontologically incorrect. The same can be said of any object's definition: if I have an object called PlaneVector, the "vector object" itself would actually be only its x and y properties, which I have kidnapped and jailed into my object. The fact that this structure (the object I'm defining in my programming language) is not the same as its counterpart in the world of ideas (i.e. the plane vector in maths) should be fairly obvious, despite using the same generic term (i.e. object) to denote both. Behold, then, the straw man: > Most OO languages also lack correct implementations of first-class functions. An extreme is Java, which doesn’t allow functions to be passed as data at all. You can always wrap functions into objects and call them “methods”, but as I said, that’s kidnapping. The lack of first-class functions is the major reason why there are so many “design patterns” in Java. Once you have first-class functions, you will need almost none of the design patterns. There are a lot of things wrong with Java, of course, which does not mean that they are also issue of object-oriented programming. Inheritance (sorry...) doesn't work both ways: the fact that a Lexus is prohibitively expensive doesn't mean moving vehicles are prohibitively expensive. I have less of a problem with the author's treatment of functional programming. What he's essentially trying to argue is that: > Simulating them [side effects] with pure functions is doomed to be inefficient, complicated and even ugly. Have you noticed how easy it is to implement circular data structures or random number generators in C? The same is not true for Haskell. IMO, this is true, but the isolation of side effects doesn't have to happen only by the ugly means he outlines next (i.e. monads) in every application. A typical CRUD application the web kids like to write can be written so that the only side effects involved are in fact modifications of the database, in which case the side effects are confined to SQL. I also think there's an ontological error in this argument. Its foundation is that FP tries to "ignore" side effects even though they are real, but the examples the author gives are several layers of abstraction below. C also woefully ignores some of the side effects in the silicon (e.g. if you go low enough, calling a function with no side effects that does not even alter the state of the program will, in fact, alter the state of the underlying silicon, and quite substantially so), and I think it's reasonable to assume that we can't quite move the debate into which of those should be ignored or not. All languages abstract the silicon away, and it's not only good that they do, it's what they were built for. I honestly don't miss hardwiring relays. |
But isn't the main point of the article that OOP just doesn't always fit the problem domain, that sometimes you want to model something in a way where forcing it into objects (nouns and verbs) only adds complexity without benefits?
I don't think the article condemns OOP in any way except when it becomes a religious dogma that everything needs to be an object, as it is in Java. I've written many different types of programs in various languages, and I can only agree that sometimes, OOP simply isn't what you are looking for. Think about streaming data processing for example, or something reactive like a network service. Surely some parts of the outside interface or the 'glue' between the outside interface and the actual number crunching or request processing can be modeled using OOP, but at the core, there's all kinds of processing on blocks of data or asynchronous IO going on that doesn't need objects and methods, and doesn't add to code clarity or stability in anyway (on the contrary even).
The article basically perfectly describes why I very much prefer programming in Python or C++/Objective-C over Java: they allow me to mix and match different programming paradigms for different problems.