11 ms·
Becoming a professional Haskell and Erlang developer really shifted my view on OOP (let OOP denote class based OOP as found in Java or C++). In my view, OOP is
by ilovecaching 8y ago
Becoming a professional Haskell and Erlang developer really shifted my view on OOP (let OOP denote class based OOP as found in Java or C++). In my view, OOP is prove a poor model for computation, and the result has been that OO code is almost always significantly more complex and error prone than an equivalent computation written in a concurrent, functional, or structured paradigm. Recent trends in language design (see Rust, Go, Elixir) also seem to be abandoning OOP in favor of other models as well.
OOP provides competing ways of abstracting behavior that in Haskell we can model with type parameters and constraints. Objects are not truly encapsulated in the way Erlang processes are and a poor fit for SMP. Objects also pathologically hide data in attempt to manage mutability, making it impossible to reason about the memory layout of the program.
All in all, OOP is a toolkit for building bad abstractions: abstractions that do not easily model computation, that hide data, and has tended to create overly complex solutions to problems that are often full of errors that a language focused more on type expressivity could catch at compile time.
- Chabs 8y agoI think you are conflating OOP with type erasure. Most OOP languages support type erasure (including rust!), but that's far from all there is to it.
- ilovecaching 8y agoHow so? I believe I was addressing the fundamentals of OOP: Classes, methods, inheritance, overloading, visibility, etc. Also, Rust, while allowing the assigning of behavior to a type, is explicitly not OOP. Check it's Wikipedia page (which doesn't include OOP in the list of paradigms) and the O'Reilly book (which says Rust isn't OOP).
- Chabs 8y agoI didn't mean rust was fundamentally OOP, but that rust implements, through runtime traits, exactly the behavior you are criticizing OOP for. Sorry about that
- ilovecaching 8y agoCan you please point out exactly what I said when you say 'the behavior I'm criticizing OOP for'. Haskell typeclasses are very different from OOP inheritance or OOP classes. In any case, I don't see how that relates to the explicit criticisms I made.
- Chabs 8y ago> All in all, OOP is a toolkit for building bad abstractions: abstractions that do not easily model computation, that hide data. That's a fundamental property of type erasure, which is not exclusive to OOP, and far from the extent of what modern OOP is about
- deleted 8y ago[deleted]
- ilovecaching 8y agoI don't think you understand what type erasure is.
- deleted 8y ago[deleted]
- Aloisius 8y agoUnder the original definition of OOP as various alternate definitions, Rust would be OOP. This is all covered here: https://doc.rust-lang.org/book/second-edition/ch17-00-oop.html https://doc.rust-lang.org/book/second-edition/ch17-00-oop.ht... Personally, I think the idea that code isn't OOP just because you don't use inheritance to be utterly ridiculous.
- ilovecaching 8y agoExcept that Rust lacks almost all of the features and terminology you'd expect of an OOP language. Again, I take OOP to mean what one learns in school... A class based language with inheritance, overloading, visibility of members, constructors, etc. Rust can define behavior on any type of data, including scalar values. There is no concept of a "class" and constructors and simple functions that return instantiated values. They are not automatically called when a value is instantiated. Traits are more like interfaces, they constrain an implementer. A value has no way of inheriting behavior. Visibility is at the package level, and Rust offers no notion of encapsulation inside of a package. Rust is, by the trending definition of OOP, not OOP.
- derefr 8y ago> Again, I take OOP to mean what one learns in school Don't do that, then. "OOP" is a term-of-art in an academic discipline. It means exactly what it was used to mean by the people who coined the term in the papers they coined it in. The thing that schools teach under the name "OOP" is a https://en.wikipedia.org/wiki/Lie-to-children https://en.wikipedia.org/wiki/Lie-to-children intended to introduce something vaguely like OOP, not to introduce OOP itself. --- And, before you ask: no, there is no academic jargon term for "the thing that C++ and Java are." From an academic perspective, neither language has any particular unifying semantics. They're both just C with more syntax. OOP is a different set of semantics, based around closures (objects) with mutable free variables (encapsulated state), where an object's behavior is part of its state. C++ and Java can simulate this—you might call this the Strategy pattern—but if you build a whole system out of these, then you've effectively built an Abstract Machine for an actually Object-Oriented language, one that ends up being rather incompatible with the runtime it's sitting on top of.
- joering2 8y agoSomeone with 15 years programming OOP told me once: here is the best way to describe object oriented programming: you asked for object “monkey”, and you got the whole jungle, as well as monkey’s bananas.
- walterstucco 8y agoYou're quoting Joe Armstrong, creator of Erlang > Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.
- panax 8y agoSteve said it too, but he said it like he was proud of it: https://www.youtube.com/watch?v=Gk-9Fd2mEnI&feature=youtu.be&t=27m55s https://www.youtube.com/watch?v=Gk-9Fd2mEnI&feature=youtu.be... "You need all the objects that come with it to make it work"
- ilovecaching 8y agoExactly, you get a tangle of objects and data that's impossible to reason about, and isn't made explicit in the types.
- mehrdadn 8y agoI don't really follow this. A fleshed-out example describing the trade-offs is almost mandatory for this kind of criticism since this could be very easily due to a misunderstanding or misapplication of OOP rather than a problem with it.
- kirkules 8y agoI don't have enough experience to agree or disagree with the quote you're responding to, but I think the intent was in part to claim that OOP gets misapplied enough that if you're working with a large enough group or company, that's what you'll end up with.
- arendtio 8y ago> my view on OOP (let OOP denote class based OOP as found in Java or C++) Maybe you should take a look at a real OOP language like Smalltalk before you tell us why OOP is a bad idea. Otherwise, I might tell you why consumers will never adopt cars as I drove a Trabant once.
- ilovecaching 8y agoSmalltalk OOP looks almost exactly like Erlang gen_servers and shares a lot of nice properties with them. Unfortunately the concept has been twisted into it's current day meaning that's akin to the OOP we find in Java, C++ etc.
- deleted 8y ago[deleted]
- crackerbarrmnd 8y agoSmalltalk is not an especially impressive language in 2018 and inspection and reflection aren't isolated to OOP today either.
- mercer 8y agoDid you read the stuff between the parentheses?
- arendtio 8y agoIn fact, I did. But I think it is wrong to judge OOP based on crude implementations. That is the reason why I added the Trabant example: > The Trabant was loud, slow, poorly designed, badly built, inhospitable to drive, uncomfortable, confusing and inconvenient. (source: https://en.wikipedia.org/wiki/Trabant https://en.wikipedia.org/wiki/Trabant) Java and C++ are both great tools for specific jobs, but from an OOP perspective, they are badly designed. So if you want to discuss OOP as a design choice, it would be unreasonable to discuss it based on those poor implementations. Smalltalk, on the other hand, has its own set of problems, but a poor OOP implementation is not part of it.
- jshowa1 8y agoA poor model for computation that is pervasive in the industry. Poor models usually don't become pervasive.
- michaericalribo 8y agohttps://en.wikipedia.org/wiki/Argumentum_ad_populum https://en.wikipedia.org/wiki/Argumentum_ad_populum
- ilovecaching 8y agoCan you give an argument why it's a good model?
- dataflow 8y agoIn your top-level comment you argued it's a bad model and didn't really give an explanation for why. You just make assertions that things are pathological/overly-complex/error-prone in OOP and that other alternatives are better, that it's impossible to reason about memory layout, etc. But I could just as easily assert the opposite is true: that proper OOP does simplify problems down to manageable parts, that encapsulation is what you're supposed to do in proper OOP, that abstracting away memory layout is a good thing, etc... I'm not sure if you find these compelling or not, but if not, then I guess you could see why others feel similarly about your arguments.
- eecc 8y agoIMHO OOP was a part of the big Software Factory model: a relatively simple, quick to understand tool to onboard masses of superficially trained workforce. A few enlightened Architects and Leaders would paint large strokes of class, collaboration, sequence diagrams while hundreds of "coders" would translate these "visions" into shippable artifacts. You know how well that ended... ;) ... oh, and watch out for Go! ducks
- sidlls 8y agoThe engineering organization where I work is full of dysfunction. This is because numerous poor practices were ignored or encouraged over the years. Now there is strong inertia against change because the incompetent long-timers know all the tricks and manage their job security through the system as it is. This is not uncommon especially in the Bay Area.
- fooyc 8y agoIt looks like that you are working on stuff that may not benefit from OOP. You seem to be doing heavy « computations », you care more about the data than the logic around it. Probably Haskell suits your usecases more.
- ilovecaching 8y agoActually I work primarily on web services. We benefit from Haskell in that HKTs allow us to model our service completely in the type system. Our Rest and GraphQL API are completely modeled in a type level DSL. Once we've ingested data, which can then be validated automatically using types, we can then express our data transformation in a way that makes the transitions extremely transparent in our code. Our backend services are written in Rust for things that need efficient computation.
- codetrotter 8y agoThat sounds very interesting. Did you open source any parts of your code, write any blog posts about it or give any public talks about it? I would love to read/watch whatever you have available to the public :)
- westoncb 8y agoI do think this echoes fooyc's point though: this does not sound like an area that would benefit from OOP. Sounds like an ideal use-case for functional.
- ww520 8y agoSounds like the service in your case is a sessionless gateway that does data transformation and dispatching. It fits the functional style.
- fooyc 8y agoLooks like functional programming sweet spot: data transformation.
- Consultant32452 8y agoMy personal anecdotal experience is that OOP lends itself well to very very large codebases. A language like java with packaging, classes, and encapsulation strongly encourages some meaningful organization. Even if that organization is implemented poorly by the user, it's better than what I have seen users create in the real world with languages like C. If you have a project where a single person could reasonably understand all the components then maybe OOP is overkill. I also recognize others may have had an equal and opposite experience.
- ilovecaching 8y agoHave you tried something with typeclasses, ADTs, or some form of interfaces? C really doesn't provide any tools to make abstractions and lacks the basics, like namespaces. My experience with OOP is that it generally drives people to very large codebases that are hard to reason about at scale. Usually it brings in a framework of some sort to manage the complexity of wiring objects together in a manageable way. For example, Java Spring uses annotations to magically wire objects together.
- deleted 8y ago[deleted]
- josephg 8y agoI was a programming teacher some years ago and I would sometimes grade two submissions, which had both gotten full marks from the automated tests but where one was 150 loc and the other 500 loc. The most surprising part was that if I read the longer submission first, it would never really seem like there was that much excess code to take away. But obviously there was. > My personal anecdotal experience is that OOP lends itself well to very very large codebases. In my experience Java / C++ style OOP creates very very large codebases in the same way. I think its quite surprising that many engineers don't seem to have any idea how much waste there is in their "clean" java code. (Or C++ that follows the same style). I also almost always find it far easier to read dataflow oriented code or functional code compared to their OO counterparts because all the state transitions are made absolutely clear. In OOP, your system state is spread across every file in the project. Compare to, say, a website implemented using React/Redux. I can inspect a single object to see the entire state of the application. When there's a bug, usually either that object has the wrong value (so I know how to fix it). Or the object has the right value and the bug is in the rendered component. Easy peasy. In comparison, in a java program the bugs often show up between classes. They end up relating to the relative timing of function calls that mutate state. Or the lifecycle of objects conflicting in weird ways. Its much worse for comprehension and much more work to debug. (And yes, I've spent years working in both styles professionally.)
- westoncb 8y agoFor some reason 'arguments' against OOP seem to follow a common pattern. You have said many things against OOP, but you haven't actually presented an argument for why it's bad. I'll present each of your assertions here individually to clarify. > OOP is prove a poor model for computation > OO code is almost always significantly more complex and error prone than an equivalent computation written in a concurrent, functional, or structured paradigm. These claims may or may not be true, but they aren't very useful at all if you don't provide a justification as well as merely asserting them. > Recent trends in language design (see Rust, Go, Elixir) also seem to be abandoning OOP in favor of other models There are a number of ways to account for these trends besides OOP being an intrinsically bad model. The most obvious one is that there are fashions in language design, and right now OOP is not fashionable. We already know that; it's not a strong argument against it. Ironically, many in the OOP opposition use the same argument to justify OOP every getting popular in the first place: "it was just fashionable." > OOP provides competing ways of abstracting behavior that in Haskell we can model with type parameters and constraints. > Objects are not truly encapsulated in the way Erlang processes are and a poor fit for SMP. You have pointed out here that more classical OOP languages do things differently from Haskell and Erlang. This should be expected and is not an argument against those OOP languages. (Yes, you could say, "Erlang is better at concurrency" because of the way in which it's different—but my understanding is it's pretty well accepted that Erlang is sort of freak of nature here, so it's not a good argument against OOP generally.) > Objects also pathologically hide data in attempt to manage mutability, making it impossible to reason about the memory layout of the program. They do hide data, but the 'pathologically' is something you've added on your own. There is a design philosophy in which this data hiding plays an important, positive role. When you say, "making it impossible to reason about the memory layout of the program." —this sounds to me like missing the point of that design philosophy: the purpose (and oftentimes tradeoff) of higher-level languages is that you don't need to personally manage these details. I think it's largely an application-dependent thing: you many be writing code that requires that, but not all interesting software hinges on low-level performance tuning. > OOP is a toolkit for building bad abstractions: > ... abstractions that do not easily model computation > ... that hide data > ... and has tended to create overly complex solutions to problems that are often full of errors that a language focused more on type expressivity could catch at compile time. Another collection of unjustified assertions, except the 'hide data' part which I accounted for earlier. So across ~10 negative assertions about OOP you have 3 quasi-justifications: newer languages aren't using OOP as much, hiding data is bad, and Erlang is better for SMP.
- shady-lady 8y ago> Becoming a professional Haskell and Erlang developer really shifted my view on OOP (let OOP denote class based OOP as found in Java or C++). Did you have many years experience with Java/C++ beforehand?
- ilovecaching 8y agoI started as a C++/Python developer. I learned C++ and Python in school, and wasn't exposed to Haskell or Erlang until later in my career. I've also professionally written Ruby, Java (Swing/Spring), Rust, and Go.
- ilovecaching 8y agoAlso for those of you doing OOP looking to try something different: Java/C++ -> Rust: It will feel familiar to you with its C style syntax and multi-statement function bodies. It takes the best parts of many different paradigms, and marries them in a very coherent way. It's performant, has incredible tooling (cargo, rustup), and the community is great. Python/Ruby -> Elixir: Elixir has the Phoenix framework, great support for web, and supports massive concurrency using the Actor model. Jose did a great job cleaning up the Erlang syntax, and it's gradual typing and heavy use of macros will feel immediately familiar to you.
- AsyncAwait 8y agoGo also has a non class-based OO.
- blub 8y agoYou develop web services professionally in Haskell, Erlang and Rust, but you think that Java-style OOP is too complex?
- ilovecaching 8y agoYes
- kroltan 8y agoI don't think it is the case that a certain programming paradigm can be intrinsically harder, maybe only less practiced. OOP / imperative style is almost the norm nowadays, but that doesn't imply it's the "easiest", just the one that got the most momentum (which can be attributed to social factors moreso than technical ones), and thus is widely taught and talked about, which helps with education on such style.
- zumu 8y agoAre you hiring? Where are these mythical FP jobs?
- n0n 8y agoInteresting view. How should i, as a sysadmin who just writes bash and powershell scripts, start to learn _serious_ programming? Is it still worth to force myself into OOP?
- 1ark 8y agoStart writing some of the scripts in Python, for example, quite popular in both sysadmin world and _serious_ programming world.
- blub 8y agoIf you want to get a job, yes. The world is built on OOP, it's just that too many like to use it as a punching bag.
- BobFromDown 8y ago10/10
- amirouche 8y agofunction are in the gray area in Python. I argue that you should start simple with functions and IF you see a use case for classes use them. To be able to make a reasonable choice, you must learn OOP at least the OOP machinery of your language. A few hints: a) Python's abc or Java Interfaces serves as template to implement multiple times the same behavior in different contexts b) If you don't inhirit the class, the class is useless, except if you use the class as an interface (see a) c) A class is more complex than a function ie. more guns to shot yourself in the foot. d) think function pointer / first-class function. Many times, you can avoid a class by passing a function as parameter e.g. filter. e) think function factory ie. a function that returns a function. f) think pure function / side effect free functions. This is a BIG life savior. A function without side effects is much simpler to test that a function with side effects. Of course, you can not avoid all side effects (io et al.) or mutations, so build your abstraction so that the side-effects / mutation to happen in a well known place. g) keep functions small
- stuaxo 8y agoI haven't done erlang or haskel, but this sums up what I've been thinking / trying to get around for years.
- cryptica 8y agoI don't understand what the problem with OOP is. My OOP code has always been clean and easy for myself and other people to read and modify. When I read articles complaining about OOP, I just can't relate at all. The idea of functional programming makes no sense to me except for writing very specific simple programs. For example, I like using some functional programming on the front end with VueJS but even there, I still allow mutations in certain parts of the code. I like being able to store state in different instances and allow it to be mutated independently of each other. I like it when related logic and state is kept close together in the code; it makes it easy to reason about different parts of the code independently. On the other hand, with functional programming, it can be difficult to figure out where state comes from because there is very little abstraction to separate different parts of the code.
- kamaal 8y ago>>When I read articles complaining about OOP, I just can't relate at all. Most problems start with OOP when people try to take the longest possible path to achieve a goal. Enterprisey code, like having to deal with thousands of classes(AbstractClassFactoryFactorySingletonDispatcherFacadeInitializer types), dependency injection, design pattern abuse. Then on top of this comes things like Spring framework etc. At that point in time you have like two problems to deal with, one is the problem itself, and second is the complexity of the language. This phenomenon has remained in the OOP world, almost forever. Things like maven have helped a little. But complexity hell has been the mainstay of OOP world for almost decades now. Sure you can write very readable OOP code. Every time I do that I see great discomfort on the face of Java programmers during code reviews. For example over all this years, I haven't met a single Java programmer who could explain why Beans are good, or even needed. So you have these religious rituals Java programmers do. They feel like their job protection scheme is at risk.
- vbsteven 8y agoI feel like this comment is exactly what the article refers to as the typical straw-man argument against OOP. Yes, a lot of bad enterprisey OOP code has been written in the last 20 or so years, but that does not mean things like design patterns, dependency injection and the Spring framework don't have their place. Don't throw the baby out with the bath water. Yes, AbstractClassFactorySingletonWhatever classes do exist in the Spring framework, they are there to help abstract away the complexity and flexibility of the framework so you as the application programmer can have a simple, productive programming environment, and you can still reach into the complexity (and extend it) when you need to. Beans, interface inheritance, implementation inheritance and dependency injection are the building blocks of a programming environment that allows me to be very productive, and still write maintainable, testable, extendable and configurable code.