5 ms·
Just don't make the mistake of studying FP first... I can't seem to wrap my head around OOP. There's too many concepts in OOP. In FP it's just data and functio
by cpursley 4y ago
Just don't make the mistake of studying FP first...
I can't seem to wrap my head around OOP. There's too many concepts in OOP. In FP it's just data and functions for transforming that data.
- bitL 4y agoCan you explain monads to a 5-year old? Can you explain objects?
- mdcds 4y agoI heard following explanation of monads somewhere online: "monads allow us to write imperative code in the functional setting. e.i. chain computations". But that explanation wouldn't make sense to a 5-year-old
- solomonb 4y agoI don't think that is a fair comparison. Monad is a typeclass so it would be like explaining some specific Java Interface (and all the context for Interfaces) to a 5 year old. The Haskell (since you brought up Monads) equivalent to explaining Objects would be like explaining Records or Sum types, which would be very easy to explain and don't require talking about inheritance like Objects would.
- freedomben 4y agoI don't know if you're being serious or not, but you can learn a ton of FP without having to understand monads. Also asking to explain "objects" is too ambiguous. an "object" in json is very simple. OOP on the other hand involves a mountain of different concepts, design patterns, best practices, etc. I would guess GP is referring to that stuff.
- LudwigNagasena 4y agoYou can learn a ton of OOP without having to dive into a mountain of different concepts too.
- yawaramin 4y agoYou can learn a ton of FP without having to dive into a mountain of different concepts too.
- pmontra 4y agoYou can write OOP code without knowing a single pattern and whilst laughing at Factory classes you read in someone else's code. You might have to reinvent the wheel sometimes and face some difficulties talking with people that know every single pattern. And there are best practices for every single language and paradigm.
- peoplefromibiza 4y agomonads are a very simple pattern it takes 5 minutes to understand it, the jargon is complex, the implementation is not. case in point https://youtu.be/C2w45qRc3aU https://youtu.be/C2w45qRc3aU objects are a very leaky abstraction that usually brings people to build taxonomies, mostly unrelated to the parent. reuse of code, which is the selling point of OOP,also comes often short with a miriad of very specialized subclasses that have nothing in common anymore. OOP is not horrible, but it requires a good amount of discipline to get it right, while FP has less concepts and you can (usually) silo the "and now for the tricky bits" (cit. Robert Virding) in a small core. the rest is simple pure functions that have also the benefit of being stupid trivial to test. Also, you don't have to be purely functional nowadays, and that helps a lot. If only I learned FP sooner, my life as a programmer would have been so much better.
- freedomben 4y agoYou're point about testability is a good one that I feel is often missed. Trying to test functions in OOP code is often impossible because they presuppose some state in the "object" and if it's not initialized properly, it doesn't work. Then they also often make side effects. So you end up building a huge test harness to build up some state, run one test, and tear it all back down again only to rebuild it from scratch for the next test. It's doable of course, but it's easy for a simple CRUD app to have a 15 minute test suite and for tests to become flaky because of some unexpected state change done in some unrelated test on the other side of the code base. That's a special form of hell
- goostavos 4y agoMonads are indeed way simpler. Just a few beautiful laws. The problem is that they take a loooooooooooong time to really internalize. Saying it takes "5 minutes" is empty in the same way that "learn C++ in 24 hours" claims are (or you're hella smart!). There's a quote that floats around that's like "as soon as you understand monads, you lose the ability to explain monads." It takes a ton of leg work to make them click. They're simpler, but definitely not easy (in the Rich Hickey sense).
- 4y ago
- unsafecast 4y agoYes, I can definitely explain monads to a 5-year old. See, a monad is like a box. You can put something in the box and close it very easily. But once it's closed, you can't open it anymore. The action of closing the box is called the wrap operation. What you _can_ do though, is tell someone else to do something to the thing inside the box. For example, if you put a toy in and close the box, you can ask a friend to go ahead and add a new one in. Or remove the toy. These are monadic functions. That's it. That's literally it. It's just a pattern of hiding the data and letting monadic functions be the only ones that deal with it. In the case of the Maybe monad for example, you'd have the unwrap function that tries to get whatever is inside out, but it might not be able to (if the box is empty).
- taeric 4y agoNot going to lie, I don't understand that explanation. It honestly sounds more like you are describing a form of encapsulation, as the contents of the box are hidden and someone else has the ability to open said box to get access to it. I also find the appeal to a physical object to explain a functional concept is rather amusing.
- solomonb 4y agoNot sure if you are looking for an explanation of Monads, but Monad tutorials are a long running joke in the haskell world. They are almost exclusively written by people for whom the concept just clicked and they either fail provide context for someone without that experience or they fail to actually describe the concept correctly. I'm not gonna give you an explanation but I will say that IMO the best way to actually learn about them is to just look at the typeclass and a bunch of instances of it and how they are used. If you ignore all the theory (and the "theory") and just look at the code you will find that they aren't that hard to sort out from a usage perspective.
- taeric 4y agoApologies, I seem to have deleted a sentence where I think I can make my understanding fit that metaphor. I don't think they are completely unapproachable, but I am not at all clear that a physical metaphor works. And, I really wanted to shine a light on the amusing appeal to physical objects in a thread that is about the short comings of object oriented programming. :D
- mejutoco 4y agoI’ll try. A monad is a description of actions to do and their order, in place of the actual actions. This description can be passed around and eventually acted upon. Objects (not Alan Kay’s original ones but say Java) are abstractions that model state and behaviour together. Objects can share common behaviour through interfaces
- justinhj 4y agoSome functions return plain values. Other functions return fancy values with the plain values inside. There are different types of fanciness. One simple kind is called option. An option may have a plain value inside it or it may be nothing. Imagine looking up a phone number in the phone book. You get the name wrapped in an option or nothing because the person is not listed. Another fancy kind of thing is a Future. It runs some operation like looking up something in a database. When you call the function it just returns this fancy thing and at some point the database sends a response and that response is a plain value inside it. If you want the plain value you have to wait for the future. Well quite often you have functions that return fancy things and you would like to chain them together; lookup some user and then lookup their account. Instead of waiting for the first one and getting the plain value out then passing that to the second one and waiting for that, you could write some code that chained the two functions together for you. That composing of functions that return fancy things is called join or flatmap. If you also have a function that can put any value into a fancy thing (this is called unit or pure) you now have what is called a monad.
- trebbble 4y ago> I can't seem to wrap my head around OOP. There's too many concepts in OOP. Which ones? You're familiar with structs, right? OO is just structs with a little magic & sugar. Not even that much. Objects, methods, properties, instances, classes: Imagine if, when defining a struct type, you could put references to functions on it, such that any struct of that type would contain those same fields with references to the same functions you put in the type definition. Then, if you create a struct of that type, the compiler and/or runtime will helpfully and magically appends an extra argument to those function signatures, assigning it some conventional name ("this", perhaps) and, if you call such a function "on" a struct of that type, the compiler/runtime will quietly, in the background, pass a reference to the struct you called the function "on" in that last argument slot, so that within the function you can make use of the function's "parent" struct (as, perhaps, a variable named "this"). The struct type with slightly-magical function references is a class. The fields on the struct containing references to functions with the magical "this" argument appended when invoked, are methods. A struct of that struct-type is an object, or instance of the struct type, if you will. Fields on the struct are properties or members or whatever you like to call them. Static: What if you could tell the compiler/runtime not to bother appending that "this" argument to some of those functions you attached to a struct type definition? Or to have a given field on a struct type definition always point to the same location for every single struct of that type, so that they all essentially share a single variable? That's what "static" means. Inheritance: What if you could tell the compiler/runtime that it should associate one or more other struct type definitions with the struct type you're currently writing, and that if it can't find a given field (including ones that are refs to functions, aka methods) on a struct of this type, it should check an associated struct of the other type(s) and only error if it can't find it there, either. With the result that a struct type so constructed effectively contains all the fields of the structs associated with it, unless a duplicate exists on that child struct type, in which case that takes precedence. That's basically inheritance. It's all about setting up and manipulating those kinds of relationships & precedence for lookups. That's all. Abstract, et c.: Just ways to have the compiler enforce constraints and requirements on a struct type definition. Final I do solemnly swear this is a constant, not a variable. Now, there are implementation details under the hood for all this, but that covers actual usage, terminology, and concepts pretty well. You don't need to dig into the details of e.g. vtables (one tool for efficiently settling those inheritance-leveraging field lookups) unless you're implementing OO itself.
- magicalhippo 4y ago> In FP it's just data and functions for transforming that data. In OOP it's just data and methods for manipulating that data.
- Floegipoky 4y agoI started with mainstream procedural and OO languages like C++ and Java. I felt like I had a pretty good understanding of OOP by the time I left university. Later, learning a little about FP took my OOP to a whole new level. I really recommend reading Sussman and Steele if you haven't already, it's basically a constructive proof showing how to represent objects in a functional language. Unfortunately the title is so boring that generations of CS undergrads skipped reading the paper, so the zeitgeist forgot. Hewitt was another important researcher at the MIT AI lab at that time credited with discovering the Actor Model, which basically combines objects with a concurrency model. I've seen him post on HN occasionally =) So many people think "OOP == classes", and I think it's really a shame that (in many ways superior) alternative representations were relegated to the sidelines for so long. I see Java's relatively recent inclusion of algebraic datatypes as a tacit admission that contemporary computing requires different primitives, and I expect to see a shift in best practices towards objects represented as immutable data structures combined with effectively-pure functions. Just like the FP folks have been saying all along! > This work developed out of an initial attempt to understand the actorness of actors... Sussman suggested the experimental approach of actually building an "ACTORS interpreter"... When it was completed, we discovered that the "actors" and the lambda expressions were identical in implementation. https://dspace.mit.edu/handle/1721.1/5794 https://dspace.mit.edu/handle/1721.1/5794
- cpursley 4y agoThanks for the recommendations and link!