9 ms·
I don't get why so many JavaScript developers thing functional is cool. Functional has been around for 30+ years. OOP won against functional because OOP is easi
by flowerlad 6y ago
I don't get why so many JavaScript developers thing functional is cool. Functional has been around for 30+ years. OOP won against functional because OOP is easier to understand and leads to more maintainable code. These days people are taking a second look at functional because functional avoids state, which makes it easier to write concurrent code with no locks. (This has suddenly become important because Moore's law is coming to an end, and CPUs are adding more cores instead of making cores faster and faster.) But this advantage of functional is not applicable to JavaScript because there are no locks in JavaScript in any case!
Functional programming actually brings some benefits to backend code. To take advantage of the extra cores in a CPU you add threads, but if these threads are continually needing to lock in order to serialize access to shared state then concurrency is diminished. The more cores you have, the more threads you have, and then the more you have to lock. Functional style solves this problem by not having mutable state.
But when it comes to JavaScript these benefits don't exist. That's not to say there are no benefits at all to incorporating some functional style into JavaScript code, but wholesale replacement of OOP with functional style is not warranted.
- CardenB 6y agoMutable state is also a readability concern. If you have to model the temporal state of some object in your mind, it is pretty prone to error as you change code.
- wtetzner 6y ago> OOP won against functional because OOP is easier to understand and leads to more maintainable code. You say that as if it's the truth. It's not at all clear to me that's the reason OOP "won". > These days people are taking a second look at functional because functional avoids state, which makes it easier to write concurrent code with no locks. I think that's only a small part of the reason for the interest in functional programming.
- Weebs 6y agoAfter picking up functional programming < 2 years ago and using it constantly at work, I definitely have to say I disagree with GP that OOP is easier to understand. I think there's a lot of value in the concepts of OO's message passing, and exposing an interface that encapsulates some internals. It's a tool I regularly use in FP even with immutable types Imperative OO to me though is plain difficult to do correctly, and shouldn't be the primary way that your encouraged to write code. It's much more difficult to track dependencies and who touches what in an imperative class, and you end up digging around the file before you can even know what you have to keep in your head. With FP, you generally have pure functions that take in some state and dependencies, and produce a new state. Everything you need to know related to how that function behaves is explicitly given to you, and it's trivial to test the code. You can do this in imperative OO too, but you're nudged in that direction by default. I do think there are cases when imperative code and imperative OO make a problem easier to represent/understand and faster to execute, but I like to keep those sections small and easy to fit in your head, delegating most of the logic to functions. The imperative OO is mostly some glue to bring the business logic to life.
- narwally 6y agoOO: 'state is hard, let's make it easier by encapsulating it with only the procedures that need to manipulate it' FP: 'state is hard, let's not do it unless we absolutely have to'
- munificent 6y agoModern multi-paradigm language: "State is hard. Let's avoid it when we can and encapsulate it in procedures when we can't."
- Weebs 6y agoI think for FP it should be added, that the state is explicit and has a clear owner. Eventually someone has to replace the old value with the new value in the call chain What's really interesting is Rust arrived at a similar destination, I assume as a natural byproduct of pushing for memory+thread safety. State isn't discouraged, but you get explicit owner(s) of data who lend it out to others who are readonly by default, and explicit when they will modify the reference you gave them.
- narwally 6y agoI'd say OOP 'won' because Java offered garbage collection and a C style syntax. The fact that it was also OOP was incidental.
- euiq 6y agoRight—garbage collection makes most software engineering significantly easier.
- munificent 6y agoOOP first boomed with C++ before Java came around, and Java got GC from function languages. If GC was the distinguishing factor, OOP would have never gotten off the ground.
- pjmlp 6y agoHaving been there when it all took off, it always feels so wrong to read "C++ code written Java style", when it was C++ that actually created that style.
- yelloweyes 6y agoLet's be honest. 90% of JS developers out there probably don't even know what a lock is. I know a JS dev who gets paid good money to develop software, who thought the reason you shouldn't use floating-point to deal with currency was because "javascript is bugged".
- skohan 6y agoIt's worth noting that there are drawbacks to functional programming as well. It tends to result in a lot of copying, which is also not optimal for performance.
- ollysb 6y agoThis is somewhat though not entirely solved by https://en.wikipedia.org/wiki/Persistent_data_structure https://en.wikipedia.org/wiki/Persistent_data_structure
- lukevp 6y agoFunctional programming is getting popular in JavaScript not because of serializability of state changes across threads, but because immutable state and immediate-mode GUIs go hand in hand. React, as an example, works as an immediate-mode GUI (re-rendering VDOM on every state change) on top of a retained-mode GUI (the DOM). You manipulate your state using reducer functions and the library works behind the scenes to convert that to a UI. It alleviates all of the weirdness and performance issues of interacting with the DOM when state changes. GUI programming is traditionally retained-mode. OOP is traditionally state encapsulation and mutability. OOP and retained-mode GUIs are conceptually similar, and Functional Programming and immediate-mode GUIs are conceptually similar. Here's a good explanation of this: https://medium.com/@puppybits/immediate-mode-reactjs-7a6302cd89cd https://medium.com/@puppybits/immediate-mode-reactjs-7a6302c...
- pjmlp 6y agoNot all OOP languages support inheritance, nor all FP languages are immutable by default, though. GUI programming surely wasn't retained-mode on 16 bit home computers, in fact that was one of the issues getting used to GUI based OSes event queues back in the day.
- flowerlad 6y agoI don't see parallels between OOP and retained mode, and functional and immediate mode the way you are describing. UI components inherently have state. Pretending they can programmed in functional style with stateless functions is bizarre because UI functions do have side effects. See prior discussion: https://news.ycombinator.com/item?id=24363261 https://news.ycombinator.com/item?id=24363261
- lukevp 6y agoYes, ui components have state in the case of a retained mode GUI like the DOM, but in the case of React, relevant data is derived from the application state (eg IsDarkMode is a state property used to derive colors for a component, or the checked state of a checkbox) and a unidirectional flow propagates that state change to the VDOM on every re render. Functional doesn’t mean stateless (state exists as closures within higher order functions, such as in the composition of functional components within React), it means side-effect-free, it means determinism in the derivation of additional state based on immutable state updates.
- arcosdev 6y agoI would agree with you if JS wasn't JS. It is a terrible language to write OOP-style code in and a much better one to write functional-style code in. It is inherently a more functional language.
- azangru 6y ago> because OOP is easier to understand and leads to more maintainable code How is OOP easier to understand exactly? If you are debugging the code that looks something like this: class Child extends Parent { launchRockets() { this.launch(this.rockets); } render() { this.score = this.getScore(); return `<span>${this.score}</span>`; } } How do you know which part of your code contains implementation of this.getScore method? How do you know which part of your code is responsible for the number of this.rockets and how many methods in how many classes can change it? How do you find out which part of your code is going to call the launchRockets method, and whether this will even be this class's method or one of its children's? How many hops across your codebase do you need to make to figure all this stuff out? How is this style any simpler than functional?
- bitL 6y agoYou have IDE for that in general. If you are writing all code in Sublime, then yeah, you have a problem.
- symlinkk 6y agoIf you need an external tool to understand code it’s an indication that something is wrong.
- bitL 6y agoIs that? If you don't write all your code with `cat`, is that an indication that something is wrong as well?
- ragnese 6y agoI somewhat disagree. This will be true for pretty much any non-trivial code project. I'd love to see a language where I didn't need tools to understand what's happening, but that's impossible currently. Do you really never need to see what a passed-in function actually does in your FP code? Never need to see what type an argument is in our fancy Haskell or Hindley-Milner-typed language?
- deleted 6y ago[deleted]
- allenu 6y agoI think it's debatable that OOP is "easier to understand and leads to more maintainable code". It depends on size of project and experience of developers. There are still certainly benefits to using FP in JavaScript from a design, readability, maintainability sense, even if you are not concerned with concurrent code with no locks. A good FP design can be easier to reason about than an OOP graph of objects.
- Zak 6y ago> OOP won against functional because OOP is easier to understand and leads to more maintainable code. OOP as we know it today, which is not what the inventor of the term had in mind, likely won because it was easy to add it to C in a manner compatible with low-level optimizations that were critical in application code at the time, and less so now. I dispute that one style is inherently easier to understand than the other, though each has certain problem domains where it maps particularly cleanly.
- chriswarbo 6y agoSlightly tangential, but Single Assignment C is well suited to functional programming
- loup-vaillant 6y ago> OOP won against functional because OOP is easier to understand and leads to more maintainable code. A couple points: I'm not sure whether OOP really won: pretty much any language now has taken lambdas & higher-order functions from FP; before those parametric polymorphism (ML was there before C++ templates and Java generics); many sources will tell you to limit mutable state; and even algebraic data types are starting to get mainstream traction (Rust). Speaking of which, I believe Rust does not sell itself as an OOP language? It is not at all obvious that OOP is easier to understand. Those animal/shape hierarchies are indeed very easy to grasp, and they are also useless. Even games have moved away from class hierarchies, which are both slow and too inflexible. They're more about ECS/data orientation now. I'm not sure that "easier to understand" does lead to more maintainable code either. If you're talking about daily use, why not. If this is a learning curve thing (and in practice I suspect it is), then I think ease of learning and code quality won't correlate with each other — provided only people who learned the stuff get to program with it of course.
- pintxo 6y ago> Those animal/shape hierarchies are indeed very easy to grasp, and they are also useless. That's a wonderful description.
- narwally 6y agoAs someone that had some background in cladistics, I knew OOP was gonna get real complicated as soon as I saw animal hierarchies as a 'simple' example.
- TimTheTinker 6y ago> OOP won against functional because OOP is easier to understand and leads to more maintainable code. Actually, OOP won because OOP is easier for non-developers to understand -- those who were making policy and purchasing decisions back in the 1990's. And the OOP we now call "OOP" (as realized in languages like Java and C++) is not at all the OOP that was first envisioned by Alan Kay and implemented in languages like Simula and SmallTalk.
- goto11 6y agoOOP won out over imperative because it fits very well to (desktop) GUI programming - UI controls maps elegantly to objects with state. OO turned out to be broadly useful, but GUI programming was definitely the driver. I don't think anybody had compared maintainability between similar projects in OO and functional style. Functional was not really a contender in this space. Almost everybody who adopted OO migrated from imperative. The popular OO languages were imperative languages adapted to OOP - Visual Basic, C++, Delphi etc.
- danielmain 6y agoHow no locks in JavaScript? Have you heard about async await?
- jk700 6y ago> OOP won against functional because OOP is easier to understand and leads to more maintainable code. If by functional you mean higher order as in the title and not what is commonly known as FP - it's never been true. For example, a function that has no outside side effect and that calls an anonymous function provided as an argument is way easier to understand, reason about and maintain than its OOP equivalent of creating an object and calling three methods in specific order mixed with your code. > These days people are taking a second look at functional because functional avoids state, which makes it easier to write concurrent code with no locks. Avoiding state doesn't make it easier to concurrently touch shared memory without locks. Event loop style concurrency simply doesn't touch shared memory concurrently, so it doesn't need locks and doesn't have all those multithreading problems. It can still mutate state left and right, higher order programming just allows to map intent better to the code, making "sequences look sequential" and all that. Actually solving problems concurrently with high performance today generally requires ditching shared memory based synchronously communicating concurrency models, leaving async communications of isolated entities where locking problems and overhead don't exist. But it has nothing to do with functional programming, OOP, higher order programming.
- munificent 6y ago> I don't get why so many JavaScript developers thing functional is cool. Let me make a meta-point. It's natural to find yourself with a thought of this form: I don't get why so many think ___ is cool. There are two answers to this: 1. None of them know something you know, and you are right. 2. At least some of them know something you don't, and you are wrong. Statistically speaking, 2 is much more likely to be true. So when you find yourself having these kinds of thoughts, which are entirely natural, you'll make better progress if you can formulate it as a good-faith search for truth and approach it with an open mind.
- yelloweyes 6y ago>Let me make a meta-point. It's natural to find yourself with a thought of this form: I don't get why so many think ___ is cool. I don't get why so many think cigarettes are cool. You're telling me they know something I don't about cigarettes?
- TimTheTinker 6y agoMany/most who have a lifelong cigarette addiction would not describe them as “cool”.
- munificent 6y agoYes, actually. * Cigarettes are stimulants and feel great when they first kick in, like a good cup of coffee. * Smoking gives you a culturally-approved reason to take breaks throughout the day and go outside. * Smoking is a social activity that provides an easy way to meet new people. Of course, it is strongly chemically addictive too with serious negative health consequences, but the reason people smoke isn't only addiction or no one would ever start. I learned the above list by once genuinely asking someone why they smoke.
- deleted 6y ago[deleted]
- pjmlp 6y agoAnother thing that people also miss all the time is that not all FP languages are immutable by default, most FP that achieve a certain level of mainstream adoption also have OOP like constructs, finally even Smalltalk-80 already provided the mechanisms to do LINQ like coding and passing closures around.
- dragonwriter 6y ago> Functional has been around for 30+ years. 60+, and OOP has been around for 50+. > OOP won against functional because OOP is easier to understand and leads to more maintainable code. OOP didn't “win”, it had a period of intense popularity starting in the late 80s and starting to fade around the mid-00s. And that was largely path dependence and building on C; had someone put the kind of effort into C-with-lambdas instead of Stroustroup's C-with-objects, we might have had a couple decades where the most popular languages were all C-descended impure functional programming languages rather than C-descended class-based OOP languages.
- didibus 6y agoFunctional is making a comeback, because the performance is now good enough. That's my personal assessment. It never really "lost" to OOP, it just wasn't ever a real contender before, because of performance reasons. With the revival of dynamic languages though, people heavily programming in JS, Ruby, Python, etc. Performance is no longer a concern of people. So now people are motivated by what makes the act of programming as convenient to the programmer. When it comes to that, it turns out a lot from FP does make things simpler for the programmer. It started with data transformation, I think helped by the appearance of LINQ in C#, which first exposed people to functional data transformation. Then Java got Streams, and everyone kind of followed suit in introducing some higher order functions and map/reduce/filter and all that. Also: callbacks. As asynchronous behavior became more popular, there was a real need to lower the amount of verbosity and just code you needed to type to program in an async style. So creating a class and an object for every little event in your app, to pass as callbacks to all async functions just got super annoying. So people introduced anonymous functions and lambdas, and added support for higher order functions that could be used as callbacks. Once you've got callbacks and higher order functions, closures are a natural extension, you often want to pass a callback that will set some state elsewhere when done or other such things. So Closures were also added. And here we are, with a full FP toolkit due to the fact that performance isn't a concern anymore and async programming is more convenient when your language has support for first class functions with closures and anonymous functions and lambdas. At the same time, like you said, people started squeezing more out of their cores and their seperate IO controllers, so concurrent and parallel programming became more common. That forced people to look at the immutable characteristics of some FP langs, and so support for immutability was also added to a lot of language. Once you're in the realm of immutability, Objects also become less useful, since there's no need to encapsulate and protect modifications to something you can't modify anyway. Thus once again, creating a class and a constructor and all that just becomes unneeded verbosity and extra code to write. So people wanted ways to go back to immutable value records and just write functions over them, etc. All these things in my opinion combined for what is today the "resurgence" of FP.