Live data from Hacker News

The Case Against OOP Is Wildly Overstated

medium.com

201–210 of 312 posts

Re: The Case Against OOP Is Wildly Overstated

#201

Earlier quoted context omitted.

I think the key differentiater is that OOP (in some versions) wants to hide the data and not just implementation details. For example, a hash map data structure hides the details of how the hash map is implemented, but it doesn't hide the data. In some versions of OO, the object should not only hide the implementation details but also the data. Any function that needs that data MUST be a method of that object. That's…

In what versions of OO does a hash map hide the data? The definition of a map requires that you can access the data.

Almost all hashmaps hide the internal references/pointers to the backing arrays. That's implementation state just like any other internal data. It's just so mundane, well executed and common that you forget it exists.

Re: The Case Against OOP Is Wildly Overstated

#202
post #163

Earlier quoted context omitted.

For what it’s worth, with ADTs and non-exposed constructors you can achieve the same result (i.e. only the creating module can actually _build_ such a list but other modules can read the data).

"Abstract data types and non-exposed constructors" is enough to give you object-based code, which is not too far from a definition of "the good parts" of OOP. Though some could quibble that "object-based" doesn't include sensible ideas such as composition, interface inheritance, delegation etc.

Classes can be used as modules, as namespaces, as datatypes, for encapsulation, etc. The problem is they're not particularly great at those things, and those concerns often become conflated.

Re: The Case Against OOP Is Wildly Overstated

#203

Earlier quoted context omitted.

> The entire point of OOP is ... 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 goril…

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 b…

> 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".

Re: The Case Against OOP Is Wildly Overstated

#204

The problem I've always had with these back-and-forths between various programming philosophies is that the very nature of the argument exposes the reason the arguments don't work. The most common (but not only) way each side argues its point is to take some contrived example and show how philosophy X does it well, and how philosophy Y does it terribly. These examples are often ranted about by the "Y" proponents beca…

So let's say I've decided to sit down and write a digital audio workstation. I've got to pick at least one programming language and at least one general programming style. Let's say I pick C++ and (somewhat by implication) a generally OOP style. Someone comes along and says "oh, you could do this much better with Haskell and functional programming". How can you argue that the comparison involves an "X and Y" that are…

> How can you argue that the comparison involves an "X and Y" that are not designed to solve the same problem?

Because Y is Haskell and your project has soft-realtime scheduling constraints.

But if Y were Rust, point taken.

Re: The Case Against OOP Is Wildly Overstated

#205

Since I accepted I was no Einstein I embraced the KISS principle. My code became simpler, easier to understand. Of course it wouldn't get the approval of any software architect or any design pattern fanatic, but I can take any code I wrote 3 years ago, understand it on the fly and edit it with confidence. There are few bugs and they're never a nightmare to find. Now if I have to modify the code I was writing before m…

This so many times over. OOP encourages clever implementations, I believe. That is, when I and others use it, I often think about how clever it is. Until I need to debug it and fix it. Then I start cursing.

Re: The Case Against OOP Is Wildly Overstated

#206
It's been forever that I have used Inheritance in OOP. Perhaps Python has spoilt me, but 99% of my thought process automatically pivots to composition when thinking in terms of OOP.

And more towards how to name libraries, what functionality to put functions into and how to name my files.

OOP is just a tool to organize code. People give it too much thought sometimes. I did too.

Re: The Case Against OOP Is Wildly Overstated

#207

Earlier quoted context omitted.

That's basically a hand-rolled implementation of a state monad that supports real mutability. The Haskell equivalent is the ST monad. While it's possible to do this kind of thing, it's busywork that properly designed programming languages are perfectly capable of handling well on our behalf.

I had the same thought: he's doing OOP without using the "class" keyword. Well-written C code is actually very object-oriented this way, it just doesn't take advantage of the syntactic sugar of C++.

This is only one thing that OO languages provide. My point, though, was that global state is not inherent to procedural languages as you claimed. And if all you're getting from an OO language is a bit of sugar and single dispatch, you're not getting much.

Re: The Case Against OOP Is Wildly Overstated

#208

Since I accepted I was no Einstein I embraced the KISS principle. My code became simpler, easier to understand. Of course it wouldn't get the approval of any software architect or any design pattern fanatic, but I can take any code I wrote 3 years ago, understand it on the fly and edit it with confidence. There are few bugs and they're never a nightmare to find. Now if I have to modify the code I was writing before m…

In my opinion, a big thing many developers forget, especially those that are obsessed with design patterns and code rules, is that simple machines to solve complex problems are actually harder to design than convoluted ones. Leave a designer to their own devices, they immediately start spitting out way to many levels of indirection, it takes real thought to collapse those levels of indirection to something simple. Many less-experinced devs think that if they keep slapping on more layers, hide the problem more, more abstraction, they will reach some sort of inception-like base-case nirvana where the complex problem will magically become simple. But they are running the wrong directions. Simple, powerful, abstractions that make great tools great are generally pretty thin. They don't mask the actual problem, instead they provide good hand holds on it. C is a decent abstraction of assembly because it simplifies it, not because it hides it. All that being said, OOP, like many patterns, is perfectly fine if it makes a good abstraction. There is no one great pattern to rule them all.

Re: The Case Against OOP Is Wildly Overstated

#209
The best thing I can say about OOP is that it allows for private state that only certain logic is allowed to know about. In some cases, you just really need that.

But I think the biggest problem with OOP is that it encourages a spirit of "eager complication". Take getters/setters as a classic example. Occasionally that pattern can be useful, but standard practice in Java is to never ever create a simple public field. You always create a private field, with a getter and setter, under the assumption that later you'll need to put some special logic in there.

We can't just create some plain functions, we need a Helper Class™. We can't just pass in a function's dependencies as arguments, we need Dependency Injection™. We can't just use a union type, we need a Visitor Pattern™.

I think some of these habits were built in a world before certain simplifying language features were widely available (union types in particular are only recently entering the mainstream). Programmers were traumatized by the limitations of Java and the ensuing complexity of their projects, causing them to enter future projects already bracing for the worst. Simplicity is assumed to be impossible, so you just go ahead and barricade the windows with some up-front complexity in hopes of flattening the exponential complexity curve down the line.

But the world has changed since then. There's a reason multi-paradigm languages are becoming so popular: because implementing real projects without creating out-of-control complexity requires having a wide range of tools at your disposal. In this new world, I think it's really important that some of these patterns get unlearned.

I'll leave you with this Paul Graham post from 2002 about OOP Design Patterns: http://www.paulgraham.com/icad.html

> When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.

Re: The Case Against OOP Is Wildly Overstated

#210

Earlier quoted context omitted.

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 b…

> 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…

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.

Post reply on HN