Returning a nextState in Redux/JS land is a workaround. Basically, one wants to avoid the situation where the state is mutated, but the framework does not know. This happens because there are multiple references to the state, and because, for performance reason, the framework is comparing the states based on referential (===) equality. Thus the view (in whole or in part) and the model can go out of sync. Always returning a new state object is an expensive way of ensuring this, but on the human time scales we're talking about, an insignificant cost.
On the other hand, in Rust, we have the compiler on our side. If one grabs a mutable reference to the state (&mut Model in the update function in https://github.com/DenisKolodin/yew/blob/master/examples/cou...), then the Rust compiler ensures that there are no other references to that Model. Thus, when the framework does `nextState = mutate(¤tState)`, one is guaranteed that there are no existing references to `¤tState`, and thus it is impossible for a shadow update to occur.
IMO, this is better not primarily for performance reasons, but because it is conceptually easier to mutate a state object instead of using reducers. (I haven't looked into this framework much, so I don't presume to speak about it's internal implementation, so this may be off in some framework-specific details.)
in a nutshell this the counterargument to functional purity: side effects can be done correctly/safely when you have/build the right tools. i'm inclined to agree with it.
It's not really a counterargument so much as another approach. Immutability and purity are still powerful concepts, but you don't need to use them for every single situation in rust.
In Haskell, mutable APIs are available but this is surfaced in the types. The idea is not so much that you shouldn’t have mutability, as that it shouldn’t look the same (and be treated by the compiler the same) as immutability.
Maybe Haskell goes too far in this regard, but Rust is in line with the same way of thinking, because mutability is surfaced and checked at type level.
FWIW, it's more of a "simplicity" choice - it is entirely possible to keep mutations reactive in React with libraries like MobX - it's just extra functionality that React doesn't ship out of the box but it works just fine without a borrow checker.
On the other hand, in Rust, we have the compiler on our side. If one grabs a mutable reference to the state (&mut Model in the update function in https://github.com/DenisKolodin/yew/blob/master/examples/cou...), then the Rust compiler ensures that there are no other references to that Model. Thus, when the framework does `nextState = mutate(¤tState)`, one is guaranteed that there are no existing references to `¤tState`, and thus it is impossible for a shadow update to occur.
IMO, this is better not primarily for performance reasons, but because it is conceptually easier to mutate a state object instead of using reducers. (I haven't looked into this framework much, so I don't presume to speak about it's internal implementation, so this may be off in some framework-specific details.)