Live data from Hacker News

OOP Is Dead, Long Live OOP

gamedev.net

181–190 of 357 posts

Re: OOP Is Dead, Long Live OOP

#181
post #48

Earlier quoted context omitted.

ECS as they are using it in this blog is about Data Oriented Design. It's not just OOP plus favoring composition over inheritance. DOD explicitly advocates separating data from behavior, and is strongly opposed to OOP in general.

Just so I understand you right: they're advocating global functions to operate on predictably similar data structures? If that's the case, it seems like you'd want some of them to be object-oriented, and some not.

Each system tends to operate on different sets of data which don't tend to be very similar, and systems may operate on multiple data sets.

You could build each system as an object, but you wouldn't want to store the relevant data structures within that object because other systems will likely need to use those data structures as well.

The entire architecture is predicated on separating data and behavior. Yes you can build an ECS system using classes, but nothing about it fits into what you'd call OOP.

Re: OOP Is Dead, Long Live OOP

#183
post #176

A good heuristic: if you’re not dealing with “state” (i.e., Games, DB ORM, Reinforcement Learning), then don’t use OOP

Really? I’d say the accidental distribution of state across objects due to cross cutting concerns is exactly where OO breaks down for me.

Re: OOP Is Dead, Long Live OOP

#184
Everything here is bad and wrong on so many levels. It's hard to even wrap my head around the amount of wrong going on everywhere here.

The initial Object Oriented (OO) code - as partially demonstrated by the author, and more succinctly by the grand-author - is badly designed. In the grand-author's slides they remove a number of these stupidities, which the author appears to ignore (both for final performance comparisons and for understanding why they were even there). Notably they (the grand author) originally built a reflection (runtime type) system [0] directly into their game objects (application level code). This of course means they then ended up fighting their programming language over the performance of this as they attempted to use and improve it.

The author's improved code is also a total failure. He removes a significant amount of the flexibility in the original system, which was a requirement of the problem space. By removing features he gains a significant amount of performance (in actuality about 2x - not 10x - compared to the grand author's slides). The lack of understanding why those features were there in the first place demonstrates he doesn't understand the actual design space of the toy demonstration code. It also demonstrates he failed to read the grand-author's slides where they go through some of these changes and why they aren't viable.

The author also fails to even discuss the Entity Component System (ECS) which it should be noted is still faster (and feature intact!) than the author's code. I cannot be more emphatic on that point, an ECS is a solution to the performance of run-time composition problems, and it still worked even better than an attempt to do the OO solution right (again by removing features!).

Though the author makes an excellent point about how most ECS solutions tend to fight the programming system they are in, he doesn't really explain or demonstrate it. What the grand-author did wrong here (though probably actually not in their talk considering who they work for) is not point out that the ECS should be part of one's programming tool to be most effective. Notably the ECS optimization should be part of one's programming language [1] (a game engine's programming language - like Unity's - would count).

Point is this author is very wrong and does not understand design (in general) nor the entity component system pattern in specific at all. The grand author's example code base is disingenuous of actual OO principles, and does not provide reasonable advice on how to deploy an ECS. Oh and they both got wrong that ECS solutions should be part of one's programming tool, not application space.

[0] Engines are often attempting to solve a sufficiently complex problem space that they require runtime type systems. This is not something one can avoid unless writing a bespoke "engine" for a single game.

[1] Unless your programming language is sufficiently advanced to allow creating - effectively - compiled code at runtime as a generalized library. Which C++ is because of template meta-programming, but the included example code is not.

Re: OOP Is Dead, Long Live OOP

#185
post #177

All my attempts to jump off OOP train break at exact same moment when I try to write a unit test. Closure: or, simply use this monstrous component pattern when 70% of your code is boilerplate or hack into namespaces and override functions in them in runtime. And don’t forget to do it in right order! JavaScript: yeah, simply re-define ‘require’ before importing dependencies in tests. Yeah, do it in right order. Recent…

Go interfaces, Rust traits, and Haskell typeclasses and simple parameters do exactly what you ask. In fact, it's harder to mock/stub in OOP than it is in FP by the nature of FP making all dependencies always explicit. Being able to use a 'property' in the body of the functions means you're now relying on a side effect that will have to be magically mocked.

In OOP, type signatures tend to lie. Not so true for FP.

Re: OOP Is Dead, Long Live OOP

#186
post #100

Earlier quoted context omitted.

That presentation basically says "write simple code". I'm not sure how is that helpful to anyone.

