13 ms·
Pitfalls of object oriented programming (2009) [pdf]
- hurril 3y agoI think this description of what OO is, is flawed and makes people talk past each other: > • What is OO programming? – a programming paradigm that uses "objects" – data structures consisting of datafields and methods together with their interactions – to design applications and computer programs. (Wikipedia) It isn't that they are together, it's that the core entity of the language used to express solutions centers around identity over state or values. As in: two objects are different even when the fields are all equal, and also: two objects can be the same even with different field values. If you are going to object to this, I ask that you first contemplate whether or not you have programmed in any other way first, because as a fish, reasoning about what water is can be difficult.
- kragen 3y agoi am going to object to this; i've programmed in, among other things, prolog, ocaml, basic-80, c, the unadorned λ-calculus, bicicleta, and qfitzah, the last two of which are languages i designed and implemented myself and which have no mutability. moreover i don't think anyone would claim that basic-80 or c is object-oriented so i feel secure in claiming that i am more a walrus than a fish and therefore qualified to opine about water i do agree that identity and hidden mutability are important aspects of the oo view of the world, and that the author of these slides is off-base about what oo is. but i think that the essence of oo is that computation is done by sending messages to objects, but sending the same message to different objects invokes different code. this feature is present without mutability in bicicleta, and in abadi and cardelli's untyped ς-calculus, which it's based on; the ς-calculus was invented to formalize the essence of object-oriented typing the original intuition behind oo was to decompose a computer system into smaller computer systems, like a computer network; each object in the system was in effect a tiny computer, with its own private code and state. this was inspired by alan kay's undergraduate degree in biology, which mostly studies organisms made out of cells, which are basically tiny organisms. and in that formulation, obviously hidden mutability is the default, because you can't prevent a computer from changing its internal state as a result of a packet you send it; and mutability generally means identity is important but even more central to this formulation is the idea that different objects can behave differently in the same circumstances obviously none of this has anything to do with memory layout! except very indirectly
- bruce343434 3y agoThis is it. OOP is about building sub programs with their own state and behaviours, yet implementing a common interface so they can still effectively communicate to each other. If you boil it down to the essence, this means branching logic is encoded via a function pointer. Instead of manually switching to the correct behavior using other branching mechanisms like if or switch. This is what polymorphism is about. It's pattern matching. An interface is like an Enum to which you can add entries after it has been defined, and the behaviour for that specific variant naturally then has to be encoded inside the variant itself.
- Gehinnn 3y agoWould it be far fetched to say object oriented programming is inspired by nature/physics? And thus, "more natural" than, let's say, procedural programming. Animals can be modeled nicely with objects/classes. Physical objects do have internal private state and public interfaces. Also in nature, usually, you have multiple similar objects that work the same but have different internal state.
- bruce343434 3y agoThat might have been what Alan Kay was going for with his "cells of an organism" thing, yes. But even if you're not inspired by biology, it might just come up "naturally". Separating your data into structs, then operations on those structs, and not wanting to deal with all kinds of bookkeeping all the time, letting things manage their own - separation of concerns, aka single responsibility principle. I think automatic memory management might be a big example of this. Who wants to bother with this malloc/free stuff all the time? Who wants to keep track of ownership everywhere? Instead, have a dedicated subsystem handle it. That allows a higher signal to noise ratio in all the rest of the code that would otherwise be polluted with malloc/free. It also removes the entire class of bugs that can happen when you inevitably forget either of those. But having memory management in and of itself isn't "OOP". It's just an example of one of the principles that people tout when they talk of "OOP". Those principles can and do apply broadly. Was Alan Kay thinking of all this? I really don't know. All I know is that the dude digs biology.
- cmrdporcupine 3y agoYou've hit the nail on the head, and I think the replies below aren't getting your original point. Which I think is actually your point :-) The defining feature of OO approaches is in shifting the emphasis in sw development into the concept of identity-bags. All the other stuff about message passing, encapsulation, inheritance etc is just window dressing and implementation details of this core concept of identity-classification in software systems. I like how the "Out Of the Tarpit" (2006) paper breaks this down into the notion of "intentional" vs "extensional" identity, and I think this is a great model. For them, OO is all about "intentional identity" in that we create identities (objects, components) in our systems and move attributes and behavior onto them. OO shifts the analysis of software to identifying objects, components, services, and then makes software development all about the taxonomical management of them. In this model of software development, it's all about identifying components and then shuffling the data and functionality "into" them and managing the flow between them. (FWIW the paper identifies this way of thinking as one of the prime culprits in unnecessary complexity in software systems, and I agree with them.) The contrast is "extensional" identity, where identity in the software systems are emergent from their attributes. In this box we can put the relational data model, and its cousins in logic programming (prolog, datalog etc). In those systems, we are not concerned with "creating" identities and classifying systems/components/objects, but instead declaring the raw attributes -- tuples, facts, relations -- only. Queries then produce, at runtime, a multitude of results from permutations of those attributes. And, as you point out, equality/inequality is defined by the value of a tuples attributes, not by the object it lies in. This is crucial. There's a couple generations of software developers that are so immersed in the OO/intentional-identity way of thinking that they don't see that it's not intrinsic to software development, but actually a mental framework that was fostered through the 80s and 90s. It was an attempt to manage complexity and structure in software systems and also to create a marketplace of re-usable components. But I think it's actually failed at that. Most classes, objects, components, microservices end up failing in two respects: they end up reflecting the company's org chart more than anything else, and .. worse .. the bulk of the code and complexity ends up being how one moves data between all these (programmer created) systems rather than what the actual data is. The relationships (lines) between the boxes becomes the focus instead of the stuff was shoved into the box, and the whole behavior of the system becomes difficult to reason about. And when developers encounter systems that don't work along this model -- relational databases, functional programming, logic programming -- they often scratch their heads, resist, or wrap them up/confine them in OO/component type structures... damaging their usefulness.
- abberation 3y agocat-v at it again lmao
- Baldbvrhunter 3y agoThe site builder, Uriel [0], was like those of us in his circle, strongly opinionated. Sadly he suicided in 2011 with Sodium Pentothal he bought mail order from China. My final Skype message to him was "goodnight, don't drink the pentothal!" and Skype used to show it to me under his username every time I logged in. He, and his acerbic nature, are sorely missed. [0] https://www.reddit.com/user/uriel/ https://www.reddit.com/user/uriel/
- kaba0 3y agoif you mean that ridiculous "gcc/pdf/web browser is ridiculous, use tcc/txt file/curl" bullshit page, then I can't take you seriously. Feel free to use a pocket calculator instead of your current device, I guess, that's not bloated.
- bufio 3y agoWhere's the lie?
- robaye 3y agoThe original author revisited this talk[1][2] in 2017. You can also read more of the same ideas from the data-oriented-design list[3]. 1. https://www.youtube.com/watch?v=VAT9E-M-PoE https://www.youtube.com/watch?v=VAT9E-M-PoE 2. https://docs.google.com/presentation/d/1ST3mZgxmxqlpCFkdDhtgw116MQdCr2Fax2yjd8Az6zM/edit#slide=id.p https://docs.google.com/presentation/d/1ST3mZgxmxqlpCFkdDhtg... 3. https://github.com/dbartolini/data-oriented-design https://github.com/dbartolini/data-oriented-design
- nemoniac 3y ago“I invented the term ‘object-oriented’, and I can tell you C++ wasn't what I had in mind.” ~ Alan Kay, OOPSLA ‘97
- vendiddy 3y agoI believe Erlang/Elixir are closer to what he had in mind. (Processes with encapsulated state passing messages to each other.)
- freetonik 3y agoAnd also Smalltalk, I believe. It appeared ~15 years earlier than Erlang. The idea of holding encapsulated state and receiving messages is its core concept, AFAIK.
- kragen 3y agoguess who headed the smalltalk team and what team he was working on when he invented the term 'object-oriented'
- frou_dh 3y agoIt does make a lot more sense if messaging is asynchronous, because the metaphor breaks down immediately if sending any message requires the sender to freeze until a reply comes back.
- lucidguppy 3y agoI don't think anyone would "want" CPP. It feels like it's multiple layers of "this is how we've always done it" interleaved with some really good ideas (STL).
- kaba0 3y agoJust because someone coined the term, doesn't mean that they get to define it. The industry absolutely doesn't use OOP in any way similar to what Alan Kay does, and the former is the de facto correct usage.
- freetonik 3y agoI find "modern" OOP concepts apply pretty well to graphical user interfaces. I believe that a good UI has a consistent and relatively strict hierarchy, with few "unique snowflake" elements. Even such a divisive idea as multiple inheritance often makes sense in UI, i.e. there could be an element inheriting low-level behavior (HTTP/API call, etc) from a button and a high-level behavior (style/presentation, etc) from a visual class. (In a way, even CSS is kind of OOP, albeit with very confusing overriding rules.) When writing generic backend code in a language like Java, I often found fighting against OOP because the business logic is not necessarily mappable to "dog inherits from animal". And I can't change the business logic, so OOP has to give in. But when developing user interfaces, I am usually in more control, I am actually designing it, not observing directly from the business logic. And OOP forces me to have a more consistent implementation, which is beneficial for the user, because consistent UI makes it easy for people to get used to it, find the underlying logic in it, and start relying on it. If all links on all web pages would inherit from normal HTML href link (like it was designed in the beginning), we wouldn't suffer from those weird JS web apps where you can't open a link in a new page for example.
- trashburger 3y agoInheritance is usually not the solution; composition and delegation is. Unfortunately, the current landscape of popular languages have equated "object programming == inheritance" in people's minds. The fact that these languages make inheritance easy but provide no syntactical or semantic support for composition and delegating to inner objects compounds this problem. > there could be an element inheriting low-level behavior (HTTP/API call, etc) from a button and a high-level behavior (style/presentation, etc) from a visual class. This becomes very messy very quickly, and you would need to clearly separate the concerns to make them non-expressible on either side. CSS and JS make this possible by being two different languages, one Turing-incomplete (in usual scenarios).
- frou_dh 3y agoI think of inheritance as just being a workaday implementation detail to facilitate code reuse in some scenarios. Polymorphism ("many forms") is more related to the concept of interfaces, but as you touch on has been equated with inheritance in a lot of peoples' minds.
- ChrisMarshallNY 3y agoFor me, personally, I’ve learned to use the right tool for the job. In some cases, it’s OOP, in some cases, it might be something like FP, or Protocol-Oriented Design. I write in Swift, which supports all of the above. It’s been a while, since I’ve worked with C++, but I have heard that the modern version of the language similarly supports multiple paradigms. For the frontend, if I am writing for UIKit, I use OOP, and fairly standard MVP, as that is exactly what the framework was designed to afford. I haven’t done much SwiftUI, but I suspect that I’ll be using a lot less OOP, when I do. On the server end, I tend to use good ol’ PHP. It’s not an especially good OOP language, but I find that OOP isn’t as relevant for my backend work. That work tends to look a lot like very old-fashioned Structured Programming, which PHP is good for. As others have pointed out, I’ve found it easy to go down rabbitholes, with backend OOP. There’s a lot to be said for an approach as an experienced, multidisciplinary professional. It seems as if programming and software engineering pundits generally start from the premise that all [other] software developers stink, and rules and tools should be used in an effort to force them to write “good code,” as opposed to, for example, hiring smart people, and training and mentoring them to be adaptable, resourceful, disciplined engineers. That’s nothing new. I have been seeing this for my entire [long] career. The “new hotness” changes, but the attitudes are consistent. Here’s an old joke, from the 1980s: https://news.ycombinator.com/item?id=29345907 https://news.ycombinator.com/item?id=29345907
- kbrannigan 3y agoDo you use any framework for PHP?
- ChrisMarshallNY 3y agoNo, but if I did, it would probably be Laravel. A number of folks I highly respect, swear by it. In that case, I'd probably be using more OOP. With PHP, I tend to use OOP constructs as namespaces. My backend work is fairly humble. Most folks here, would laugh at it, but it works really, really well.
- lincpa 3y ago[dead]
- zigzag312 3y agoOOP, FP and other paradigms are all useful. Just don't do extremes like everything is an object or everything is immutable or everything is without side effects. I enjoy multi-paradigm languages the most.
- danielvaughn 3y agoYep. Any given software project of non-trivial complexity is going to be composed of many types of problems, each of which requiring its own solution and approach. I don’t think I’ve ever worked on a codebase that didn’t need both OOP and FP in different places.
- pydry 3y agoYeah but have you considered joining the church of everything is a list?
- augustk 3y ago> Data abstraction > Encapsulation > Polymorphism > Inheritance Note that it's the last two concepts which are specific to object oriented programming. The first two are already supported by non OOP languages like C and enable implementation of abstract data types. I think it's unfortunate that all concepts are often introduced in the same OOP course which may make the students believe that a class and an abstract data type is the same thing.
- Log_out_ 3y ago> Encapsulation as an idea failed spectacular again and again. What would have been valuable would have been a way to enforce layers of abstractions, with no composition or inheritance of objects on the same layer.
- ryandv 3y agoPolymorphism is not at all specific to OOP, and there are in fact different kinds of polymorphism; "generics" are pervasive in pure FP languages such as Haskell or imperative/functional languages like Rust, and are an instance of parametric polymorphism. Ad-hoc polymorphism, or "operator overloading," can also be seen in both languages as the "Eq" typeclass/trait and the equality operator `==`. It's subtype polymorphism and deeply nested inheritance structures that are maybe particular to OOP. It's also worth making a distinction between an abstract data type - a "thing" and some set of operations defined over it - and a data structure - a particular in-memory construction and set of procedures defined over it, often used to realize an abstract data type. An example being a dictionary ADT - supporting get, set, delete, etc. being realizable through different data structures; for example, a linked "association list" of (key, value) pairs vs. a hash table - with each having different performance characteristics, despite possessing the same properties as the ADT they implement.
- adrian_b 3y agoPolymorphism that is resolved at run-time, i.e. "virtual" functions is what is specific to OOP. The term "polymorphism" was first used in the documents of the language CPL (in mid sixties), the source of BCPL, where in British English it corresponded to what in the American documents of the same age, starting with McCarthy, were called overloaded operators and overloaded functions. The use of "polymorphism" mostly for the run-time polymorphism of OOP languages has appeared only a couple of decades later, with Smalltalk. "Generic", which might be a better term than both, has been popularized during the programming language contest that has lead to Ada (1979). Nowadays it is mostly used for polymorphism/overloading that is resolved at compile time, because this is how the term has been used in Ada.
- ryandv 3y agoThe slide deck is about performance pitfalls of OOP languages, which can surreptitiously introduce cache misses, random access to memory, and excessive levels of indirection into your code: > Prefetching > Data accesses are now predictable I'm reminded of a Stroustrup talk in which he says that vectors will always outperform linked list structures, by taking advantage of spatial locality and predictable access patterns to enable better cache prefetching. He even has a slide on C++ vs "True OO" style object graphs, and it looks remarkably similar to what's described in the OP: https://www.youtube.com/watch?v=YQs6IC-vgmo&t=3m53s https://www.youtube.com/watch?v=YQs6IC-vgmo&t=3m53s
- commandlinefan 3y agoThat went in a different direction than I expected it to - but it's also not specific to object oriented programming. Richard Stevens summarized this 40 years ago: "modularity is the enemy of performance". We've mostly accepted that this is an acceptable tradeoff, although the author (and I) aren't fully on board.
- rkagerer 3y agoWhen the whole OOP movement gained traction I struggled to accept the degree of value it provided above simple structs and functions (at least for an organized programmer). After decades developing on a lot of diverse platforms in a variety of languages and models, I've decided there ain't much you can't achieve without structs and functions (or their equivalent). Sure, any tool is most efficient in the hands of a master who knows how to wield it. But in practice all those shiny extras too often become productivity distractions.
- AnimalMuppet 3y agoTo me, the big difference between a struct and an object is when data has constraints. Let's say I have a rotation matrix. That means that the squares of all the entries in any one row or column add up to 1. If I have such a structure, and I find that it has rows that no longer add up to 1, well, what function messed it up? I have no idea. And if I have a million lines of code, that gives me a lot of places I have to look. But with an object, if I made that data private, only a member function can have messed up. I may still have a thousand lines I have to look at, but that's a lot less than a million. For larger code (tens of thousands of lines and larger), I consider access control to be essential, just to limit the size of the code that could possibly be at fault. Back in the day, I spent a lot of time playing "who messed up the structure?" in structure-and-function code...
- ReleaseCandidat 3y ago> But with an object, if I made that data private Being able to make a field of a record private does have nothing to do with OOP, even in C you can hide a struct's fields.
- deleted 3y ago[deleted]
- angiosperm 3y agoCongratulations, you have discovered Turing Completeness. But it is not a contest of what can be done, but rather of how clearly, succinctly, and performantly it can be done. Modularity is essential to human understanding, but inimical to performance. Succinctness demonstrates economy of expression, where it matters that what people need done is more succinct than things they don't. OO as a movement was childishly silly. OO as an organizational technique among many has been fruitful.
- angiosperm 3y agoAnything-oriented programming amounts to tying a hand and foot behind your back. Any big enough program can benefit from OO in certain spots, functional in others, relational here and there, generic throughout all the others, pipelined, dataflow, declarative, what-have-you. The problem dictates its solution. "Specialization is for insects."