10 ms·
A Healthy Hatred of OOP, or the principles of my message-driven framework
- KirinDave 10y agoI think that we suffer from a paucity of precise language around OOP. Everything is OOP, everything is what Kay created, etc. But that's clearly not the case, and so people have these radically divergent systems of programming within the framework of "object orientation". My read of this article and it is very message-passing OO to me. Its broadcast mechanism is interesting, for sure. But it reads a lot like Erlang's supervision tree without all that troublesome thinking about a network. But it's approach is still very "OO".
- lcfcjs 10y agoCouldn't upvote this enough. Rabid, unreasonable and blind faith in OOP is just awful. Just because its Object Orientated programming, doesn't mean its good. Quite the opposite, it's highly likely that it wasn't implemented properly, its impossible to maintain and ultimately a complete waste of money.
- carsongross 10y agoA traditional OOP approach would have much of the functionality taken out of the player objects, using them simply to hold state. I don't agree with that characterization. The author certainly has a point that, in some languages in particular, like java, there tend to be massive over-decomposition of problems into reams of factories, controllers, controller factories and controller factory manager factories, but that isn't OOP, that's due to cultural and syntactic issues with those languages. (I know, I know, No True Scotsman.) In the Rails world, which is a non-trivial component of the broader OOP software world, there is a saying: "Fat Model, Skinny Controller" which is much more in the spirit of what the author is advocating, despite remaining OOP. Again, this isn't to deny the authors general point, but I don't believe it is bound to OOP, so much as it is to a certain style of OOP coding that arose from early (java in particular) over-engineering and excessive decomposition.
- jasode 10y agoYour 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 class/object with both private state and associated functions combined to provide a public interface for clients to use. (Although Java & C# (unlike C++) may have muddled this aspect because their language specification does not allow "free" functions to live in a plain namespace. Therefore, programmers are forced to use the "class{}" keyword with static functions as a workaround. Maybe that's where your "holding pen" characterization came from?) >A traditional OOP approach uses shadowy architecture to remove the responsibility of an object, No, good OOP tries to push responsibility into classes/objects so they can act as independent agents with minimal coupling to the outer context they sit in. I'm guessing your comments are based on seeing a lot of poor practices masquerading as OOP which affects what you think OOP actually is. Unfortunately, it's like trying to argue against Javascript because of overuse of "eval()" or arguing the flaws of Haskell because variable names are often 1 character long. There are definitely problems with OOP but they are not the bullet points you mentioned.
- smt88 10y agoI think your comment highlights my biggest problem with OOP: no one agrees on what it is or how to organize it. The amount of mental energy I used to spend on exactly how things should be separated into objects and how those objects interacted was astronomical.
- rlt3 10y ago>I'm guessing your comments are based on seeing a lot of poor practices masquerading as OOP which affects what you think OOP actually is I personally feel that the current OOP model eventually devolves into the bullet points you listed given enough complexity. One reason why I think this occurs is that there is no concept of a 'message' in OOP, only methods or functions of a class. There's explicit coupling even when calling a method with no arguments because you know the method is valid for that object. Contrast this with the example of the 'listener' in the room. A speaker broadcasts his message but the independent agents ultimately decide what to do with that message. The OOP approach calls "object->listen" on each listener. My approach simply broadcasts the message and lets the objects determine how to handle it themselves.
- daxfohl 10y agoThe downside of message passing is debugging. No call stack so you can't trace things back to their source.
- SlipperySlope 10y agoAn agent framework I built for my AI research has exactly that. I use an additional message parameter, automatically inserted and maintained by the framework, which is a list of the messages (FIPA style operation + parameters) from the originating agent forwards to the point of debugging. This gets voluminous and is gated by debug levels.
- Diederich 10y agoSame here. The framework I've been building over and over for various companies for the past 20 years has extensive debugging capabilities. With the right 'messages all the way down' mindset, it gets extremely powerful.
- koder2016 10y agoIf the framework is factored well, then you can plug-in a synchronous single-threaded message delivery when debugging.
- mpweiher 10y agoMaybe we need better tools? "Causeway, an open source distributed debugger written in E, lets you browse the causal graph of events in a distributed computation." http://www.erights.org/elang/tools/causeway/index.html http://www.erights.org/elang/tools/causeway/index.html
- kazinator 10y agoThat'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.
- andrewmcwatters 10y agoThe 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, don't just talk about it.
- rlt3 10y agoI 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.
- orillian 10y agoI 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 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.
- rlt3 10y ago>Is the need to bench then add an actor the only way you "allow" transfer of children between parent actors? 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?").
- ninjakeyboard 10y agoI made up the term 'object-oriented', and I can tell you I didn't have C++ in mind -- Alan Kay, OOPSLA '97
- rdtsc 10y agoJoe Armstrong's thoughts on how Erlang is more OO than OO languages: http://erlang.org/pipermail/erlang-questions/2009-November/047748.html http://erlang.org/pipermail/erlang-questions/2009-November/0... Joe likes to be funny, so don't get upset and confrontational about it. The central idea is this I think: --- I now believe the following to be central to the notion of OO. - Isolated concurrent things - Communication through message passing - Polymorphism All the other stuff (inheritance, private/public methods, ....) has nothing to do with OO. ---
- zzzcpan 10y agoDon't take it seriously. Joe actually admitted, that they only called Erlang OOish because of the OO hype, but Erlang is not an OO language in any way, of course.
- Diederich 10y agoI would gently submit to you that Erlang is pretty close to the definition of 'Object Oriented' as given by the guy who created that phrase. The commonly held definition of OO has drifted far from that ideal over the years.
- incepted 10y agoFYI, Armstrong thinks that OO sucks [1] so it's weird to see him claim his language is a better OOP language than others. [1] http://harmful.cat-v.org/software/OO_programming/why_oo_sucks http://harmful.cat-v.org/software/OO_programming/why_oo_suck...
- amelius 10y agoThe only good thing that OOP brings to the table is, in my opinion, access control.
- kevinavery 10y agoAlso referred to in this context as encapsulation. OOP provides a method of information hiding that allows implementation details to be changed later without changing the public API.
- abiox 10y agoone downside being that you risk creating obscured islands of mutable state, complecting engineering efforts.
- kevinavery 10y agoI view that more as a risk of using mutable state, not OOP. Regardless, I'd rather have the mutable state contained in as limited a scope as possible.
- sbov 10y agoIsn't this basically event driven programming?
- deleted 10y ago[deleted]
- koder2016 10y ago> Objects just aren't supposed to be reaching into each other with 'getters' and 'setters' and messing with information. In pure Actor Model adding two numbers would probably involve 2+ actors, yet Erlang is not doing this for some reason... I guess on a lower level hardcoding messages makes complete practical sense.
- qaq 10y agoHow does this make fp? If we fill fp with plugs for 1 man projects with 1 watcher we'd have 1000s of entries a day.
- barrkel 10y agoThe OOP referred to in this article is certainly a straw man, but the alternative suggested has problems too. Teams that work well act almost like they're mind-reading one another. High quality orchestration of disparate parts is in tension with encapsulation. Actor-based programming is highly concurrent but in my experience it's harder to reason about as it scales up. Emergent behaviour of interactions between hidden states is sometimes the goal, and sometimes an unwanted side-effect. Network protocols are tricky to get right for a reason; splitting everything out into a shared-nothing message-passing architecture isn't a panacea. I lean more towards explicit but immutable data structures, and referentially transparent functions over those data structures. In this world, parallelism can increase performance without observable concurrency. Concurrency is the root of non-determinism; non-determinism should be avoided unless it's inherent to the problem at hand. OOP is a middle ground in this world, but it's ill-defined. Depending on style, it can be stateful and imperative, functional or message-oriented. OOP is not an absolute bad; with effort, it can be massaged, or herded, into working patterns. But it's certainly not a universal optimum.
- paulddraper 10y agoOne of the more ironic titles I've seen. Alan Kay (progenitor of Smalltalk and OOP) has said on various occasions that it should have been called message-oriented programming, rather than object-oriented. "I'm sorry that I long ago coined the term 'objects' for this topic because it gets many people to focus on the lesser idea. The big idea is 'messaging'" http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-...
- markbnj 10y ago>> 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 kid put a ball of tin foil in it. C++ is a great language when you are developing big compiled programs and need strong metaphors for decoupling and modularity. Most developers today work on distributed systems where the individual cooperating pieces that they write are much smaller. Your 1000 line HTTP handler in python won't benefit much from strong static type checking, but the linux kernel does, and so do a lot of the infrastructure components we all take for granted every day.
- wtetzner 10y agoThe Linux kernel is written in C, not C++. C has static typing, but it is definitely not strong static typing.
- markbnj 10y agoYeah I did not mean to imply that the kernel was written in C++. As to whether C is "strongly typed" or not that is a matter on which we can disagree, as there is no agreed-upon definition of what that means. In my view it certainly falls on the strongly-typed side of the line when compared to the languages most developers use today. The point of my response is that OO methods as embodied in C++ were a response to the growing complexity of compiled programs back when it was developed, and those principles definitely helped developers, including myself, get a handle on that complexity.
- lucb1e 10y agoSome meta feedback on the article: this font is too big to comfortably read on mobile, fitting about five to seven words on a line (the typically recommended line length is about 14 words).
- CyberDildonics 10y agoTLDR: Terrible programming practices end up putting blame on labels and languages.
- nbevans 10y agoThe same thing happened with REST, TDD and Microservices, etc. The term gets hijacked by people that are less than skilled at executing it. And unfortunately there are more unskilled than skilled people in software; so usually the hijacked term wins the contest. It then takes decades of the "original guy" sending out a BBS message / IRC message / vBulletin post / Blog post / Tweet / HN comment / etc to try to correct people's understanding by saying "actually, that's not canon!".
- copx 10y agoComment on the code: As a Lua aficionado I hate to see stuff like this: Ball = {} Ball.__index = Ball function Ball.new (x, y) local table = {} setmetatable(table, Ball) table.x = x table.y = y return table end Explicit setmetatable() call and manual __index setting? You can automate this and hide all the metatable magic = less code to write, less potential for bugs. E.g. in my own Lua object system the above would be: Ball = Class() function Ball:Properties(x, y) return { x = x, y = y } end
- andrewvijay 10y agoThe 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 too much credit to FP but I was not it's simply just the way things are. But why has FN been used only as an academic tool and not as a goto programming paradigm? Can someone shed some light on this?
- nv-vn 10y agoHistorically, mostly performance. Outside of academia, performance becomes an important factor in most programs. In the past, both slower computers and fewer optimizations made implementing the abstractions of functional programming ridiculously costly. Once it lost out to imperative programming, it only got harder to change the tide. Performance is now adequate but functional languages lack educational material and libraries as well as industry support.
- lostcolony 10y agoBroad generalizations here, but from my understanding - Back in the dark ages, the performance difference between imperative code and functional code was too large for FP to gain much traction outside of academic circles. By the time the hardware was anywhere near reasonable, OO had become a thing. People missed some of the key points Alan Kay had, latching on to the one thing that was immediately understandable: objects could model the nouns of your problem domain. That popularity meant that the mainstream was focused on OO, rather than FP. I went through college in the late 2000s, at a well respected university, for computer science. I had classes devoted to OO(A/D/P); I had none devoted to FP. If you were exposed to it, it was via having to learn a Lisp in the AI class, or similar.
- andrewvijay 10y agoOkay. That's a great way to put it.