It's immensely helpful. Stuck in a rut designing your type hierarchies and making sure they are perfectly SOLID? STOP. Write the simplest, most clear and concise thing that works, refactor it once it gets too big to fit in your head. Not sure if your AbstractFactoryBeanProxyImplImpl is generic enough to cover all use cases? STOP. Write the simplest most clear and concise thing that works, refactor it to adapt to more…

I'm by no means advocating SOLID is the right/only way. I agree with "Write the simplest, most clear and concise thing that works", but it offers no help on how to do that. The how comes from experience. Simplifying complex and large things takes effort and thinking. SOLID helps with that, if used right and not as a religion. I feel "do the simplest" is way too generic an advice.

Re: OOP Is Dead, Long Live OOP

#187

Becoming a professional Haskell and Erlang developer really shifted my view on OOP (let OOP denote class based OOP as found in Java or C++). In my view, OOP is prove a poor model for computation, and the result has been that OO code is almost always significantly more complex and error prone than an equivalent computation written in a concurrent, functional, or structured paradigm. Recent trends in language design (s…

> my view on OOP (let OOP denote class based OOP as found in Java or C++) Maybe you should take a look at a real OOP language like Smalltalk before you tell us why OOP is a bad idea. Otherwise, I might tell you why consumers will never adopt cars as I drove a Trabant once.

Smalltalk is not an especially impressive language in 2018 and inspection and reflection aren't isolated to OOP today either.

Re: OOP Is Dead, Long Live OOP

#188

OOP is just a mental model. Deep down everything is made of bits. The church of OOP has failed but if something looks like a duck, walks like a duck and talks like a duck it probably is useful to make a duck class. We're now down to fighting for nuances. You can do most things with OOP or without OOP but each path has some upsides and downsides and most of the time it's good to use some things it provides where it ma…

I think this relates to what you're saying. I've never felt any frustration that OOP feels like the wrong tool when I'm using languages that give me the choice to use it or not (like Python, and JavaScript). But when I'm using Java, as one example, it often feels like I'm really locking myself into a design up front. In Python, especially. I'll find myself starting off all experiments or simple projects with function…

> I've never felt any frustration that OOP feels like the wrong tool when I'm using languages that give me the choice to use it or not (like Python, and JavaScript).

Do you not miss more advanced features, like multiple dispatch? Do you just implement it ad-hoc when you need it?

I don't know any way to say it that doesn't come off sounding condescending, but this looks like the Blub Paradox to me. Python's brand of OOP is better than most, but it still feels pretty limiting to me. It doesn't even offer syntactic abstraction to make it easy to work around. You have to hope (as the 'multimethod' package does) that other features accidentally allow you to.

Re: OOP Is Dead, Long Live OOP

#189

Does anyone know of a good reference for idiomatic OO(P)? Like the Codd paper for Relational Algebra.

If you use a typical IDE that comes with Squeak or VisualWorks, you can quickly inspect a lot of idiomatic code from the standard library. The most common mistake I have seen is that people who know about other programming languages, start looking at OOP as a way to separate and organize code. Instead, it starts from the other side: OOP is based on a few core concepts, and those concepts are critical to understanding…

Thanks for your reply. Where would you go to "to understand the concept-side of it" better?

I am reasonably fluent in Java and Python, and read a lot of C/C++. So I think I have a solid understanding what OO looks like, and what concepts are involved (dynamic dispatch, polymorphism, inheritance, etc). However, there is a lot of critique about the OO models in these languages and code that is found in the wild. What I am looking for is a principled treatment, that avoids these pitfalls.

Re: OOP Is Dead, Long Live OOP

#190
post #177

All my attempts to jump off OOP train break at exact same moment when I try to write a unit test. Closure: or, simply use this monstrous component pattern when 70% of your code is boilerplate or hack into namespaces and override functions in them in runtime. And don’t forget to do it in right order! JavaScript: yeah, simply re-define ‘require’ before importing dependencies in tests. Yeah, do it in right order. Recent…

Dependency injection is probably my favourite paradigm out there, especially in a statically typed language: for the reasons you mentioned, and for discoverability with an IDE (or ctags).

It is also a natural fit for “OOP”, or rather: classes. In a sense, it turns non-OO code into OO simply by storing the interfaces implementing the dependencies required by your code.

If that’s your only state, are you still OO? I’d say no. (Not as it’s commonly understood: mutable state.)

Hence, my proposed solution is: use classes & DI, but avoid (mutable) state (i.e. non dependencies).

Curious to hear others’ thoughts on this, though.

Post reply on HN