Hacker News new | ask | show | jobs
by gruseom 5199 days ago
What is wrong is using OO when it is unnecessary

That's a platitude which everybody can and does say about everything.

But I think one can make a case that there is something wrong with OO in general. The original arguments for OO were: it's better for managing complexity, and it creates programs that are easier to change. Both of these turned out not to be true in general. So we need to ask, when is OO a win? But for simpler problems it doesn't matter, because anything would work. So we need to ask: what are the hard problems that OO makes significantly easier? I don't think anyone has answered that.

I suspect it's that OO is good when the problem involves some well-defined system that exists objectively outside the program - for example, a physical system. One can look at that outside thing and ask, "what are its components?" and represent each with a class. The objective reality takes care of the hardest part of OO, which is knowing what the classes should be. (Whereas most of the time that just takes our first hard problem - what should the system do? - and makes it even harder.) As you make mistakes and have to change your classes, you can interrogate the outside system to find out what the mistakes are, and the new classes are likely to be refinements of the old ones rather than wholly incompatible.

This answer boils down to saying that OO's sweet spot is right where it originated: simulation. But that's something of a niche, not the general-purpose complexity-tackling paradigm it was sold as. (There's an interview on Youtube of Steve Jobs in 1995 or so saying that OO means programmers can build software out of pre-existing components and that this makes for at least one order of magnitude more productivity - that "at least" being a marvelous Jobsian touch.)

The reason OO endures as a general-purpose paradigm is inertia. Several generations of programmers have been taught it as the way to program -- which it is not, except that thinking makes it so. How did it get to become so standard? Story of the software industry to date: software is hard, so we come up with a theory of how we would like it to work, do that, and filter out the conflicting evidence.

5 comments

> The original arguments for OO were: it's better for managing complexity, and it creates programs that are easier to change. Both of these turned out not to be true in general.

Wrong. Even the worst Enterprisey mess of Java classes and interfaces that you can find today, is probably better than most of the spaghetti, global state ridden, wild west that existed in the golden days of "procedural" programming.

If you consider that software is composed of Code and Data, then OOP was the first programming model that offered a solid, practical and efficient approach to the organization of data, code and the relationship between the two. That resulted in programs that, given their size and amount of features, were generally easier to understand and change.

That doesn't mean OOP was perfect, or that it couldn't be misused; it was never a silver bullet. With the last generation of software developers trained from the ground up with at least some idea that code and data and need to be organized and structured properly, it's time to leave many of the practices and patterns of "pure" OOP and evolve into something better. In particular, Functional has finally become practical in the mainstream, with most languages offering efficient methods for developing with functional patterns.

You believe this, but you've given no reason to believe it other than the dogma you favor. The old-fashioned procedural systems I've seen with global state and the like were actually easier to understand than the convoluted object systems with which they were often replaced. Your comment is exactly the kind of thing that people who are enthralled with a paradigm say. But the "worst Enterprisey mess of Java" that you blithely invoke is... really bad, actually, as bad as anything out there. You're assuming that paradigm shifts constitute progress. I offer an alternate explanation for why paradigms may shift: because the new generation wants to feel smarter than the old one.
OO enterprisey mess is strictly better than global state ridden spaghetti code. The hard part with enterprisey code is that the code performing the action is hidden under layers of abstraction. The bootstrapping cost is much higher here because you have to put more abstractions in your head before you can understand a particular bit of functionality. This is a different sort of complexity than the global state spaghetti.

With the global state code you have to understand the entire codebase to be sure who exactly is modifying a particular bit of state. This is far more fragile because the "interaction space" of a bit of code is much greater. The dangerous part is that while you must understand the whole codebase, the code itself doesn't enforce this. You're free to cowboy-edit a particular function and feel smug that this was much easier than the enterprisey code. But you can't be sure you didn't introduce a subtle bug in doing so.

The enterprisey code is better because it forces you to understand exactly what you need to before you can modify the program. Plus the layered abstractions provide strong type safety to help against introducing bugs. Enterprisey code has its flaws, but I think its a flaw of organization of the code rather than the abstractions themselves. It should be clear how to get to the code that is actually performing the action. The language itself or the IDE should provide a mechanism for this. Barring that you need strong conventions in your project to make implementations clear from the naming scheme.

This sounds like ideology to me. You can never be sure you didn't introduce a subtle bug, you can never force someone to understand what they need to, and interactions between objects can be just as hard to understand as any other interactions.

I agree that a project needs strong conventions, consistently practiced. See Eric Evans on ubiquitous language for the logical extension of that thinking. But this is as true of OO as anywhere else.

First off, apologies for seemingly badgering you in various threads in this post. I don't usually look at usernames when replying so it was completely by accident.

>interactions between objects can be just as hard to understand as any other interactions.

While this is true, there are strictly fewer possible interactions compared to the same functionality written only using primitives. To put it simply, one must understand all code that has a bit of data in its scope to fully understand how that bit of data changes. The smaller the scopes your program operates in, the smaller the "interaction space", and the easier it is to reason about. Class hierarchies do add complexity, but its usually well contained. It adds to the startup cost of comprehending a codebase which is why people tend to hate it.

That's hilarious. Well, you're welcome to "badger" (i.e., discuss) anytime. It's I who should apologize for producing every other damn comment in this thread.

In my experience, classes don't give the kind of scope protection you're talking about. They pretend to, but then you end up having to understand them anyway. True scope protection exists as (1) local variables inside functions, and (2) API calls between truly independent systems. (If the systems aren't truly independent, but just pretending to be, then you need to understand them anyway.)

When I compare crappy codebases in procedural C vs OO java, all I can say is that it took fewer lines of code to bring a project to the region of paralysis in C. Does that mean the C codebases accomplished less? I don't think so.

Part of the allure of Java: it gives the illusion that more progress was made before you entered that region.

We've all heard that you can shoot yourself in the foot with any language, but I think the implications haven't fully sunk in: There are no bad paradigms, only bad codebases.

>The original arguments for OO were: it's better for managing complexity, and it creates programs that are easier to change. Both of these turned out not to be true in general.

How so? I find OOP code to be much easier to understand and change.

I've tried to explain that in my other comments. But we may not be able to say much to each other than that our experiences differ. How much of our experience is real and how much is owed to our assumptions (like "OO is good" or "not") is impossible to disentangle in a general discussion. You know how this stuff really gets hammered out? When people are working together on the same system. Then we can point to specific examples that we both understand, and try to come to an arrangement we both like. Barring that, it's pretty much YMMV.
The thing that is wrong with OO in general is that is is not a silver bullet. I disagree that OO is useful only for simulation - I've done virtually no simulation work and I've found using OO useful in many contexts. Maybe if I used functional style or hypertyped dynamic agile mumbojumbo style or whatever is the fashion de jour - I would save some time, but OO worked fine for me and allowed me to do what I needed efficiently. Would I use it everywhere? Definitely no. Does it have a prominent place in my tool belt? Definitely yes. I reject the false dichotomy of "OO is Da Thing, should be used for everything" and "OO is useless except in very narrow niche". My experience is that OO is very useful for reducing complexity of projects of considerable size with high reuse potential and defined, though not completely static interfaces.
Of course you find OO useful in many contexts, since you know it and like it. But the argument is not that OO is useless. The argument is that it provides no compelling advantage and that it comes with costs that people don't count because -- owing to familiarity -- they don't see them. It would be interesting to know how much of the "considerable size" of the systems you refer to is owed to the paradigm to begin with. The cure is often the disease.
No compelling advantage over what? Over random bag of spaghetti code? You bet it does. Over some other methodology? Bring up the example and we'd see. I am sure you can replace OO with something else - so what? I explicitly said OO is not the panacea - you like something else, you do it. So what's your proposal?

Considerable size of the system is because of considerable complexity of the task at hand. I don't see how you can write 1000-page book of requirements into 2 screens of code. And if you need the system that is able to be customized to satisfy different books with minimal change - you need more complex code.

Another reason it endures is the large collection of mature and easy to use libraries available. Of course this is something of a chicken and egg problem, but a very present one.
Yes, but that's just the same inertia. If programmers no longer believed in those libraries, they'd soon write new ones. Otherwise our systems would all still be integrating with Fortran and COBOL. Some still do, of course - and the extent to which they still do is probably the true measure of the library argument.
I'm not so convinced. There was a time when most people had grown up with procedural code. OO offered enough promise that people moved over to it and developed things like Cocoa or Java.

If people aren't moving on, it's not simply because of 'intertia'. It's because the alternatives aren't offering enough benefit yet.

I think that's nearly entirely untrue. Emotional attachment to what one already knows is the dominant factor - all the more dominant because, in our zeal to appear rational, we deny it.

What will change the paradigm is the desire of a future generation to make its mark by throwing out how the previous generation did things. One can see this trying to happen with FP, though I doubt FP will reach mass appeal.

When you do anything as intensely as writing software demands, your identity gets involved. When identity is involved, emotions are strong. The image of being a rational engineer is mostly a veneer on top of this process.

Edit: 'intertia' - your making fun of an obvious typo rather illustrates the point.

You haven't explained how the inertia was overcome before. Nor have you explained what you think would replace OO if not for the inertia.

So this is basically a contentless argument that says people are stuck on OO because they are irrational.

As you me 'making fun' of a typo - I don't know what you're projecting onto me. I simply mistyped the word inertia. I put it in quotes because I don't think it's a cause of anything.

My apologies! I had typed intertia at one point and thought your quotation marks were quoting that. It seems our fingers work similarly even if our minds do not :)

As for OO, I think our disagreement has probably reached a fixed point.

Edit: nah, I can't resist one more. I believe I explained how the inertia was overcome before: people who were not identified with the dominant theory at the time (structured programming) came up with a new one (object-orientation) and convinced themselves and others that it would solve their problems. Why did they do that? Because the old theory sucked and they wanted to do better. Their error was in identifying with the new theory instead of failing to see that it also sucks. The only reason they could see that the old theory sucked was that it was someone else's theory.

As for "what would replace OO if not for inertia", I know what my replacement is: nothing. I try to just let the problem tell me what to do and change what doesn't work. Turns out you can do that quite easily in an old-fashioned style. But if you mean what paradigm will replace OO (keeping in mind that we ought to give up our addiction to paradigms), who knows? FP is a candidate. One thing we can say for sure is that something new and shiny-looking will come along, until we eventually figure out that the software problem doesn't exist on that level and that all of these paradigms are more or less cults.

Perhaps I should add that I don't claim to know all these things. I'm just extrapolating from experience and observation of others.

Maybe the reason programmers moved from cobol to OO is because they found OO better? Staying with Cobol was an option?
It would have been if pre-existing software (libraries) were the dominant factor.
There is that other sweet spot: UI programming. I don't think I have ever seen a better setup for UI code.
I just read through the ClojureScript One source and read through their wiki and tutorial. The mini-framework they've developed borrows ideas from (at least as I gather from their docs) functional reactive programming and dataflow programming. You register handlers who respond to events, and it's mostly just functions calling each other, although obviously there's a huge pile of Objects with a capital O in the browser's DOM. But I think it's a pretty compelling alternative, and certainly interesting, although I'm not sure if it's actually better or not.
State machines! But that is another discussion. Let's have it some time.