4 ms·
> But you quickly realize that there are benefits to separating out code with side effects from code without. This belies your whole previous argument... Ever
by horsawlarway 5y ago
> But you quickly realize that there are benefits to separating out code with side effects from code without.
This belies your whole previous argument...
Everyone understands that side effects are a requirement (literally - a program with no side effects is useless). Functional programming herds the programmer into a situation where code that creates side effects is consolidated into just a few places, and the majority of the code is pure functions.
That paradigm has a real cost - consolidating side-effects isn't particularly easy, and you have to work to do it.
But in exchange you get a LOT of pure functions that are
1. Easy to reason about
2. Easy to compose (because they have no side effects)
3. Easy to test
Hooks are the antithesis of this - they create code them seems pure, and has the guile of being composable & testable, but in reality they are very hard to reason about. They have completely undone the work of consolidating state and side-effects into one location. It is very easy to call a function with a hook in it in a way that breaks that function, and it's usually hard to reason about what subtle differences are causing this new breakage.
- PaulHoule 5y agoSome things are easy to express as functions (compilers). Other things aren't (user interfaces). Even when immutable data is easy and is good from a software design perspective it is often a terrible choice from a performance perspective. Advocates say the performance loss is just a factor of two in many cases but that's why FORTRAN survived so long against C, why people are developing Rust when Java is available, etc.
- horsawlarway 5y agoI don't disagree with you at all. There's a reason no on is writing modern games in functional languages, and that reason is performance. But that said - At least for me - the major attraction of React was that it really concentrated on making ui related code pure. Give a component the same props, and you get the same DOM. That's a really powerful concept for reducing bugs, easing testing, and giving you composable components. It is not a performance improvement. I think hooks really hollowed out the value proposition here. Because class based components were more painful, I used to see a lot of care and thought put into consolidating the logic that generated props into a single class based component (consolidating state). That component would then mostly pass down props to pure components. Hooks make it easy to just throw state into any old component - which is nice in some sense, but like I said - it hollows out the value proposition of having pure components. Good teams will still try to write mostly pure components, but many folks will just liberally scatter hooks into their code, creating code that becomes increasingly hard to reason about.
- jokethrowaway 5y agoThat reason is not performance but familiarity and ecosystem. A trendy way in gaming to build games is to use ECS which is FP and there are very performant framework to do ECS.
- horsawlarway 5y agoI would argue (pretty hard) that the reason is actually performance. The ecosystem matured around C-style procedural language concepts because naive functional implementations simply weren't fast enough (and were often much more difficult to work with). Yes - some companies do leverage FP concepts for development, but they're usually heavily modified for that specific purpose (ex: GOAL at naughty dog, ECS for Unity) And even then... ECS is "vaguely" functional at best. The entities are mutable, and the logic in the systems is directly modifying those mutable entities. I appreciate that the logic is applied consistently, and I think there's value there that comes from FP - but it's very much not classic FP.
- bern4444 5y ago> Hooks are the antithesis of this - they create code them seems pure I disagree. The presence of a hook is the indicator that something impure is happening. Seeing a hook should be equivalent to seeing a promise, option, IO type etc. Hooks also compose beautifully together. You can make so many great new hooks by combining just useState and useEffect together, bundling up that functionality into a new hook that you can then use in any UI.
- horsawlarway 5y ago> The presence of a hook is the indicator that something impure is happening. Yes. And that's my whole point. React was very powerful when care was taken to place impure code into a single class based component, that then passes state down to pure components as props. React is a lot less powerful when developers scatter hooks everywhere. New developers no longer have to go out of their way to understand the render lifecycles of a class based components, and feel the pain of writing componentDidMount or componentWillMount or componentWillUnmount or shouldComponentUpdate functions. Instead they just throw a hook in. Which is mostly ok - but it's hiding that you do actually still have to care about how this whole shindig works (and opens up a whole new world of pain around identity and equality checking, re-render cycles, dependency passing, etc) I'm not saying hooks don't have an upside (ex: I'm right there with you, I mostly prefer a hook to an HoC from a reusability stand point) but hooks let developers shove their head into the sand and mostly pretend that they're writing a pure function - and they're ABSOLUTELY NOT.
- nightski 5y agoThere was nothing preventing you from scattering state everywhere in class based components. On top of this the component tree became a huge mess of HoC's stacked on top of each other. You absolutely should not be scattering hooks everywhere in your code base. The same principle applies to use them higher in the hierarchy and pass down props. This is a simple principle that can be taught to a new React developer. Keep your state at the highest level it makes sense to no matter the state mechanism used. Hooks allow for composition of effects in a way that class based components did not.