One problem is that every OOP advocate has a different perspective on "what the entire point of OOP is". Another problem is that irrespective of what any OOP advocate believes is OOP, the body of code that is commonly understood to be "OOP" is plagued with abuses of inheritance (I'm not even convinced there are legitimate uses), mutable state, the "banana with a reference to the gorilla holding it with a reference to the entire jungle" problem. OOP advocates are quick to say "that's not real OOP" in a very no-true-scotsman fashion, but that aspirational statement isn't comforting to people who have to deal with these problems day-in-and-day-out.
> Also treating code as data isn't a feature of OO, it's an old idea starting with Lisp I suppose and it's present in functional languages as well.
The parent specified that their objection was about tightly binding data to code, not about treating data as code.
The problem with lookibg at bad X code and concluding X is bad is that X can be anything.
It's true that bad OO code suffers of different problems than bad FP code, and both are different from bad procedural code. But there is no guarantee that an organization which produced bad OO code would have produced good FP code, just as there was never a reason to imagine (though many did) that an organization that produced bad procedural code would produce good OO code if forced to switch to OO.
In general, there is no solver bullet. We can absolutely replace the problems specific to bad OO code with problems specific to bad FP code if we move from OO to FP, but we cant be sure of any other outcome.
More likely than not, we need to change more than the style of code we build if we want to take an org that has produced bad code and make it produce good code - we should change incentives, testing, goals, timelines etc.
And just to be clear, you're absolutely right that saying 'that's not good OO code' is no-true-Scotsman and not helpful in any way, other than pointing out that it is possible to produce good OO code (some people doubt that, I think).
> The problem with lookibg at bad X code and concluding X is bad is that X can be anything.
The difference is that FP, procedural, data oriented, etc are all pretty reasonably defined. No one seems to agree with what OOP is, and any objection to the kind of code that is typically considered "OOP" is that "that's not real/good/etc OOP code". It's a no true Scotsman.
When I talk with OOP proponents and point to issues about inheritance or the gorilla/banana/jungle problems, they say that these things aren't part of OOP. I think when you deduct from OOP these kinds of warts, you end up with something that looks almost indistinguishable from data oriented programming (something like what you would write in Go or Rust) and increasingly something that resembles functional programming specifically now that many OOP languages have support for first class functions and more functional abstractions in their standard libraries.
So if there is any truth in the "not true OOP" argument, I think it's that "good object oriented programming" is just another spelling of "data oriented programming".
I think that there are two groups that try to claim OOP.
One is the Alan Kay camp, which usually defines OOP as primarily message passing, with Smalltalk as a beacon of what they consider good code. This is a very vocal group, but I think that it is extremely obscure in the industry.
The other group is mostly focused on SOLID and design patterns. I would say that Java's Swing is a good example of a usable library based on this style of code, inheritance-heavy but still principled.
I believe that this style of code is most reliant on garbage collection to actually be reasonable. Otherwise, you end up caring about ownership for every little object and it rapidly becomes a nightmare. I believe your banana/gorilla/jungle problem is related to this mostly.
For myself, I do believe that implementation inheritance is usually to be avoided, but I think that other OOP concepts, such as encapsulation and interface-style extensibility, using constructors to establish invariants, are frequently useful, especially in the high-level architecture of a program or module. I do prefer some kind of support for sum types and multiple dispatch, rather than traditional virtual dispatch.
One problem is that every OOP advocate has a different perspective on "what the entire point of OOP is". Another problem is that irrespective of what any OOP advocate believes is OOP, the body of code that is commonly understood to be "OOP" is plagued with abuses of inheritance (I'm not even convinced there are legitimate uses), mutable state, the "banana with a reference to the gorilla holding it with a reference to the entire jungle" problem. OOP advocates are quick to say "that's not real OOP" in a very no-true-scotsman fashion, but that aspirational statement isn't comforting to people who have to deal with these problems day-in-and-day-out.
> Also treating code as data isn't a feature of OO, it's an old idea starting with Lisp I suppose and it's present in functional languages as well.
The parent specified that their objection was about tightly binding data to code, not about treating data as code.