Live data from Hacker News

Moving Beyond the OOP Obsession

prog21.dadgum.com

61–70 of 72 posts

Re: Moving Beyond the OOP Obsession

#61

If you need an interface to your data, use structs/classes. If you need genericness when the size of the data doesn't change, use templates. If you need genericness when the size of the data does change, use inheritance. If you need genericness with respect to part of an algorithm, use lambdas.

Thank you for succinctly putting this to words.

Re: Moving Beyond the OOP Obsession

#63
post #40

Earlier quoted context omitted.

Are you saying all these outlets (labels, text box, buttons) are inheriting from a base FormObject that can be rendered? That would work without OOP. Make a FormRender component that manages that logic (being rendered in a form) and other components, one that manages a keyboard, other that can be clicked and handle hover, touch states, etc.

And you started slow reinvention of OOP!

No, the name of the game is composition. See ECS in game dev.

Re: Moving Beyond the OOP Obsession

#64
post #46
post #40

Earlier quoted context omitted.

Are you saying all these outlets (labels, text box, buttons) are inheriting from a base FormObject that can be rendered? That would work without OOP. Make a FormRender component that manages that logic (being rendered in a form) and other components, one that manages a keyboard, other that can be clicked and handle hover, touch states, etc.

Sure, but routing get's complex in your solution. The point was OOP is a natural fit for collections of different types in some context ex:GUI, Simulation, etc. The classic OOP case is probably a MUD where OO code ends up being very straightforward. IMO, the problem is it works really well in so many contexts that people end up trying to use it everywhere.

Routing? I'm just saying that OOP is as much of a perfect fit to GUI that Entity Component Systems (composition) are.

Re: Moving Beyond the OOP Obsession

#65
post #64
post #46

Earlier quoted context omitted.

Sure, but routing get's complex in your solution. The point was OOP is a natural fit for collections of different types in some context ex:GUI, Simulation, etc. The classic OOP case is probably a MUD where OO code ends up being very straightforward. IMO, the problem is it works really well in so many contexts that people end up trying to use it everywhere.

Routing? I'm just saying that OOP is as much of a perfect fit to GUI that Entity Component Systems (composition) are.

ECS works well when you can predefine everything ahead of time. But, it must be extended for every additional type.

As to messaging, consider what happens when you add JavaScript that can change the DOM. Now, you need to pass messages in both directions not just What is your Height- Width, but also my Height-Width has changed. Animated Gifs or Videos now want to update things in real time, and other windows can cover parts of your view port.

And let's not forget about transparency.

PS: ECS can still work, but it starts getting really complex.

Re: Moving Beyond the OOP Obsession

#66
post #55
post #27

Earlier quoted context omitted.

Well, if everything is an object, I guess everything is an object. Usually when people are talking about OO objects they mean data+behaviour.

> when people are talking about OO objects they mean data+behaviour The distinction between behavior being "a set of methods defined inside a class", and "a set of methods whose first param is a particular type of struct" is not that important.

The distinction between "a set of methods with privileged access to encapsulated internal state of a class" and "a set of functions whose first param is a particular type of struct, and operate on members of that struct that everyone can access" is pretty critical though.

Re: Moving Beyond the OOP Obsession

#67
post #14

A value, with a type. Nothing else. Stop highjacking everything into your OO religion. If you take everything of a value that originated elsewhere, there will be nothing left in the OOD.

Many of your comments have been breaking the HN guidelines. Please stop being uncivil and calling names.

You clearly know enough to make substantive contributions, which is great for this forum, but it you keep being rude, we'll have to ban you. So please don't.

We detached this subthread from https://news.ycombinator.com/item?id=11373716 and marked it off-topic.

Re: Moving Beyond the OOP Obsession

#68
Personally, think object oriented programming gets a fair amount "right". That isn't to say there aren't problems.

Specifically, classes as a mechanism of packaging data together with all the functions that act on that data is a good idea. Additionally, I think classes are more intuitive and generally tend to be syntactically clearer than their functional equivalent, namespace factories (though less semantically explicit). Fluent style chaining of method invokation is also a lot easier to read than nested function calls in most languages.

The biggest issue I have with classes is the concept of constructors and destructors. These are semantically unclear and basically break multiple inheritance. Aside from that, in dynamic languages classes also encourage people to write code that checks class type, which is both brittle and potentially limiting, depending on the context.

Re: Moving Beyond the OOP Obsession

#69

Earlier quoted context omitted.

The point is not a lack of objects but a lack of OOP. Yes, there are "objects" but there is also a separation between objects and methods etc.. The issue with m->set_volume(.08) is it becomes difficult to tell what happens inside set_volume() because in the method scope you have access to the internals of the "m" object, not just the interface. With mixer_set_volume(m, .08) you have ".08" and "m" but only the interfa…

Can you expand on this? I'm not sure I follow, but maybe there's something particular to C++ here that I don't get as I'm not well-versed in it. >> The issue with m->set_volume(.08) is it becomes difficult to tell what happens inside set_volume() Isn't that the point? That you shouldn't have to care what happens inside set_volume? If mixer was designed and implemented well, then set_volume (along with the rest of its…

Whether you are dealing with OOP, functional, or some other pattern it is always the point to create abstractions which you and others can forget about how they work.

Thus m->set_volume(.08) and set_volume(m, .08) should not require you to understand what happens internally as the user of either.

More generally in programming that is the point.

My only point is that of scope and essentially search space -- set_volume(m, .08) can only access the public interface of "m". While, m->set_volume(.08) could do almost anything to m. In a perfect world, with perfect programmers thinking the same way about what "set_volume" means or should do the separation of state and action would be less valuable.

This not to say OOP is > Functional or vice-versa. I think there is a place for both but that is a MUCH larger and more nuanced conversation :)

Re: Moving Beyond the OOP Obsession

#70
You could generalize the described approach even further and have a single global function called 'message', so that your entire app consists entirely of statements like:

    message(receiver, msg)
Sure, it's encapsulated, but it's hardly modular. The author knew not to do this because he's undoubtedly already had a lot of experience with OOP. So writing OOP-like functions comes easy to him. I'm not sure that would be the case for a beginner, who could also go to the other extreme and have a different function for everything, even if two methods differ only in their arguments:

    add_one_to(number)

    add two_to(number)

    etc.
The point of OOP is that it provides some guidance in navigating between the two extremes, and tools to manage modularity and redundancy (like inheritance and composition). Encapsulation isn't the sole benefit.
Post reply on HN