12 ms·
Classes Considered Harmful [pdf]
- paulrpotts 10y agoHaving used C++, Java, C#, Python, Ruby, NewtonScript, Dylan, Scheme, and various other languages "in anger" I can say that in general I agree with the author's frustrations. My favorite (as in most flexible, least boilerplate) approaches to object-oriented programming have been: - NewtonScript's frames with prototype inheritance. Allows "objects" to consist of very small data structures that point to ROM objects and only use RAM for slots that actually vary, using copy-on-write. The actual implementation had some issues and of course that platform is dead, but the concept was great. - Dylan's adaptation of generic functions, with multiple inheritance. There are classes but they don't have methods "inside" them. The class hierarchy describes the dispatch for the generic functions. Allows some really nice styles of programming (dispatching on multiple parameters) that are perhaps possible but absolutely hideous in C++. - Qt's method. The use of a separate preprocessor step and generated code for dispatch was a hack to get around limitations of C++, but although you don't want to look too closely at that generated code if you value your sanity, at a practical level it works pretty well. In summary, I'd just add that it is a deep and abiding shame of my industry that people wind up in silos learning one model of object-oriented programming and never consider other models that are different and can be cleaner and far simpler to think about.
- formula1 10y agoI, being one of the few people on HN that like OOP, dont find anything you mentioned that organized, clean or simplified like oop. No copy is available in rust. Overloading a generic function seems like we are talking about interfaces. A preprocessor step again is similar to rust. But only the second has anything to do with writing in oop
- miles7 10y agoIn addition to Dylan, Julia also allows multiple dispatch via generic functions. I have found this approach to multiple dispatch leads to code that's much easier to reason about and maintain. My use case is a tensor library where the tensors have a single interface but various storage backend types, which 'interact' with each other. It doesn't make sense to define these interactions through methods belonging to only one class or the other.
- jghn 10y agoAlso R via the S4 OOP system, which was directly inspired by Dylan
- iokevins 10y agoFor what it's worth, the footer reads, "Submission to NOOL / 2015/10/12". NOOL seems to stand for "New Object-Oriented Languages", a workshop of the ACM SIGPLAN conference on Systems, Programming, Languages and Applications: Software for Humanity (SPLASH). http://2016.splashcon.org/home http://2016.splashcon.org/home http://2016.splashcon.org/track/nool2016 http://2016.splashcon.org/track/nool2016
- more_original 10y agoAnd the paper does appear in the program of NOOL 2015(!), so it has been accepted. http://2015.splashcon.org/track/nool2015#program http://2015.splashcon.org/track/nool2015#program
- ravenstine 10y agoThere seems to be a common fixation on objects "modeling the real world" with the counter argument for classes being that they don't model the real world. True, there isn't a physical chair class in real life(philosophically, there aren't even chairs), but there is a common abstract idea of what would describe the function and attributes of a chair. Granted, it differs a little from person to person, but objects themselves are all different in some way. As far as I can tell, in most OO languages, there's no reason why classes must use inheritance, though I am certainly willing to be schooled in that regard.
- merb 10y agoWell I'm a lover of scala and I dislike deep inheritence. That's actually why I love the model of golang and rust. They model the real world more closely. When you look at a desk, how do you define it? Well if it's a wooden desk it's actually the type Wood and it porbably has 4 table legs and probably a desk size of x*x. So this is way easier to represent with Subtyping, since a Desk can be made of wooden, but doesn't need to, so with structual inheritance that would mean a lot of boilerplate if you would need to define all type's of desks while in rust you would just add the impl trait to any of the base struct's, etc. Also deep inheritance can be nasty to debug, even Scala will probably move to a more flat level in their collections library.
- lmm 10y ago> As far as I can tell, in most OO languages, there's no reason why classes must use inheritance, though I am certainly willing to be schooled in that regard. That there is no precise definition of what a class is and isn't, and that the traditional notion of a class conflates several independent concepts, is precisely the big criticism! To my mind "traditional classes" means inheritance, and recent languages without inheritance (Rust or Go) have tended to not use the term "class".
- pottereric 10y agoForgive my ignorance. What do Rust and Go call their data structures that are analogous to classes?
- brudgers 10y agoLink to The Treaty of Orlando: http://web.media.mit.edu/~lieber/Publications/Treaty-of-Orlando-Chapter.pdf http://web.media.mit.edu/~lieber/Publications/Treaty-of-Orla...
- leblancfg 10y agoAlthough he spends quite some time on exploring the alternatives, the only reason the author specifically states where classes are harmful is because they are premature optimization. That's it? I guess "Classes considered a PITA" just didn't make a good title.
- lgas 10y agoHe delegates to his other paper with "A long discussion of the issues can be found in my submission to MASPEGHI 2013 [1]". That paper can be found here: http://www.cs.jyu.fi/maspeghi2013/papers.html http://www.cs.jyu.fi/maspeghi2013/papers.html specifically: http://www.cs.jyu.fi/maspeghi2013/p17-black.pdf http://www.cs.jyu.fi/maspeghi2013/p17-black.pdf
- newtscamander 10y agoThe premise is wrong, read the POODR book.
- newtscamander 10y agoThe premise is the introduction is wrong. "so before we have written a single program in our language, before we know whether shared behaviour will be important in the applications that will be written in it" read the POODR book, or watch this https://youtu.be/OMPfEXIlTVE?list=PL5s3t9kPeAN6aDxaSywIbeFJOCfm7ixpi https://youtu.be/OMPfEXIlTVE?list=PL5s3t9kPeAN6aDxaSywIbeFJO... it explains how shared behavior works without code duplication and why people tend to mess it up.
- asavinov 10y agoI like this kind of critical papers but I cannot agree with the author in this case. I have studied this problem quite deeply while working on concept-oriented programming and concept-oriented data model (http://conceptoriented.org/ http://conceptoriented.org/) for many years by also trying to minimize the number of basic constructs. Yet, my conclusion is that classes are actually needed. There are several major reasons for that. One of them is that we actually need two different relations: 1) membership relation, and 2) inheritance (or inclusion in more general case). Unfortunately, we cannot reduce them to one relation. If we do (in prototype-based languages) then normally we will still distinguish the role of this one relation depending on the context. Mathematically, we have the membership relation '∈' between an element and a set, and we have the subset relation '⊆'. Just as we need both of them, we need both class instances and classes. In other words, if somebody argues that classes are not needed, then it is analogous to the statement that sets are not needed and it is enough to have only membership relation among elements. It is possible to develop such a theory but then we will get an alternative mathematics. Or we will implicitly treat some elements as sets.
- eternalban 10y agohttp://conceptoriented.org/savinov/publicat/arxiv_1501_00720.pdf http://conceptoriented.org/savinov/publicat/arxiv_1501_00720... Just skimmed the 'Cross-Cutting Concerns' in your paper above. Isn't AOP far more general than what you propose there? Please correct any misunderstanding but per the parent based approach you describe -- "cross-cutting concerns are modularized in parent incoming methods and this functionality is injected in child methods" -- you would need to duplicate a CCC e.g. logging in each distinct 'parent'.
- asavinov 10y ago> Isn't AOP far more general than what you propose there? Yes, definitely AOP provides much more freedom in injecting behavior to other parts of the code - it is its main goal while COP has different goals. > you would need to duplicate a CCC e.g. logging in each distinct 'parent' No, because in COP, "Parents are Shared Parts of Objects" [1], that is, a parent may have many children. Inheritance in COP is inclusion. If a parent implements a method then it will be reused by all its children. [1] http://bibliography.selflanguage.org/_static/parents-shared-parts.pdf http://bibliography.selflanguage.org/_static/parents-shared-...
- wrongdog 10y agoI feel like I just read a lot of opinions by one frustrated dude without a real sense of why classes are bad (or even really why they frustrated him so much). Am I missing something?
- hguillermo 10y agoNo. You are right. Everything can be bad or good depending on how you use it.
- macintux 10y agoMost eye-opening moment in my software engineering class was when the professor asked, of four core OO features (don't recall the precise list now), which was superfluous. The answer, of course, was inheritance, and once the question was asked it wasn't hard to see how much better life could be without it. I've been on an anti-inheritance kick ever since. Now I see how much better life can be without OO entirely, but that's a different discussion.
- novembermike 10y agoEh, inheritance is a subset of composition. One of the issues is that the subset is ambiguous and different languages create a different contract for it, but there's nothing theoretically wrong with inheritance.
- marcosdumay 10y agoWhat do you use to implement interfaces then? Generic interfaces are the one single feature that made OO popular for GUI programming; what by its turn is the one application that made OO popular. And it's still the most powerful of the OO concepts (what is shame really).
- uryga 10y agoAre you referring to the fact that in Java interfaces are basically pure virtual classes? That always felt like an implementation detail to me. For example, both Go and Rust have interfaces without inheritance.
- marcosdumay 10y agoI'm referring to a pattern on OO languages where you specify an interface using a superclass¹, with hooks that you can specialize on subclasses, reusing most of the code on the superclass and keeping the code around it generic. Go interfaces have the part about keeping the code around it generic, but I don't think it gets the easy reuse of code by just writing the hooks. (But I can easily be wrong here - I'm not a proficient Go programmer.) In that, it looks very like Java's interfaces (the literal Interface thing). 1 - In Java you would not use a literal Interface for that, since you can't provide default code for the subclasses to extend.
- BuuQu9hu 10y agoThe E programming language, and its newer relatives like Monte, lack classes; instead, objects are defined by object literals and the extends keyword performs object composition by delegation.
- goatlover 10y agoYou mean it's prototypal, like Self, IO, Javascript?
- abecedarius 10y agoNo, it's similar to creating an object this way in ES6: function makeVector(x, y) { return { norm: () => Math.sqrt(x*x + y*y), // ... more methods ... }; } but frozen so that consumers can't change it except by calling a method. It's odd how this is the 'obvious' way to generalize lambda expressions from functions to objects, yet it's rare to see this style, and you always have to clarify that you're not talking about prototypes. (IIRC Emerald, mentioned in the paper, also works something like this.)
- usrusr 10y agoFunny how when the author finally arrives at the point where he intends to go from "unnecessary" to "bad", he has little more to say than "there is no space to repeat it here".
- antiquark 10y agoHilarious how he blatantly ignores the existence of C++. He talks about Smalltalk, Java, Grace, Emerald, Pharo... but no C++!
- pjmlp 10y agoMany academics love to ignore it.
- pdonis 10y agoNot a single line of code in the entire paper. Without that I have little or no idea what the author is talking about.
- asavinov 10y ago> "classes do not “model the real world”" Classes are supposed to model sets (of objects), that is, instances represent real objects and classes represent real sets of objects. So the question is whether sets are as real as the members they consist of. For example, if a set of chairs is a reality that we can comprehend and want to represent in the system. Yet, I think the problem is that we are probably not happy how classes model sets in OOP. They actually do not - and it is a major problem. (Classes in OOP are mostly templates for instantiating objects.) Also, we are not happy with how inheritance works and it also limits possible benefits of classes. But it is not a reason to say that classes per se are harmful. I would say that they are not as good as they could be :(
- jackmott 10y agoComputer science gets a lot of papers with arguments for a certain way of doing things. Very few with controlled experiments to find out if a way of doing things is better than another. Every time I mention this, people say that it is hard to do such experiments. Yes, it is hard to actually know things. while it is very easy to make plausible arguments, for almost anything.
- tonyplee 10y agoJust challenge the promoter to rewrite a c++ base program in their new favorite method, paradigm. For example, the author of this paper can try to rewrite the google chrome browser - a huge C++ project in the "non-Harmful" way.
- nine_k 10y agoRewriting is not very likely. A new development could use a new paradigm. Same applies to goto vs structured programming, plain procedures vs classes and OOP-style method dispatch, etc.
- deleted 10y ago[deleted]
- jimbokun 10y agoThis applies to you, too. What controlled experiments have you performed to test productivity differences of different methods of programming?
- khedoros1 10y agoJackmott didn't make a claim. The linked PDF did. Why should someone have to support a claim that they didn't make?
- dasfasf 10y agoJackmott is the one who introduced the standard of "controlled experiments". Why doesn't he propose an experiment design which will shed light on the question of whether classes are harmful or not?
- Koshkin 10y agoThe practical usefulness of classes in C++ comes not from an "object-orientedness" that they supposedly give the language. It comes from the fact that they are merely a mechanism that can be used to create abstract data types, thereby providing a better encapsulation, and do many other things, rather than a policy saying that every object must be an instance of a class. So, one has to be careful when talking about classes, because they may effectively mean different things in different programming languages, even though on the surface they may look similar or appear to serve the same purpose.
- a-nikolaev 10y agoThe fact that C++ offers classes for building abstractions, does not imply that classes are the best (or even a good) way to do that. Also, it does not mean that the particular C++ implementation of classes is any good.
- andrewflnr 10y agoIt's a good thing GP didn't imply any such thing, then.
- naasking 10y agoClasses tightly couple functions on types with the type declaration itself. It's often not even clear in which class certain methods belong. Better to separate data types from functions on data types the way it's done in functional languages, and if you still want object-oriented programming, you can support it like Ada does, or as syntactic sugar over the ordinary call syntax like some functional languages do.
- gertef 10y agoBetter why?
- wyager 10y agoSuperior composability with simpler semantics and sounder type systems. Class hierarchies are inherently unfriendly to strong, sound type systems. Interface composition isn't. Composing interfaces is clean and straightforward. Composing classes isn't, and you run into things like the diamond problem.
- neo2006 10y agoIMO language should be designed to be more effective, simpler or powerful, not to avoid programers to miss use them. All the "rules" about not using goto for example are legitimate but people forget that sometimes using goto could be a good practice in some languages. A semantic is just a tool you can miss used it`s programer issue not a language/semantic issue. OOP is a way to program among other we can argue that it's harder than another or easier but we can't say it's good or bad, it depend on how you use it and hwo effective you are using it.
- Clubber 10y agoAn adage I use is you should know all the rules so you know when and which to break.
- Sophistifunk 10y agoThe problem is that this requires rules to not actually be rules, but strong recommendations. Compilers are good at rules, less so with strong recommendations, which end up in static analysis tooling.
- Clubber 10y agoThe compiler is fine with using GOTO, it's people that are not.
- noblethrasher 10y agoAt least in the cases of C# and Java, classes and interfaces recapitulate a weak form of ML-style functional programming rather an impoverished version of Smalltalk-style object-oriented programming: “Inheritance” from a class corresponds to logical disjunction (and hence is equivalent to a sum type) and “implementation” of an interfaces corresponds to logical conjunction (and hence corresponds to product types). The visitor pattern is a verbose form of pattern matching. You can recover the strong form of ML-style FP (albeit without the nice type inference) if you limit inheritance to abstract classes (thus, all classes are sealed/final or abstract), mark all fields as readonly/final, and use interfaces for destructuring (which addresses problems 1,2 and 3 under the “Alternatives” section). As an aside, one of the big issues with “classical” OOP is that it enjoins the programmer to create phenomena using logic (i.e. wizardry) rather than of using math to model a system (i.e. science and engineering). Among other problems, this leads to designs that break symmetry (e.g. if modeling a bucket brigade, the perspective of many humans passing by a single bucket should be just as valid and available as the “natural” perspective of many buckets passing by a single human). Of course, appeals to symmetry is question begging, and I don’t have time to litigate that here, but it sure seems like symmetry is key to building scalable systems (where scalability means not just number of users, but also things like number of edits to a codebase). In summary: Classical OOP seems to require that you either have a prior (well-designed and debugged) model against which you can program, or really, really good taste.
- cousin_it 10y agoI can buy a language without classes if it gives me these things: * Interfaces * Records * Abstract data types * All the above should use foo.bar() syntax Classes provide those things, which is good, but also provide implementation inheritance, which is bad.
- biocomputation 10y ago>> but also provide implementation inheritance, which is bad. Inheritance isn't bad. Abusing inheritance is bad. For the record, you can also abuse composition, polymorphism, operator overloading, free functions, interfaces, records, and abstract data types. I've abused them all and seen them abused as well. Inheritance is just another tool. Like all tools, we are expected to use them wisely.
- deleted 10y ago[deleted]
- cousin_it 10y agoDo you know any situations where implementation inheritance is the best tool?
- biocomputation 10y agoYeah, inheritance is the best tool when I want a derived class to implement all the behavior of the super class.
- mjevans 10y agoI mentioned one such example about 6 hours before your post. As the other reply stated, when you mostly want to keep the base class but over-ride a small specific subset of what it does. E.G. The base class uses class member functions to do save/load records from a store. You want to implement a variant of that class which instead works well with a database engine you like. You can then derive a class and define JUST the storage and recall functions, and inherit everything else.
- lacampbell 10y agoThe paper was a good read. I was kind of dreading it'd be another tired rehash of attacking straw men from someone who thinks having used Java or C++ makes them expert on OOP. In the early history of smalltalk Alan Kay talks about how he was never entirely satisfied with inheritance, and having inheritance in the language (quoting in full, hard to link to): A word about inheritance. Simula-I had neither classes as objects nor inheritance. Simula-67 added the latter as a generalization to the ALGOL-60 <block> structure. This was a great idea. But it did have some drawbacks: minor ones like name clashes in multiple threaded lists (no one uses threaded lists anymore), and major ones like rigidity in the extended type structures, need to qualify types, only a single path of inheritance, and difficulty in adapting to an interactive development system with incremental compiling and other needs for instant changes. Then there were a host of problems that were really outside the scope of Simula's goals: having to do with various kinds of modeling and inferencing that were of interest in the world of artificial intelligence. For example, not all useful questions could be answered by following a static chain. Some of them required a kind of "inheritance" or "inferencing" through dynamically bound "parts" (i.e. instance variables). Multiple inheritance also looked important but the corresponding possible clashes between methods of the same name in different superclasses looked difficult to handle, and so forth. On the other hand, since things can be done with a dynamic language that are difficult with a statically compiled one, I just decided to leave inheritance out as a feature in Smalltalk-72, knowing that we could simulate it back using Smalltalk's LISPlike flexibility. The biggest contributor to these AI ideas was Larry Tesler who used what is now called "slot inheritance" extensively in his various versions of early desktop publishing systems. Nowadays, this would be called a "delegation-style" inheritance scheme [Liberman 84]. Danny Bobrow and Terry Winograd during this period were designing a "frame-based" AI language called KRL which was "object-oriented" and I believe was influenced by early Smalltalk. It had a kind of multiple inheritance—called perspectives—which permitted an object to play multiple roles in a very clean way. Many of these ideas a few years later went into PIE, an interesting extension of Smalltalk to networks and higher level descriptions by Ira Goldstein and Bobrow [Goldstein & Bobrow 1980]. By the time Smalltalk-76 came along, Dan Ingalls had come up with a scheme that was Simula-like in its semantics but could be incrementally changed on the fly to be in accord with our goals of close interaction. I was not completely thrilled with it because it seemed that we needed a better theory about inheritance entirely (and still do). For example, inheritance and instancing (which is a kind of inheritance) muddles both pragmatics (such as factoring code to save space) and semantics (used for way too many tasks such as: specialization, generalization, speciation, etc.) Alan Borning employed a multiple inheritance scheme in Thinglab [Borning 1977] which was implemented in Smalltalk-76. But no comprehensive and clean multiple inheritance scheme appeared that was compelling enough to surmount Dan's original Simula-like design.
- codr4life 10y ago"I find OOP methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms - you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work." A. Stepanov (http://www.stlport.org/resources/StepanovUSA.html http://www.stlport.org/resources/StepanovUSA.html)
- keithnz 10y agoI think this is more based on the early methodology advice for developing OO software. But the methodology is independent of the constructs (though often limited by it). In practice these days often the most effective way when developing OO code is working the "proofs" till you have a set of classes. Also, some people go for very FP inspired OO code.
- codr4life 10y agoThose are clearly exceptions to the rule, though. You can write sort of Haskell in any language, OOP is still bullshit.
- romwell 10y agoAs a side note, this is a very true statement about mathematics, which, unfortunately, doesn't hold for a plethora of texts (from elementary to the graduate level) which do, in fact, start with axioms. To that end, even starting with definitions is often harmful when the definitions themselves are so often tailored to make a particular proof work, and make no sense without such context.
- scriptkiddy 10y agoI write most of my code in Python. I think that's give me a leg to stand on when it comes to discussing OOP. I find that classes, if nothing else, are a fantastic way to namespace data and methods that operate on said data. For instance, if I have a chair object, I could use a class to describe the chair. I could store the materials it's made out of, the height of the seat, whether it is an office chair, a barstool, or something else. I could also write methods that can say, price the chair based on data about the chair. In this particular case, I wouldn't subclass the chair at all. There's no point. Every time I need a chair, I would just create a new instance of Chair. That's why chair is an object. It's a self contained thing that I can pass around and pull data out of or mutate. I don't really use deep inheritance at all in my code. I think the deepest I've ever subclassed something is once. I find inheritance to be useful if I need to be able to create multiple objects that deal with very different things, but perform similar operations on them. A good example of this is Django class based views(it's own controversial topic). I created my own resource class to use for handling API specific requests. The methods of pulling filters out of the query string and serializing database objects are exactly the same for every single request, but the objects that these classes operate on are vastly different. Therefore, I need to specify a serialization schema for each database object type, but I don't necessarily need to rewrite the function that does the serialization. I use my Resource class in order to more easily re-use these generic methods. Just my two cents.
- kazinator 10y agoPaper neglects to discuss CLOS approach: generic functions instead of methods, etc. The claim that classes don't do object creation because some operator like "new" actually does that is jaw-droppingly stupid.
- non_repro_blue 10y agoThe meme is becoming lame. Talentless developers who fight and argue are the only real hazard in the world of programming. Mature trends and languages have attracted decades of developers good and bad, and because they're widely used, they have the misfortune of also providing a home to the largest corpus of terrible code. Mark my words: in a generation, functional programming will accumulate just as much garbage, inadequately programmed by just as many careless and/or passive-aggressive developers desperately clinging to their jobs throughout the next wave of whatever becomes the next Steve Ballmer stack ranking code review process. It doesn't matter how many words or ideas you throw at this circumstance. Terrible developers will still manage to commit garbage. Life finds a way.
- jaredklewis 10y agoI feel this counter meme (programming languages/language features/paradigms aren't bad, developers are) also get's thrown around a lot, but I don't understand the argument. Are all languages really equally good? Is C really no more productive than assembly? Is Swift really no more productive than Objective-C? For many higher level applications is Java really no more productive than C? Doesn't using something higher level like Python make certain kinds of tasks easier than the same task in Java? Since the inception of programming languages, there has been continuous improvement of the existing languages as well creation of new languages, both of which have introduced new paradigms and features to programming. These new features and paradigms often replace older features and paradigms. Not everything works, but much of the time the new features and paradigms have made writing and maintaining good programs much easier. Unless you believe our current tools are already completely optimal, it seems only natural to try to improve upon them. So is your argument that programming languages in a generation will be equal productive/un-productive as what we have now? That seems too pessimistic to me. I think our tools will be much better, just as I feel our tools now are better than they were in 2000 or 1990. If the argument is that functional programming is not an improvement, that's fine, how do you see languages improving? What's the direction they should take?
- non_repro_blue 10y agoTuring tarpits aside, people speak very highly of C, just as they may do the same for assembly, but depending on context. Languages fill a niche, and outside of their area of utility it's easy to notice weaknesses. But arguments in favor of functions are similar to those in favor of objects. They both joust for the award of being adept at doing more with less code, in terms of mythical-man-month project scalability. I've experienced that problem with huge OOP code trees, and I still don't foresee Pure Functional programming supplying a cure for that problem. Maybe I'm just not one of the lucky ones yet. I don't know. But when I read Pure Functional code, even though it's tighter, with less boiler plate, it doesn't feel like honest improvement. It's like Coke or Pepsi, McDonalds or Burger King. OOP might yeild thousands of source files and hundreds of lines per some files, but if a Pure Functional project does the same thing with fewer lines of code in fewer files, it's still doing the same thing. So in a decade you'll probably find the same complaints, in the same places, but at least people will have different hair styles.
- keithnz 10y agoso, the argument is it's harmful because it's a premature optimization? the evidence being simply alternatives to classes? It seems like the paper doesn't present a good case for why classes are harmful. Seems the whole premise if flawed based on a glib quote from Knuth Premature optimization ( if that is what classes are ) doesn't mean the optimization is harmful. It could actually be really good. The quote means, when you find some evil, and track it back, you'd find premature optimization. You can also find awesome code, track it back, and also find premature optimization. So, you need to prove classes are evil, and then track it back to premature optimization. This paper fails to do that and therefore fails to make the case for harm
- MarcusBrutus 10y agoEven in OO languages (such as Java and C#) people are routinely advised to favor composition over inheritance whenever given half a chance. Classes definitely smell (or rather reek) of the infamous 90s that inflicted such atrocities on humanity as the Rational Rose "products" and the UML "methodologies". It also goes to show why the "typescript" Microsoft strategy is ill thought. Unless of course it's simply (as I think it is) the Mother of all Embrace Extend Extinguish strategies in which case it is very cleverly thought. Sadly ECMAScript has also jumped on the OO bandwagon by offering "classes" syntactic sugar but at least it is left to the developer to use it or not, whereas in the Microsoft-land of "typescript" you get classes rammed down your throat.
- ap22213 10y agoWhat is the point of these types of arguments and opinions if they don't have any evidence to back them? I don't give a shit if it's functional or object-oriented or procedural or whatever comes next. I just want a language that is proven, via empirical evidence and reproducibility, to solve my particular use case better than any others. And, given all the use cases I have, I'd be amazed if one class of language can do it all. I'm guessing it's impossible. It's way better for my engineering team to know how to use a bunch of different specialized tools, and how to use them together, than to focus on one type of tool.
- chowells 10y agoThe biggest problem with classes is that they conflate two different concepts in a way that limits reusability. When you have classes, you have subclassing, and subclassing means two different things at the same time. First, subclasses are the subtyping operation. If you want type B to be a subtype of A, B must subclass A. Second, they provide code reuse via inheritance. Each of those things is useful, but there's no reason to tie them together. In fact, modern best practices in OO say to favor interfaces and delegation over subclassing, and that's precisely because it separates those two concerns. As far as I can tell, this is what the paper was getting at - separating delegation of implementation from subtyping. Since this is already what OO best practices suggest, why is it controversial?
- sytelus 10y agoAmount of boilerplate one needs to implement "good" OO design is just horrendous. For example, in C++, previously we had rule of 3. Now its rule of 5! Just having a virtual abstract interface means almost half dozen lines of boilerplate! Even in managed languages such as C# or Java, it would require significant effort to create, say, read-only version of collection given a read-write collection. One of the goal for language design should be to eliminate all these forced boiler plate. It is definitely the time for new paradigm in language design. However I'm not sure how the "delegates" would solve this which is proposed alternative in this paper.
- pakl 10y agoI believe Objective C's @property declarations brings some level of what you describe to C/C++. They generate the boilerplate for you. E.g., @property (readonly) NSString* myName;
- bjourne 10y agoI like Factors (http://factorcode.org/ http://factorcode.org/) approach to classes. In that language, a class is a category and not a "mold" from which objects are created. E.g, I can say the following: 33 number? t 33 integer? t integer number class<= t number object class<= t The last two lines demonstrates a little of the class algebra possible. It says that if an object is an instance of the integer class, then it also an instance of the number class and of the object class. That is, the set of objects that are integers is a subset of the set of objects that are numbers which is a subset of all objects. I can add new classes which refines categories of existing objects: PREDICATE: positive < number 0 > ; PREDICATE: prime-number < integer prime? ; 17 positive? t 17 prime-number? t 13.4 positive? t Note that both real and integer values can be "positive" which means that "positive" isn't a strict subset of either class. That kind of refinement isn't possible in most oo languages.
- neo2006 10y agoIMO language should be designed to be more effective, simpler or powerful, not to avoid programers to miss use them. All the "rules" about not using goto for example are legitimate but people forget that sometimes using goto could be a good practice in some languages. A semantic is just a tool you can miss used it`s programer issue not a language/semantic issue. OOP is a way to program among other we can argue that it's harder than another or easier but we can't say it's good or bad, it depend on how you use it and hwo effective you are using it.