6 ms·
OP here, it's a great question indeed! Now let's forget about elm/elmish but we are to write a stateful application. It doesn't have to be a web app, just any a
by reverseblade2 6y ago
OP here, it's a great question indeed! Now let's forget about elm/elmish but we are to write a stateful application. It doesn't have to be a web app, just any application needs to hold some state. And that state should be modifiable (Not to mention we will have side-effects as well.) in order to do something useful but we also want to stay on the Functional programming realm to get benefit from things like immutability and other functional goodies.
So you see these two goals are contradictory. How FP tackles this state problem? One solution is to use actors and agents. And that's precisely what elmish is. Unlike the conventional apps where you mutate the state directly, an agent in F# is a recursive call which can await for further messages.
So just like Flip Flop holds the state in memory, an agent hold the state in a recursive function. And how is this connected to elmish? Let's see how elmish v2 is implemented:
https://github.com/elmish/elmish/blob/5330f52153d5181923bb3cb065436748dc38231e/src/program.fs#L90 https://github.com/elmish/elmish/blob/5330f52153d5181923bb3c...
You can see an agent there and that's the core of elmish.
So basically elm and elmish is a way to handle state changes
in a functional manner along with side effect support via commands.
I cannot emphasis importance of elmish, because not only it
helps for isolating the state functionally but it helps you to keep your business logic separate from UI. So you don't end up messing your code like you use React hooks or context.
- kingdomcome50 6y agoI understand what you are saying. I'm not sure how your points are at odds with the OOP counterpart I describe though. The essence of your response seems to be "because we want to use a pure FP paradigm" to which _I_ would add "despite a clear downside to which F# has the capacity to avoid". If the framework only expects every `Model` to contain 2 methods (`view`, `update`) and never any more (which is the case), I see no reason at all to adopt the Elm architecture. The interface for `update/view/model` is well-defined and un-changing. It's clearly sitting on the wrong side of the expression problem. The program loop could work exactly the same no? Just re-organize: let (model',cmd') = program.update msg state to: let (model', cmd') = state.update msg // I'm not sure where/how program fits in My question is truly as simple as trying to figure out the advantage of the chosen semantics (in F# - I don't know Elm). It can't possibly just be "because we want to stay on the Functional programming realm" can it? Immutability can be achieved in any paradigm. Forgive me if I am coming off overly controversial - I don't mean to be. https://guide.elm-lang.org/webapps/structure.html https://guide.elm-lang.org/webapps/structure.html - Even here in the "MVC" section the documentation _recommends_ you organize your project according to type (containing the `view` and `update` functions). This is very-much akin to my critique. If you reach the point in your project above you have essentially regressed back to OOP (in FP clothes).
- reverseblade2 6y agolet (model', cmd') = state.update msg In order to write that you have to pin a reference to the state. But state is something that has to flow. Sure you can pin it to a ref, make it mutable and change the state but then nothing prevents you to change the state arbitrarily e.g. from a command. I believe yes the answer is because we want to stay on the FP realm. FP imposes some restrictions to keep our sanity. So not having a reference to the state and making it immutable is one of those restrictions.
- kingdomcome50 6y ago> In order to write that you have to pin a reference to the state Forgive my ignorance, but why is that the case? Isn't `state` being passed into the loop? Mutability is orthogonal to the question of where one defines a unit of behavior. Maybe an immutable object is not possible to achieve in F#, but one could certainly imagine the concept of an immutable type with methods. My question is more about the modes of organization: Large unions vs discrete modules and how they affect how one's ability to change a program over time. If you say that the architecture was chosen out of a purest sense of FP, then fair enough. I can understand why someone would go that route. Just had to know.