OOP is the biggest problem in software development

Monkey Archive Forums/Digital Discussion/OOP is the biggest problem in software development

maverick69(Posted 2016) [#1]
About two or three months I stumbled upon this youtube video:


After that I began to reflect, thinking and researching and I come to the conclusion that Brian is actually right.

When I reflected I came to the conclusion that I've wasted the last 10 years or so with hunting bugs due to OOP and not understanding program flow. I've tried to used the best practices to do OOP right or fix OOP and complex software always tend to end up in a mess. Probably some of you will tell me I should do OOP right, but actually I know NO ONE who does it right. I've worked with lots of clever people over the last years and no one can do it right.

What I've also done is I had a looked at complex source code I did 15 years ago which was not object oriented and I instantly understood the program flow and were able to make changes without a problem (although the code wasn't the cleanest). With my OOP-Projects I often can't understand program flow instantly when I don't look at the project for a few weeks.

I've also did a new game (Demon Drop) with mostly no OOP-Concepts and instantly felt it was easier to refactor / add bigger changes to the code base. Debugging also becomes a lot easier and straight-forward. (But it was a rather simple game so not the best test to be honest).

I've also watched and read a lot of Casey Muratoris, Jonathan Blows and Mike Acton Videos and Articles and found out that a lot of the best developers in the game industry don't like OOP-Concepts and use them seldomly.

I'd really like to hear your opinions on that topic.

