6 ms·
Some problems don't require OOP, but most large complex problems do, IMO. Most complex codebases I've seen which were pure Functional Programming were spaghett
by jongjong 17d ago
Some problems don't require OOP, but most large complex problems do, IMO.
Most complex codebases I've seen which were pure Functional Programming were spaghetti code; unmaintainable.
What I saw every single time was that the project was syncing a huge amount of state in a central place and then passing it through a large number of components and sub-components. The top level component basically had to have full awareness of everything going on inside the system in order to do its job and there were no separation of responsibilities because none of the components had sovereignty over the state they needed to do their job independently. It's just components micro-managing components all the way down.
React with Redux is probably the best FP implementation I've seen thus far but even it is kind of a mess. I have nightmares about Redux Saga. The Redux Saga logo is literally a stylized drawing of entangled spaghetti.
Had Redux + Saga been presented to people as part of React at the time it was introduced, React would probably not have become so popular. Because people would have understood that it creates too much unnecessary baggage which isn't worth it. React was used as a gateway drug to Redux which was itself a gateway drug for Saga! And what I observed in practice is that most React apps are glitchy AF; and those glitches are usually difficult to reproduce and fix, even if you know all the ins and outs of the framework!
- slopinthebag 17d agoya ive seen the same but in OOP codebases, where the state is all distributed and incapsulated and it's just impossible to reason about how the entire system works because despite it's separation of responsibilities everything is still intrinsically coupled together. and then you have all sorts of hidden mutations and other shenanigans. to me the best way to design large systems is sort of like an ecs. you don't separate components by state + behaviour, you separate systems and state.
- jongjong 17d agoI've seen some ugly OOP codebases, but I've seen some very nice ones too. I haven't seen any nice FP codebase yet besides basic APIs. There's a reason why 99% of video games are OOP. That level of complexity is just too much for FP.
- slopinthebag 17d agovideo games are oop for historical reasons mostly. ue6 is built on verse which is a crazy functional language. carmack himself flirted with haskel and racket. but games are so perf oriented that for a long time the only options were c or c++ (c style ofc). the current trend are ecs's which are distinctly not classical oop
- hurril 17d agoComponent is not a term out of the FP schoolbook. I am sorry to be making what smells like a true scottsman here, but you seem to be describing a React codebase since they call themselves functional with that Redux stuff, you think this is functional programming. A graph of "components" all talking amongst each other. Functional. Programming. Come one, man :) What you are describing is OOP. Passing messages between identities over calling pure functions with values.
- jongjong 17d agoIn the newer versions of React with Redux, the components are all pure functions and state is centralized and passed down into the components. IMO it's as close as a codebase can be to pure functional programming whilst still functioning.
- pyrale 17d ago> IMO it's as close as a codebase can be to pure functional programming whilst still functioning. You know, people have put functioning codebases using pure functional programming languages like Haskell, Elm, Purescript, etc. I really don't see what in your opinion is too close to FP to work.
- kodoman 17d agoNot a frontend developer and my frontend skills are lacking, but the argument I think that is being made is that a react component should generally be written with no side effects and rely on signal for state change and do reactive programming. While of course something like Elm is more so this model and actually is functional from the get go. In js/ts react you are writing a lot of code that aims to be side effect free. Most programs code bases of course need some way of doing side effects and not being 100% pure so many haskell projects would not be classed as 100% pure.
- hurril 17d agoThat is just not the case. I have worked, full time, as a functional programmer coming up to 15 years, in different langauges. Actual functional programming and not merely doing web programming with React. "[...] pure functional programming whilst still functioning." I mean, what is this? When I read what you are saying here, you are saying that an "advanced codebase", whatever that means, using functional programming leads to centralized state and distributed components. And you know this because the codebase you are thinking about has this software architecture. I have been in such codebases too, they tend to be frontend and maybe that is just the way you have to do it, maybe not. But this is not a property inherent to functional programming. Solving problems with a component or object concept as a central abstraction for "a thing" is the OOP way. I know this because this is how I spent the first half of my career. You think you need a _substantive_ onto which you perform verbs. Nothing wrong with this though, I am not picking a fight with OOP. I can offer what I refer to when I talk about FP so that we can at least have a real thing to disagree over :) 1. model the domain and interactions with it with strong types such that neither interactions nor state can represent values outside of the domain. 2. parse, don't validate 3. Use modules, stateless collections of declarations, to organize stateless functions. No this. No self. 4. No magic code. I.e.: no null checks, no magic number checks, no arbitrary logic in four places that together make up the fact that prices can have taxes. Abstract it and "store" these runtime decisions using typed values, use functions that accept these typed values to force use of the aforementioned types. 5. Control the side effects. This does not mean that you have to use Haskell or monads or anything like that. Just that managing it is a good thing. 6. #5 implies keeping track of state. I.e.: no, you may not just willy-nilly read it from the persistent store, cache or file.
- jppittma 17d ago> none of the components had sovereignty over the state they needed to do their job independently. It's just components micro-managing components all the way down. Isn't one of the tenants of FP that nothing is mutable anywhere?
- jongjong 17d agoCorrect, technically they pass copies of the state; which gets cloned at every component/module/function boundary. This protects you from 'spooky action at a distance' which is a real problem which can happen when mutable state is shared by different components but FP can introduce other issues related to passing around a lot of state which can become outdated as it traverses the many layers of spaghetti code.
- mrkeen 17d agoDon't forget to define OOP before requiring it!