>> When I started learning C++ I was shocked. Instead of using objects for compartmentalizing functionality, they were just used as a holding pen for loosely related functions. Instead of communicating between themselves, objects were operated on by some bigger parent object. I found it absurd and fought it for a long time. This has nothing whatsoever to do with C++. It's like blaming a microwave oven because your ki…
The Linux kernel is written in C, not C++. C has static typing, but it is definitely not strong static typing.
A Healthy Hatred of OOP, or the principles of my message-driven framework
71–80 of 98 posts
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#72Earlier quoted context omitted.
how fast can that player run? Is asking about internal state. When can you get to X is not. The internal vs. external separation can often greatly simplify things. A player does not care where another players feet are they care where the best place to toss the ball is. PS: In an actual game there is a lot of communication going on. You don't want to throw a ball at someone looking in the wrong direction. So, at some…
Of course there's innate complexity, but pursuing encapsulation for its own sake adds complexity you don't need (just like using functional programming techniques for intrinsically non-functional use-cases adds complexity for no good reason). Again, "messages", "objects", etc. -- these are metaphors. They should be abandoned as soon as they stop being helpful.
So, sure not everything should be an object. But, saying nothing should be is a much higher hurdle than that.
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#73Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#74Earlier quoted context omitted.
>If a class has state, you have to be able to read that state or it's useless. ... That's where getters come into play. No, having a bunch of getABC(), getXYZ(), getEtc() is a code smell . If the class has many getters()+setters() or has the equivalent of many public data members, it means that related actions requiring those variables are happening outside of the class/object instead of inside the class. The more ge…
You don't seem to realize it but your countLines() method is a getter. At the end of the day, you need to get values from your class, otherwise, they are useless (and they do side effects).
Yes, you eventually have to "get" values from the class but you don't literally have to mindlessly create a one-to-one set of "get()" for every private member variable.
The author's example and my response to it were talking about a literal thin wrapper of public getX() for a private int x. This practice deceptively looks like OOP (I "hid" that private member with a public method) but it's not really OOP.
Instead of gets() & sets(), the programmer should find the higher level concepts to turn into higher-level methods. This way, the gets()/sets() is kept to a bare minimum.
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#75The more I read about functional programming the more I question why are things this hard in traditional oops. If so many people have been doing oops for so many years then it must have something that is easy to pick up or something that is easier to work with. But after doing some functional programming the number of lines are painfully less and the code is easier to understand. I was thinking may be I was giving to…
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#76Earlier quoted context omitted.
Moreover, getters and setters can be readily modeled with messages. That messages and (at least single dispatch) methods are identical was settled decades ago. (Has someone worked out a multiple dispatch OOP based on message passing?)
The conceptual difference between messages and methods to me is that messages implies that it is the object itself that is the arbiter of whether or not it can handle a specific call, and the decision may depend on factors not knowable before the call. While "method" implies to me that it is something that may be applied to the object by an external actor. E.g. if I do "foo.bar()" in C++, the compiler will simply not…
In a more dynamic language, in fact "foo.bar()" may be equivalent of asking foo whether it understands how to bar, and if so, then please do it. If foo doesn't understand, there could be some mechanism for handling that, like a catch-all function that can be defined that gets invoked.
Likewise, we could also have a static language with message passing OOP in which the same check is implemented. The classes declare statically which messages they understand and the compiler checks that.
Quite simply, "late binding" != "message passing". There can be late binding of messages, and late binding of function calls.
There is no real conceptual difference between single dispatch and (synchronous) message passing.
What is Unix ioctl? Message passing or function call?
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#77The less actual code I see in articles like this, and the more abstraction I read about, the less I take the concept seriously. In fact, all of this seems like bullshit to me. The actual code inside of the repo is, well, object-oriented. How I interpret this is that the author seems to have no idea what they're even talking about, and that they write more about code than they write code itself. Show me what you mean,…
I should have a tutorial out very soon. The documentation is not yet complete but does have a few examples. Also, of course it's object-oriented. The article is titled a "healthy" hatred for a reason.
In similar systems that I have constructed in the past, I have used a number of methods for passing actors in different states.
Pass a fully instantiated actor via a transfer process. Nothing changes for the actor, beyond reassigning parentage.
Pass a cleaned actor via a similar process to the bench and add process. This was used to allow an actor to be reduced to a resting state as it were. In most cases you could think of it as a resurrection method that allowed discarded actors to be reinstated with only specified base properties in place.
Anyway, I don't use Lua at all, but I like these type of actor messaging models. I look forward to reading through the rest of your documentation once it's done.
O.
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#78The downside of message passing is debugging. No call stack so you can't trace things back to their source.
That's a big down side of a framework for asynchronous message passing (object-oriented or not). E.g. "Flow based programming". Message passing OOP doesn't necessarily imply that type of message passing. That is to say, the "send" call doesn't have to return until the target object has processed the message.
I think that obscures the better parts of the OOP view quite a bit.
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#79Your essay is arguing against a strawman of what "good" OOP is supposed to be. Your examples... >Objects just aren't supposed to be reaching into each other with 'getters' and 'setters' and messing with information. The getX() and setX() is an anti-pattern of good OOP. >Instead of using objects for compartmentalizing functionality, they were just used as a holding pen for loosely related functions. No, good OOP has c…
> The getX() and setX() is an anti-pattern of good OOP. No it isn't, it provides encapsulation, which the most important aspect of OOP. I agree with the rest.
Re: A Healthy Hatred of OOP, or the principles of my message-driven framework
#80Earlier quoted context omitted.
I should have a tutorial out very soon. The documentation is not yet complete but does have a few examples. Also, of course it's object-oriented. The article is titled a "healthy" hatred for a reason.
I just have one smallish question. Is the need to bench then add an actor the only way you "allow" transfer of children between parent actors? In similar systems that I have constructed in the past, I have used a number of methods for passing actors in different states. Pass a fully instantiated actor via a transfer process. Nothing changes for the actor, beyond reassigning parentage. Pass a cleaned actor via a simil…
Currently, yes. Since this is sort of an entity component system and that actors can always create more children anytime they want, I suppose I just always assumed that actors could be "spun-up" with any sort of functionality and then deleted when not used.
Benching/Joining an actor is more for handling errors at runtime or for debugging ("If I temporarily remove this actor will it solve my issue?").