In my app, I changed the standard update signature from: msg -> model -> ( model, Cmd msg )
to: msg -> model -> ( Maybe model, List msg, List notification ) Here was the reasoning for each of the changes: 1. Returning Maybe model: Laziness in view generation depends on not needlessly changing the data being passed to a view function. Originally, I was handling this by checking the results of sub-model updates for equality before updating the containing model. That approach, however, can run afoul of the fact that Elm doesn't like to compare functions for equality, so if your sub-model happens to contains a function, the equality comparison can result in JavaScript assertions. (Or at least it could in 0.16.) [*] So, instead, it seemed better to let update functions signal that they didn't change the model and maybe provided a good way to do that. 2. Lists of messages rather than a single command: This made the no command case easier to write — [] — and the batch function just wraps the list anyway. 3. Lists of notifications: This third parameter provides a way to pass information back up the hierarchy. For example, I have a notification that adds an error to a globally managed error list. Lower-level update functions can just observe that something went wrong, not update the model, and report the error up to the level where they are being collected. But this mechanism also allows the login logic to return a "LoggedIn userid" notification to the main app state manager. I've contemplated merging the commands and the notifications to get things down from three to two but they do behave rather differently. Commands get annotated with additional routing as they move up the hierarchy and are expected to flow out to the app logic to interact with the outside world. In contrast, notifications are destined for upper levels within the model update process and can absorbed, transformed, or passed on as appropriate. The passed on part is important. Where a command will get mapped so that it's result comes back to the sender, a notification isn't expected to come back anywhere and hence doesn't need mapping unless we have to change notification types. This approach has only been in place for a while so I'm not ready to give a definitive report, but it has seemed to clean up a lot of ad hoc logic. Mark [*] I've thought about whether Elm should fallback to essentially creation-defined equality — i.e.., values are equal if and only if they are the same JavaScript object — or offer an operator providing this test, but doing so would mean that various compiler optimizations could change the meaning of programs, so it's probably not a good idea. -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