Shinkiro1(Posted 2016) [#2]
I found the same thing to be true in many cases. I also think that for each problem there is a style that fits the problem best.
E.g. OOP is a (mostly) good fit for GUI programming.

I have been writing more functions again, with simple input -> output semantics (pure).
For example, I have a function called EntityCanMoveDirection:Bool(entity:Entity, direction:Int, collisionLayer:TileLayer) in a seperate file.
It uses entities and TileLayers, but doesn't mix them as they would then become dependent on each other.
(like entity.CanMoveDirection(direction:Int, collisionLayer:TileLayer) would need to import TileLayer)

Objects are just abstractions, as are functions. There is always a fine line between too much and too little of it.

maverick69(Posted 2016) [#3]
>E.g. OOP is a (mostly) good fit for GUI programming.

I think even in the domain of GUI programming OOP is not the best fit. On most cases that I've worked an immediate-gui-mode-approach would have been simpler, faster and more intuitive:

Here is a video with thoughts of Casey: https://mollyrocket.com/861

And a C++ Lib to see how an implementation can look like:

muddy_shoes(Posted 2016) [#4]
It's possible to go overboard with OO abstraction but there's nothing inherent in the basics of OO that causes program flow to be difficult to follow. Equally, there's certainly nothing in procedural programming that guarantees that program flow will be easy to follow.

OO was sold on promises of re-use, straightforward modelling of real-world problems and a kind of enforced code modularity that eases the process of working with large projects and teams. Re-use was massively oversold and pushed in ways that encouraged hideous inheritance hierarchies. The modelling was oversold with the silly "just find your nouns" teaching of OO but it has broadly delivered a methodology that helps bridge the gap between "business" heads and software design. Equally, while OO is no magic bullet for large projects and teams I think it's hard to argue that it doesn't offer some structural support in those cases.

Neither OO zealots and hardline "OO is the root of all evil" types are right. Anti-OO arguments pretty much always pin weaknesses of OO without recognising the strengths (and often neglecting to mention that many of the more problematic areas can simply be avoided). That's especially true of people talking from a games programming perspective where the balance of desirable properties in a development approach is mostly very different from the broader business coding world.

maverick69(Posted 2016) [#5]
The thing is that in procedural programming you will see it instantly if the project is not structured well while in oop an unstructured big mess still looks structured.

But I also agree that the overuse is the main problem of (bad) OOP.

What do you think are the strengths of OOP (with examples) over procedural programming. I searched for examples a lot and didnt find much.

Gerry Quinn(Posted 2016) [#6]
Well, in your first post you mentioned refactoring / making changes, and that probably is the most fundamental thing OO should be making easier. so the question is, what's going wrong?:

OO is about attaching data to the methods that work on it. Now in principle, that seems like a win. But one can also imagine a situation in which you have a big block of data that you understand, and a load of functions that each do one thing, And then you change to OO and it's like a load of little fishies, all different shapes and colours, swam off and each bite off some data and some functions, and then they all start swimming in circles. Is that what's happening? Of course the problem is that OO is supposed to be about accessibility, not the opposite!

If you are separating things that are better off not separated, OO can make programming harder. It's necessary to be selective about how you do it, and how far you go with it,

Would you be without classes/structs for points, lists etc? Of course not. But depending on your programming style, your game logic can be pretty monolithic.

muddy_shoes(Posted 2016) [#7]
You won't find neat little code examples because the benefits aren't expressible in the sense of "Look at this nice bit of code that can't be achieved in procedural languages". The benefits, as I mentioned above, are mostly found in how the methodology finds a fit with broader business needs. They're certainly not to be found in a line-by-line comparison.

To be honest, nearly all syntax-level examples break down to "I prefer this", "I've engineered these examples to make my point" or "I'm going to ignore where this example I'm saying is bad actually has benefits over the one I'm saying is good". They're useful when discussing how easy or clear code to achieve one particular thing is (e.g. creating and populating an array) when comparing or designing languages/APIs but they're really very superficial when talking about entire methodologies.

Pretty much the same goes for your claim that procedural code is somehow instantly recognisable as badly structured. I don't see how that is universally the case. For a start I've seen plenty of procedural codebases with unrecognised structural issues that required deep reading of the code to find and OO codebases where structural issues were obvious to everyone involved. It's also plainly possible to write procedural code that follows many of the structural conventions of OO code that you presumably think obscure such problems and possible to write OO code that works very much like procedural. I'm not saying that what you say isn't true in your experience but it would seem to be the usual sort of overstatement of a (perfectly allowable) subjective opinion.

FelipeA(Posted 2016) [#8]
I think one thing we as programmers should have in mind is that we work with machines. Machines don't understand abstractions. I've told other game developers that love object oriented programming that having a game engine with that design will potentially run slower than a data oriented one. It's pretty clear that an object with a huge hierarchical tree structure will pollute data cache lines much easier. For example if you check the size of UE4's AActor class you'll see it's about ~860 bytes, now imagine iterating over every actor just to update the position. You would load all 860 bytes into d-cache and from the 860 bytes you'll probably just access or use ~24 bytes or a bit more. this is a waste of memory in my eyes. This approach could get a huge improvement with moving to a component based system and you just sample memory that you actually need and use.

Here is an benchmark I did for a current engine I am working on in JavaScript. http://perftestlazer.azurewebsites.net/ . Even though it's JavaScript the principles of data oriented design still apply.

I also think we should avoid doing an entity-component system where all components are stored in the entity, kind of Unity's style. A more efficient design is to have systems that store components contiguously in memory and let this same systems handle logic for that specific component. Entities should just be simple logicless identifiers.

Here is a great resource on data oriented design: http://www.dataorienteddesign.com/dodmain/

Of course all of this brings a lot of problems for developers used to object oriented because it forces you to think in a different way.

Edit: A great talk from C++ "guru" Scott Meyers talking about this topic

maverick69(Posted 2016) [#9]
@FelipaA: Great Talk! Loved it!

wiebow(Posted 2016) [#10]
I really like component systems. I ported Artemis to Max and it was a great experience. Maybe I'll move it to Monkey 2 as well just for the heck of it.

taumel(Posted 2016) [#11]
Whatever works best project related. I guess there is no perfect way for everything. Things tend to fire back at you once you push one direction too much. Some knowledge about the hard- and software below can be important. The best possible solutions change according to them. Sometimes it's just about having access to a linear chunk of memory.

Gerry Quinn(Posted 2016) [#12]
C++ may be a pig, but the great thing about learning it is that you wind up with a general understanding of how all languages (or at least most of the popular ones) translate into machine code. Then you can work around many of the issues when you need to, regardless of your preferred methodology.

Pixel_Outlaw(Posted 2016) [#13]
The biggest problem is languages that force you into a single paradigm. You can cut your foot off and marvel how clean your new stump is.
Use the right tool for the job, don't reduce your toolbox to a single screwdriver in the name of simplicity.

I like Common Lisp, Scheme and Python when not doing Monkey.
Dated C++ for quite a few years before it imploded with templates and became <template>++.

Is there a time I'll reach for C++? Sure, when I need speed and don't need dynamic/metaprogramming things happening at runtime.

maverick69(Posted 2016) [#14]
In my opinion the problem is that most programmers use OOP by default. In the last months I came to the conclusion that it's far better to force yourself to a more procedural style by default and when you think you have very good reason to use more complex paradigms, think about it again and only then use it.

At least for the stuff I've done in the last months I have used OOP language features very, very rarely. And In my case, this leads to easier to understand program flow, cleaner code and also to more efficient code. In comparison to some of my colleagues I always thought I had used OOP wisely but from my perspective now I was completely wrong. I had layers of layers of indirection and abstraction which looks nice on paper, but as soon as bugs are appearing it is much, much harder to debug - especially when you haven't worked on the project for a few weeks.

Don't get me wrong. Abstraction and Indirection can be a powerful tool - but if you have a hard time to understand the data-flow you should get of rid of it. If a framework or engine forces you to much into such a direction throw it away. Especially in web development I've seen this excessively - Build something on top of something that sits on top of something else that sits on top of something else. Then when something doesn't work well put another thing on top of it. It's crazy if you think about it. No one can ever such grown system, and so it's very easy to produce bugs.

I only can encourage all programmers to try this out: Force yourself to don't use any OOP features for a few weeks. Believe me this is quite hard - harder that you might think at the moment. And sometimes you have no idea how to do something without this specific OOP Feature just to find out later that there is a much more simpler solution for your problem. After doing this for a while, and you have forced yourself to think Anti-OOP you can safely mix OOP and procedural style - and you can use OOP features much more effectively. But in my case, for the projects I'm doing right now, I got rid of 95% of OOP code I would have written a few months ago (and tapped myself on the shoulder for it).