Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Is there still pressure to use OOP? On Hacker News, at least, the trend seems to be moving in the opposite direction. There’s growing skepticism toward OOP, and that’s reflected in the popularity of languages like Rust and Zig, which are explicitly designed to push against traditional object-oriented patterns.

That’s not to say OOP advocacy has disappeared from HN. It still exists, but it no longer feels dominant or ascendant. If anything, it feels like a legacy viewpoint maintained by a sizable but aging contingent rather than a direction the community is moving toward.

Part of OOP’s staying power comes from what I’d call a cathartic trap. Procedural programming is intuitive and straightforward. OOP, by contrast, offers a new conceptual lens: objects, inheritance, polymorphism, and eventually design patterns. When someone internalizes this framework, there’s often a strong moment of “clicking” where complex software suddenly feels explainable and structured. That feeling of insight can be intoxicating. Design patterns, in particular, amplify this effect by making complexity feel principled and universally applicable.

But this catharsis is easy to confuse with effectiveness. The emotional satisfaction of understanding a system is orthogonal to whether that system actually produces better outcomes. I’ve seen a similar dynamic in religion, where the Bible’s dense symbolism and internal coherence produce a powerful sense of revelation once everything seems to “fit” together. The feeling is real, but it doesn’t validate the underlying model.

In practice, OOP often increases complexity and reduces modularity. This isn’t always obvious from inside the paradigm. It tends to become clear only after working seriously in other paradigms, where composition, data-oriented design, or functional approaches make the tradeoffs impossible to ignore.



In my circles, there is one part of OOP seen as positive: encapsulation. Everything else, specially inheritance and partly polymorphism are seen extremely negatively. The hype is over. BUT: I still hear more often as I would like, some manager stating “of course we will use C++, because is THE OOP language, and everybody knows OOP and UML are the only right way of doing software” this is an actual verbatim statement I had to listen 4 years ago.


I mostly agree with your assessment of how OOP is viewed today. In many technical circles, inheritance is seen as actively harmful, and polymorphism is at best tolerated and often misunderstood. The hype is largely gone. I’ve also heard the same managerial rhetoric you mention, where OOP and UML are treated as unquestionable defaults rather than design choices, so that part unfortunately still resonates.

Where I disagree is on encapsulation being the “good” part of OOP.

Encapsulation, as a general idea, is positive. Controlling boundaries, hiding representation, and enforcing invariants are all valuable. But encapsulation as realized through objects is where the deeper problem lies. Objects themselves are not modular, and the act of encapsulating a concept into an object breaks modularity at the moment the boundary is drawn.

When you encapsulate something in OOP, you permanently bind state and the methods that mutate that state into a single unit. That decision fixes the system’s decomposition early and hardens it. Behavior can no longer move independently of data. Any method that mutates state is forever tied to that object, its invariants, and its lifecycle. Reuse and recomposition now operate at the object level rather than the behavior level, which is a much coarser and more rigid unit of change.

This is the core issue. Encapsulation in OOP doesn’t just hide implementation details; it collapses multiple axes of change into one. Data representation, behavior, and control flow are fused together. As requirements evolve, those axes almost never evolve in lockstep, but the object boundary forces them to.

What makes this especially insidious is that the failure mode is slow and subtle. OOP systems don’t usually fail immediately. They degrade over time. As new requirements arrive, developers feel increasing resistance when trying to adapt the existing design. Changes start cutting across object boundaries. Workarounds appear. Indirection layers accumulate. Eventually the system is labeled as having “too much tech debt” or being the result of “poor early design decisions.”

But this framing misses the point. The design mistakes were not merely human error; they were largely inevitable given the abstraction. The original object model could not have anticipated future requirements, and because it was not modular enough to allow the design itself to evolve, every change compounded rigidity. The problem wasn’t that the design was wrong. It’s that it was forced to be fixed.

Polymorphism doesn’t fundamentally resolve this, and often reinforces it. While polymorphism itself is not inherently object-oriented, in OOP it is typically expressed through stateful objects and virtual dispatch. That keeps behavior anchored to object identity and mutation rather than allowing it to be recomposed freely as requirements shift.

The deeper requirement is that a system must be modular enough not just to extend behavior, but to change its own design as understanding improves. Object-based encapsulation works directly against this. It locks in assumptions early and makes architectural change progressively more expensive. By the time the limitations are obvious, the system is already entangled.

So while I agree that inheritance deserves much of the criticism, I think encapsulation via objects is the more fundamental problem. It’s not that encapsulation is bad in principle. It’s that object-based encapsulation produces systems that appear well-structured early on, but inevitably accumulate rigidity and hidden coupling over time. What people often call “tech debt” in OOP systems is frequently just the unavoidable artifact of an abstraction that was never modular enough to begin with. OOP was the tech debt.

The way forward is actually simple. Avoid mutation as much as possible. Use static methods (aka functions) as much as possible. Segregate IO and mutation into its own module separate from all other logic. Those rules are less of a cathartic paradigm shift then OOP and it takes another leap to see why doing these actually resolves most of the issues with OOP.


> Where I disagree is on encapsulation being the “good” part of OOP. Encapsulation, as a general idea, is positive. Controlling boundaries, hiding representation, and enforcing invariants are all valuable. But encapsulation as realized through objects is where the deeper problem lies. Objects themselves are not modular, and the act of encapsulating a concept into an object breaks modularity at the moment the boundary is drawn.

I’m personally with you here. Just in my circle they see it positively. But I agree with you: as long as it helps modularity, great, but also have many downsides that you describe very well.

Your last paragraph also perfectly aligned with my views. I think you are coming from a functional PoV, which luckily seems to have some more traction in the last decade or two. Sadly, before you say it, often are underline the parts of functional programming that are not the most useful you address here… but maybe, some day…


> There’s growing skepticism toward OOP, and that’s reflected in the popularity of languages like Rust and Zig, which are explicitly designed to push against traditional object-oriented patterns.

I don't know about Zig, but my experience with Rust's trait system is that it isn't explicitly against OOP. Traits and generics feel like an extension and generalization of the OOP principles. With OOP, you have classes (types) and/or objects (instances) and bunch of methods specific to the class/object. In Rust, you extend that concept to almost all types including structs and enums.

> OOP, by contrast, offers a new conceptual lens: objects, inheritance, polymorphism, and eventually design patterns.

Rust doesn't have inheritance in the traditional sense, but most OOP languages prefer composition to data inheritance. Meanwhile, polymorphism, dynamic dispatch and design patterns all exist in Rust.


> I don't know about Zig, but my experience with Rust's trait system is that it isn't explicitly against OOP. Traits and generics feel like an extension and generalization of the OOP principles. With OOP, you have classes (types) and/or objects (instances) and bunch of methods specific to the class/object. In Rust, you extend that concept to almost all types including structs and enums.

That’s not oop. Traits and generics are orthogonal to oop. It’s because oop is likely where you learned these concepts so you think the inception of these things is derived from oop.

What’s unique to oop is inheritance and encapsulation.

Design patterns isn’t unique to OOP either but there’s a strong cultural association with it. The term often involves strictly using encapsulated objects as the fundamental building block for each “pattern”.

The origin of the term “design patterns” was in fact established in context of OOP through the famous book and is often used exclusively to refer to OOP but the definition of the term itself is more broad.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: