Wouldn't the main definition of OOP be defined as merging data and functions into a single unit? When using libraries, I find this concept unavoidable for UI and games.
I agree though, that having the entire program be a graph of objects is actually usually the worst pattern.
> I agree though, that having the entire program be a graph of objects is actually usually the worst pattern.
This is what I was primarily thinking about, and this is what is most written about in OOP books. OOP is a big bag that wraps itself around a lot of things, and which appropriated quite a lot of concepts. The concept of gluing together a bunch of data and code in order to treat them as a single entity is indeed useful (at least for imperative code), and while it is the foundation of OOP, I don't think it's really the distinguishing thing about various OOP approaches. For the class-based OOP, it's the composition of data+behaviour, encapsulation, polymorphism and inheritance that together create a particular philosophy - one that I find much less useful than advertised.
The building blocks are no doubt useful - a proper type system is great, but you don't need classes and objects for that. So is polymorphism, and again, you don't need Java-style classes to get method dispatch (see e.g. Common Lisp multimethods for an arguably better way of doing this, and one that doesn't even treat methods as parts of classes!).
I'll concede that OOP approach fits UI libraries unusually well (though you can hit some conceptual roadblocks there too; I'm not sure I've ever seen a good OOP design of tables, nor do I know how to design it well). But then again, I was recently writing some React code in ClojureScript, and it turns out that functions and plain data can handle building stateful UI components well too.
What I mean by saying that OOP appropriated things - I've seen people thinking, and even myself I used to think, that "abstraction" is something that a class creates, and is what you achieve with OOP. I gradually grew out of that belief, and I vividly remembering that reading SICP made it finally click in my head that quite a lot - if not most - of the software engineering practices discussed and attributed to OOP are in fact more general concepts applicable regardless of your programming paradigm.
> Not really. In fact in Lisp OO is the opposite, the functions are explicitly keeped away from the data.
Common Lisp really opened my eyes here. Initially it felt weird to have methods[0] living completely independently from classes, but over time I realized that where classes and objects implement nouns, generic functions and methods represent verbs, and in a language the verbs are an independent domain from nouns, representing their own generalized concepts that's unrelated to the taxonomy of nouns.
--
[0] - A "method" in CLOS is an individual implementation of a "generic function". So e.g. you could have a generic function `(defgeneric draw (device figure))`, and then specific implementations dispatching on any combination of arguments; e.g. `(defmethod draw ((device printer) figure)` to draw any kind of figure on a specific device, or `(defmethod draw (device plotter) (figure circle))` to draw a specific thing on a specific device, etc.
Yes. Note that `this` is just syntactic sugar; a call to `obj.method(arg)` is, underneath, essentially a call to `method(obj, arg)`, with the first argument always being hidden, and the only one that's a subject of a method dispatch (polymorphism).
Common Lisp gets rid of implicit `this` by making all arguments explicit, and by not restricting polymorphism to the first parameter - in fact, you can do a method dispatch on any of the method parameters, or any combination of them. See https://news.ycombinator.com/item?id=18848384 for an example.
I agree though, that having the entire program be a graph of objects is actually usually the worst pattern.