5 ms·
> ...and capture a sequential list of updates when you call setState. In functional programming, functions are not allowed to do that. The only thing a functio
by petilon 4y ago
> ...and capture a sequential list of updates when you call setState.
In functional programming, functions are not allowed to do that. The only thing a function is allowed to do is return a value.
> ...you reach out up the stack to the component and store it there.
FP functions are not allowed to do that. In FP functions can only rely on the parameters passed to it (it cannot refer to anything outside) and it should not do anything beyond return a value.
> It’s why call order is important, because it’s how they know which is which
In FP, functions can be called in any order (unless one function needs the return value of another), and the final result is not affected by the order.
> You don’t modify any global state though.
If you have state it is not FP, whether it is global or not.
- javcasas 4y ago> In functional programming, functions are not allowed to do that. The only thing a function is allowed to do is return a value. Oh, yes, they are allowed to do that. You capture the effects into a list, and return the tuple of list and return value. If you feel like it, you wrap that into a monad to pretend you are only "returning" a single thing. > In FP functions can only rely on the parameters passed to it (it cannot refer to anything outside) and it should not do anything beyond return a value. You mean explicit parameters (props) and implicit parameters (context), right? I thing you forgot the latter. Implicit parameters have existed for quite a bit, for example in the reader monad. > In FP, functions can be called in any order (unless one function needs the return value of another), and the final result is not affected by the order. Yup, except if you write a bunch of functions and store them in a list with the intention of applying the result of the first entry of the list against the first entry of the list. Now, if you construct the list of functions as effects (by hiding them behind a monad) you find out that you need to call the effects in the same order as to construct the list of effects in the same order. This doesn't contradict FP, it contradicts your mental model of how React is supposed to work. > If you have state it is not FP, whether it is global or not. The state resides in the runtime executor, exactly like Haskell's IO monad. Again, this contradicts your mental model, not React or FP.
- petilon 4y agoI think you may be missing the forest for the trees. The point of FP is that you can glance at a function and say 'this is obviously correct' without having to work out the state and context of every call.
- ojkelly 4y agoBut you can do that with algebraic effects. That’s kind of the point. You keep the clarity of declaring what you want to happen, and abstract the how to the effect handler.
- petilon 4y agoNone of that is true in React hooks. The negative sentiment towards hooks that you see here is because it is weird and complicated. Want to see how much simpler code can get when you code without React or any such fat frameworks? Take a look: https://github.com/wisercoder/eureka/tree/master/webapp/ClientApp https://github.com/wisercoder/eureka/tree/master/webapp/Clie... You just need to know JavaScript, HTML and CSS, not much else. The code is simple, and yet maintainable. No need for hooks, useEffect, useState, useMemo and all that crap.
- _v7gu 4y agoHow can you ever be sure that your state is valid when you’re putting it on the DOM? Worse yet, only parts of the state is stored there. I can’t really call this code simple since it had to resort to timing hacks to get its functionality in order. A random 250ms delay and bam, bugs you cannot reliably reproduce
- petilon 4y agoCan you clarify what you mean here? What state is in DOM? Do you mean the state inherent in input elements? What timing hacks are you talking about?
- jameshart 4y agoI find it's best (if side effects and state mutation make you nervous) to think of hooks as essentially part of the function signature of a react component, both on the parameter side, as well as on the return side. They are not written as such, because of syntactic limitations of JavaScript, but essentially a react component that starts off like this: function MyComponent({}) { const [count, setCount] = useState(0); const [active, setActive] = useState(true); useEffect(() => if (active) setTimeout(1000, () => setCount(count+1)), [count, active]); ... can kind of be thought of as if it accepts an extra hidden set of parameters, kind of like this: function MyComponent({}, hook1 : useState, hook2 : useState, hook3 : useEffect) { const [count, setCount, hook1Result] = hook1(0); const [active, setActive, hook2Result] = hook2(true); const hook3Result = hook3(() => if (active) setTimeout(1000, () => setCount(count+1)), [count, active]); ... return [<div></div>, [hook1Result, hook2Result, hook3Result]]; } In this version, those hook functions are side-effect free, pure functions that our caller provides us with, closed over the previous stored state of our component in the tree; and when we return the results along with our rendered output, our caller has the new state of our component together with our desired DOM. Instead of forcing us to write all that extra code, route those extra variables, and figure out the metadata mechanism whereby the caller of the render method figures out what hook functions to supply, the rules of hooks let you use JavaScript's imperative, procedural syntax to call hooks which are implemented using ugly side-effecting impure techniques, but in a way that pulls off something semantically identical to this pure functional flow. It's a pretty neat trick, honestly.
- petilon 4y agoDon't call this functional programming. If you call setCount() then this is not functional because your function is doing something besides returning a value. In fact, it is setting state, which is against FP principles.
- jameshart 4y agoOkay. But is it against FP principles to write software that runs in web browsers then? Because web browsers exist, and they work in a nonfunctional way. So to interact with one we need to do a little bit of imperative code. And then react lets us figure out what to do when the web browser responds to that imperative code by letting us run a largely functional program. Which is pretty neat considering we’re doing so in JavaScript. The thing that we’re after here is not a badge that we can slap on our code saying ‘certified 100% functional’. We are trying to write code using patterns that help us reason about and structure what we want the computer to do, avoid bugs, and ship software. If react managed to squeeze a surprisingly functional pattern into a JavaScript library to that end, can’t we just applaud the audacity and enjoy using it, without nitpicking that they didn’t actually reimplement the lambda calculus?