The phrase 'object-oriented' means a lot of things. Half are obvious, and the other half are mistakes. - Paul Graham.
Implementation inheritance causes the same intertwining and brittleness that have been observed when goto statements are overused. As a result, OO systems often suffer from complexity and lack of reuse. - John Ousterhout Scripting, IEEE Computer, March 1998.
The problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. - Joe Armstrong
The artiste's perspective:
Everything tends to make one think that there is little relation between an object and that which represents it. - René Magritte, surrealist
The conceptual purist perspective:
The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages. - Alan Kay
The pedagogical perspective:
CSCI 2100: Unlearning Object-Oriented Programming - Discover how to create and use variables that aren't inside of an object hierarchy. Learn about 'functions,' which are like methods but more generally useful. Prerequisite: Any course that used the term 'abstract base class.' - James Hague
I think the problem is more that OOP and FP teach that the solution is in the language constructs, when in fact the solution is in the developer.
OOP and FP are typically taught as outputs. You take a problem, you apply FP or OOP magic, and you get a solution squeezed into an FP or OOP shape. The implication is that the language somehow half-solves your problem just by being how it is, and all you have to do is apply it.
IMO this is the wrong way to do things. Developers should be taught abstract domain modelling skills in a language-independent way, then taught how solutions can be implemented in different paradigms. Then they can start coding.
The solution is in the design of the relationships, not in the language syntax. And there's no such thing as a off-the-shelf one-size-fits all set of relationships.
There are domains where it makes total sense to subclass polygon through rectangle to square, and domains where that's a very bad idea and will cause endless pain. So it's not enough to say "This thing is like this other thing, so they both belong on the same inheritance tree." Sometimes the resemblance is superficial and irrelevant in terms of the domain - even though to you as a human programmer the similarities are "obvious."
Neither OOP nor FP can help you if your ability to design minimal but powerful abstractions that fit specific problems is poor. OOP and FP will expose you to new ways of thinking about problems, but neither is general enough to "just work" or keep you out of trouble if you don't truly understand what you're trying to do.
I think the problem is more that Roman and Indo-Arabic numerals teach that the solution is in the notation, when in fact the solution is in the mathematician. . .
I’m confused about your analogy. Indo-Arabic number representation enables one to mentally carry out computations that would be much more complex in Roman notation. The notation might not be the solution, but the notation certainly enables solutions not really conceivable in other notations.
I believe functions + immutable data enable me to mentally figure out solutions to complex problems that would be much more complex if solved with objects and inheritence and mutable state.
The analogy breaks down (at least for me) as there are some trade-offs being glossed over that don’t really exist with the different systems of numerals. What’s being lost for the conceptual simplicity you’ve gained?
Perhaps that works in theory, but in practice abstract domain modelling only gets you so far. In the real world to build a working system that solves a real problem you typically have to work iteratively from both ends simultaneously until you eventually meet in the middle. Do some modelling, then write some code to validate your understanding and understand what's really going to work, then repeat ad nauseum.
The classes of bugs you get in an OOP heavy conceptual modelling inheritance tend to be far more difficult to reason about, because half of the damn classes using it end up being utility classes, so you end up modeling a computer that does a thing instead of the thing.
> I think the problem is more that OOP and FP teach that the solution is in the language constructs, when in fact the solution is in the developer.
I would say the solution is in the appropriate construct. Do whatever means writing the least amount of code possible. Less code means less to maintain and less to execute.
The No True Scotsman fallacy leads to arguments like this:
Person A: “No Scotsman ever steals.”
Person B: “I know of a Scotsman who stole.”
Person A: “No True Scotsman would ever steal.”
Person A is thus protected from the harmful effects of new information. New information is dangerous, as it might cause someone to change their mind. New information can be rendered safe simply by declaring it to be invalid. Person A believes all Scotsman are brave and honorable, and you can not convince them otherwise, for any counter-example you bring up is of some degraded Untrue Scotsman, which has no bearing on whatever they think of True Scotsman. And this is my experience whenever I argue against Object Oriented Programming (OOP): no matter what evidence I bring up for consideration, it is dismissed as irrelevant. If I complain that Java is verbose, I’m told that True OOP Programmers let the IDE take care of some of the boilerplate, or perhaps I am told that Scala is better. If I complain that Scala involves too much ceremony, I’m told that Ruby lacks ceremony. If I complain about the dangers of monkey-patching in Ruby, I’m told that True OOP Programmers know how to use the meta-programming to their advantage, and if I can’t do it then I am simply incompetent. I should use a language that is more pure, or a language that is more practical, I should use a language that has compile-time static data-type checking, or I should use a language that gives me the freedom of dynamic typing. If I complain about bugginess, I’m told that those specific bugs have been fixed in the new version, why haven’t I upgraded, or I’m told there is a common workaround, and I’m an idiot if I didn’t know about it. If I complain that the most popular framework is bloated, I’m told that no one uses that framework any more. No True OOP Programmer ever does whatever it is that I’m complaining about.
I think OO has so many fierce defenders, due to the simplicity of the concept, allowing even the mediocre to paint a system by the photograph of reality as it is imagined to be.
In this Object Orientated Fairy world even the Programmer has a place- he usually becomes the "Controller" Object - passing messages and half finnished objects between components.
Everyone can do this, everyone can relatively fast read into this. And this is why object orientation persists. It has no value beyond that.
Inheritance is one of those concepts, people went overboard with in the 90s, generating matroschka objects- that only the compiler could read and whos methods without a IDE where unguessable.
Since then- we put it into the history box, and replaced it with composition, which is inheritance in all but syntax and creation call hierarchy.
The attack on the holy mountain of OO is thus doomed to be unsuccesfull, because those who are besieged up there can not come down here- because they allready struggle with "normal" code and are happy to code down reality as seen by some "architect".
Efficiency or adequate abstraction, is not actually part of the discussion. Neither is speed.
What it provides is accessability- and that it provides rather well. Its a crutch for human minds- and a good one at that.
I don’t think those are No True Scotsman fallacies. Or at least not as you describe them. The problem appears to stem from using specific languages to argue about a broader concept. Java being verbose, Scala having too much ceremony and Ruby allowing monkey patching aren’t really complaints about OOP per se. Nor are issues of static or dynamic typing, bugs or bloat.
For example the discussion here hasn’t seen a lot of shying away from the practical and conceptual issues with inheritance.
The No True Scotsman fallacy is based on the arguments of a single interlocutor who is trying to evade the conclusion.
Your description sounds more like a series of different conversations with different people at different times starting from different topics. Since people, times and topics vary, yeah, you'll get different counterarguments.
Especially since, like all programming theories, the content, meaning and boundaries of OOP are widely disagreed on.
What are you trying to argue? Like what's the actual proposition that you're putting forward?
Those mostly sound like scattered, particular complaints about particular OO languages, none of which have anything to do with OOP as a paradigm (as far as I can tell).
If you're trying to suggest that there is no viable OOP programming language, that's manifestly false, as trillions of dollars of value have been created following the OOP paradigm in various OOP-oriented languages.
If you're trying to argue that there is no perfect OO language, I'd agree with you but argue that the it's a trivial consequence of there being no perfect programming language in general (language design is a game of trade-offs).
If you're trying to suggest that every use of OOP could be replaced by a clearly superior, readily available, battle-tested non-OOP approach (which you haven't, you've just listed languages and language flaws with no alternatives), the argument sounds pretty implausible.
You can weaken some of these claims to make some headway (replace always with in general or whatever), but that kind of takes the wind of out the argument's proverbial sails.
Personally I dislike OO approaches because I usually work on greenfield projects, and every example of OO in a greenfield context that I've seen has been deeply premature and slowed down development. (I also think the DRY principle is a pile of crap in a greenfield context with highish-level code). When I pull down a gigantic, mature Apache repo though, I'm usually not put off by mature OO abstractions, and they (in general) help me follow and add to the code. It cuts both ways. Like most ideas cooked up by smart people solving hard problems, OO is imperfect but sometimes useful.
> The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages. - Alan Kay
In other words it is about avoiding brittle hard-coded dependencies. When you "send a message" you can't depend on the implementation of the responding party. I think that's the general idea.
> The conceptual purist perspective:
>
> The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages. - Alan Kay
>
Given that Alan Kay is the one who came up with the term "object oriented", it might be wise to give him authority about the definition.
That would be next to impossible, since the term is overwhelmingly used by working programmers in the context of C++/Java/C#/etc. Also, I suspect that the only reason Kay's version is even brought up in every discussion of the term is some sort of programmer-hipster signaling thing. Not that Kay's OO isn't important - it is. It's just hardly ever relevant to the actual discussion.
I really dislike this kind of hand-wavy dismissal of ideas/opinions as “programmer-hipster”.
It seems to assume the person in question has no intelligent reason behind their thoughts/opinions. And it dismisses the opinion instead of engaging with it intellectually.
And having been on the receiving end, it’s insulting. It feels like being called stupid.
It’s fine to disagree with opinions, but when you assume people are “signaling”, you’re assuming the worst about people before seeking to understand them.
I get what you're saying, but I'm still persuaded this is what happens with Kay and/or smalltalk. 100 times I've seen threads about OO. 99 times someone brought up Kay/smalltalk. Zero times did they specify why the messaging model was relevant to the present discussion. That's important to do, because more OO programmers use C++/C#/Java, and are not smalltalk experts. So, it seemed to me that they were namedropping. Which opinion should I have engaged with?
Duck typing is central to the Smalltalk "vision thing". That and the idea that a message is a symbolic representation of a method, which an object may or may not support. It is not, in fact, the method, nor does it stand for a direct call to the method. In C++ and Java, for a call to a.foo(12) the compiler can look up the class of a, determine whether it has a foo implementation, and if so compile a call directly with the number 12. In Smalltalk, a foo: 12 has no such implications. Rather the runtime will look up whether a's class has a foo: method at call time and if so, invoke that method; otherwise invoke the object's doesNotUnderstand: method with the message and arguments as parameters. There's an added layer of indirection there. It's rather like a single-threaded Actor model. Kay was trying to get people to think in terms of encapsulated objects that communicate in (often ad hoc!) ways, not in terms of inheritance trees or type hierarchies.
Is it better? Is it worse? I don't know. We know Smalltalk is slower, but it (along with Objective-C) admits designs unfathomable in C++. For example, all objects that understand a given protocol (set of methods) and implement it in a sensible way are substitutable with each other (with respect to the protocol) irrespective of their place on the inheritance hierarchy (or even whether such protocol was formally defined). This is NOT true with C++, absent template metaprogramming, and it's not true with Java unless you define an interface and assert that all classes which understand those methods implement that interface.
Furthermore, by overriding doesNotUnderstand:, you can specify a behavior for classes when sent a message they don't have a method for, besides raising an error. Maybe you want them to forward the method to one or more delegate objects, or log the invocation.
It's super-flexible, powerful, and neat in a similar dynamic-language way to how Lisp is neat. That's why Smalltalk attracts so many fervent converts. As I said, it can be better or worse depending on your perspective. Some people like working with type hierarchies; Haskell, Rust, and even C++ attract fervent converts too!
> ... all objects that understand a given protocol (set of methods) and implement it in a sensible way are substitutable with each other (with respect to the protocol) irrespective of their place on the inheritance hierarchy (or even whether such protocol was formally defined)....
This is a very interesting property, and you'll also see it in statically-typed languages which support row polymorphism, like OCaml. OCaml directly supports OOP and subclassing, but it also supports structural typing, which means that objects are type-compatible if they support the same methods.
Unlike Smalltalk, this is all resolved at compile time, so it's quite efficient.
Introducing template metaprogramming comes with its own passel of problems: compile times (and code size) can explode, and then there are the difficult-to-debug error messages if you screw up. Because Smalltalk uses latent types, these decisions are deferred till run time, which is a loss for static analysis, but doesn't require a separate generated bit of code for every combination of arbitrary types used in the program, and it can be debugged on the spot without recompiling much more than a single method.
> Introducing template metaprogramming comes with its own passel of problems: compile times (and code size) can explode, and then there are the difficult-to-debug error messages if you screw up
I don't know any even remotely large recent C++ project that does not use templates at some point. Templates are central to C++ since Alexandrescu's book and the main point around which the current language revolves.
Template meta-programming is a different usage from template generics. It has a higher compile time cost because it performs computations as a side-effect of compilation.
Which is what the commenter above was trying to say, templates are completely normal, vanilla C++. Also, I cannot think of any codebase that is actively under development and doesn't use some template magic, like at least tuples or variadic perfect forwarding etc... If you look at old codebases you can find them, but template metaprogramming is still very common, mainstream C++.
That makes sense. Sounds like the kind of comments you tend to see are out of context and don’t engage with the subject matter. I can see how that comes across as signaling.
The concept of smalltalk are implemented to some degree in many dynamic languages like Ruby, Python, Perl, Elixir, etc.
And if we are going to talk about functional programming, we can't exclude languages like Python for having too small a user base, as their popularity and impact is often wider than that of any static functional language.
> It seems to assume the person in question has no intelligent reason behind their thoughts/opinions.
If they had, they wouldn't systematically resort to baseless appeals to authority, whose only purpose is to intentionally avoid having to present any semblant of an intelligent reason.
> If they had, they wouldn't systematically resort to baseless appeals to authority, whose only purpose is to intentionally avoid having to present any semblant of an intelligent reason.
This is pretty much what I was talking about. It assumes the worst about someone before hearing them out.
It’s a pretty unreasonable assumption to count every reference to Alan Kay’s quote about OOP as a “baseless appeal to authority”.
Perhaps the person has given a lot of deep thought about the matter, and have reached some reasonable conclusions. If you dismiss the person, you’re just cheating yourself of an opportunity to learn and engage in intelligent conversation. And blindly insulting the person.
Definitions arise in real world use, independently of who might have first invented a concept or coined the term.
In the end, only how a term is used by the majority of people matters -- because only that retains the basic requirement of language: to say something and have it be understood.
Sure, misunderstanding happen, true. But at a certain point it becomes just another excuse.
And that's not to get into the "SOLID" definitions which are more a feel-good word for handwave and murky definitions typical of the "True Scotsman" fallacy
How does dropping a bunch of out of context quotes contribite to a discussion? Why was this voted to the top? Clearly I should just skip the first comment tree entirely when reading comments on pieces about "programming paradigms."
The phrase 'object-oriented' means a lot of things. Half are obvious, and the other half are mistakes. - Paul Graham.
Implementation inheritance causes the same intertwining and brittleness that have been observed when goto statements are overused. As a result, OO systems often suffer from complexity and lack of reuse. - John Ousterhout Scripting, IEEE Computer, March 1998.
The problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. - Joe Armstrong
The artiste's perspective:
Everything tends to make one think that there is little relation between an object and that which represents it. - René Magritte, surrealist
The conceptual purist perspective:
The notion of object oriented programming is completely misunderstood. It's not about objects and classes, it's all about messages. - Alan Kay
The pedagogical perspective:
CSCI 2100: Unlearning Object-Oriented Programming - Discover how to create and use variables that aren't inside of an object hierarchy. Learn about 'functions,' which are like methods but more generally useful. Prerequisite: Any course that used the term 'abstract base class.' - James Hague
Quotes via http://github.com/globalcitizen/taoup