Elmish update argument order

I am big into the MVU style of UI application. I adapted Elmish to have declared/testable side effects. I even created an MVU variant on the back-end to run business logic. I love it (with declared effects) because it cleanly separates decisions from side effects and is easy to test.

In building and testing some of these things, the argument order of msg → model always seemed odd to me. My test functions always used a fold which would nearly fit update if the parameters were reversed. (Runtime execution uses a recursive loop so argument order makes no difference.) And update returns model first, with the returned Cmd conceptually representing future Msgs.

It seemed intuitively that this argument order is “wrong”, but it is not that important to my life, so in the years I’ve been working with MVU I didn’t bother to investigate. However I was recently trying some tweaks to MVU and I thought to see what I could find. I’d be curious if anyone else has more info.

First Elmish is more or less a port of Elm into F#. So Elmish’s argument order is inherited from there. The Elm language is based largely on Haskell. The compiler is written in Haskell. It was originally focused on FRP and folding signals played a central role. I am not overly familiar with Haskell but my understanding from the documentation is that right fold (foldr) is the preferred way to iterate. And the parameter order of the right fold’s folder function has state (model in MVU) on the right. foldr also supports short-circuit evaluation, which seems like it could be handy for FRP. Heck even Elm’s left fold function eschews tradition and uses right fold’s parameter order for the folder function. Which makes it behave unexpectedly when parameter ordering matters (examples: string concatenation, subtraction).

F# has left and right folds (fold and foldBack) in its collections. However, they are not lazily evaluated and foldBack does not do short-circuit evaluation. The primary difference between F#'s left and right folds is the order items are iterated.

My conclusion so far is that the parameter order for update is based on implementation details of Haskell’s folding functions. And that these details are not relevant in F#. So there’s no particular reason for it to be one way or the other in F# aside from what best fits the situation. State on the right makes a lot of sense if the state is piped a lot. But as an accumulator in left-to-right list processing, less so.

It doesn’t get us closer to solving world hunger, but I was curious.