4 ms·
The right way to get rid of mutable state is to replace it with a stream abstraction, which declaratively models how the state changes in response to events. Th
by spion 10y ago
The right way to get rid of mutable state is to replace it with a stream abstraction, which declaratively models how the state changes in response to events. That would be cyclejs: http://cycle.js.org/ http://cycle.js.org/
Too bad that this model doesn't work well with React. React models the UI as a (mostly pure) function from props/state input to DOM output, however in reality the UI is a stream containing both DOM states and input events. The minimal modification would be to select the input events that a component would like to expose in its event stream, in a similar manner to Elm: https://guide.elm-lang.org/reuse/checkboxes.html https://guide.elm-lang.org/reuse/checkboxes.html
- aidos 10y agoWhy do you say that's the right way? Is there something intrinsically better about having the state modelled as a stream of changes? Is that really getting rid of mutable state? [EventA, EventB] is a mutation of [EventA], sure it's a WAL style, but the combined final state is a mutated version of the original state. Presumably the concrete state model (like MobX) is a realisation of the event stream at a moment in time. As far as the user is concerned, the only moment in time that really matters is now.
- nine_k 10y agoMutable state is fundamentally harder to reason about. You get aliasing bugs, stale cached values, etc. With immutable data in an append-only stream this is simply impossible.
- aidos 10y agoI've done plenty of work with immutable data, and I tend to code in a way that minimizes the amount of state I have to manage. I guess that's what I was saying about mobx though - I can have a much smaller set of core data and then pure functions for the layers of derived data. And it's a) easy to reason about and b) super performant at managing the calculations. Aliasing bugs don't really apply in JS, unless there's some variation of the term? Stale caching is also not an issue with calculated derived data.
- nine_k 10y agoSaying about "aliasing bug" I meant something like this: var my_data = {"foo": null} function innocuous(input) { var data = {"one": input, "two": something()}; data.input.foo = data.input.foo || "foo" // set a default value // do something with data } var result = innocuous(my_data) // Oops, now my_data.foo has changed.
- spion 10y agoI'm saying its the right way to get rid of it, not that its right to get rid of it :) MobX does really, really well in minimising the complexity of mutable state. Its the best there is out there. Where MobX does worse is when there is more complexity then a simple direct map function to calculate derivations: debouncing key input, doing async requests, creating animated transitions, etc. Its a great model, but it needs some more work to be truly amazing. The user does care about the past. For example if the state of the input box changed too many times during the last second, they don't want every change to cause a slowdown in response time due to too many requests being sent to the server, and they want only results from the last request they sent, not the last one that was processed. I think the reverse criticism applies for cyclejs: while it can do everything thanks to RxJS, it needs a better component composition model. The current one is too tedious and alien for my taste. (For example, why isn't the same DOM selector syntax used for component-event selection?)
- nunyabuizness 10y agoYou should check out cycle-react [1], as it combines the best of Cycle and React. [1] https://github.com/pH200/cycle-react https://github.com/pH200/cycle-react