Skimming through the code, it looks like batch commands will happen in order. The mentioned `mailbox.push` was from the Elm source code.
Also, I fleshed out an example with both a clean separation and using event sourcing. I posted it with some commentary on marcosh's github <https://github.com/marcosh/marcosh.github.io/issues/1>. I like the terminology in this example much better than my previous examples, especially because `Action` was a previous concept in Elm. type Act = Increment | Decrement type Fact = Incremented Int | Decremented Int type Msg = Perform Act | Apply Fact perform : Act -> Model -> Cmd Msg apply : Fact -> Model -> Model update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of Perform act -> (model, perform act model) Apply fact -> (apply fact model, Cmd.none) The Facts here are also idempotent <https://en.wikipedia.org/wiki/Idempotence> (no dependency on previous values). That's not as important in this example, but can as its extended. On Friday, August 12, 2016 at 9:15:23 AM UTC-5, OvermindDL1 wrote: > > Will your pushed command appear after or before a potentially pushed > 'other' command, say from an incoming port, or button click? That is the > part I am not sure about yet (not read enough Elm internals 'quite' yet). > > On Thursday, August 11, 2016 at 6:31:06 PM UTC-6, Kasey Speakman wrote: >> >> Checked the current implementation of Cmd.batch and it appears sequential >> (`mailbox.push`). Ordering guarantees are not documented so I suppose they >> shouldn't be depended on. But otherwise, the one I coded above that >> guarantees Act doesn't change the model and Evt doesn't have effects would >> work. >> >> On Thursday, August 11, 2016 at 6:33:39 PM UTC-5, Kasey Speakman wrote: >>> >>> Yes, that's why I said back to square one if Cmd.batch isn't ordered. >>> The only thing this is guaranteeing (and the only intended guarantee) is >>> that the messages which only update the model are separated from the ones >>> which cause effects. The ones which cause effects produce ones which update >>> the model, same as always. >>> >>> It occurs to me that some of the benefit of event sourcing the UI could >>> be gained by adding features to the TTD, since it has the magic which >>> ignores Cmds on replay. Some are already listed as ideas at >>> http://debug.elm-lang.org/. I'd still have to keep the messages in my >>> model and provide a way for the user to transmit them in a bug report. But >>> if I could load them in the TTD, that would make repro a snap. >>> >>> On Thursday, August 11, 2016 at 5:22:05 PM UTC-5, OvermindDL1 wrote: >>>> >>>> Isn't `doSideEffects` basically just the current `update` function >>>> though? Except it is returning a list of changes (via message) to perform >>>> to a model instead of doing it in-place? What is this saving precisely? >>>> >>>> >>>> >>>> On Thursday, August 11, 2016 at 4:05:57 PM UTC-6, Kasey Speakman wrote: >>>>> >>>>> Actually, I'd probably use a List instead of Maybe on the immediately >>>>> returned event(s). >>>>> >>>>> doSideEffects : Act -> Model -> (List Evt, Cmd Evt) >>>>> doSideEffects act model = >>>>> case act of >>>>> UpdateCustomer customer -> >>>>> ( [ CustomerUpdateRequested ] >>>>> , callServerWithCustomer customer >>>>> ) >>>>> >>>>> ... >>>>> >>>>> updateModel : Evt -> Model -> Model >>>>> ... -- implementation as previous >>>>> >>>>> update : Msg -> Model -> (Model, Cmd Msg) >>>>> update msg model = >>>>> case msg of >>>>> Action act -> >>>>> let >>>>> (events, command) = doSideEffects act model >>>>> in >>>>> (List.foldr updateModel model events, Cmd.map Evt command) >>>>> >>>>> Event evt -> >>>>> (updateModel evt model, Cmd.none) >>>>> >>>>> >>>>> >>>>> On Thursday, August 11, 2016 at 4:26:03 PM UTC-5, Kasey Speakman wrote: >>>>>> >>>>>> Yes, that was the goal. That way the UI state is utterly >>>>>> deterministic / reproducible in isolation of all outside services. >>>>>> >>>>>> That's a good point on the race conditions. I only use Cmd.batch >>>>>> because it's the facility that came to mind. (I'm still getting >>>>>> acquainted >>>>>> with Elm.) I don't know if Cmd.batch makes any ordering guarantee. >>>>>> >>>>>> If not we'd be more or less back to square one. Abuse `update` to do >>>>>> both things. >>>>>> >>>>>> doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt) >>>>>> doSideEffects act model = >>>>>> case act of >>>>>> UpdateCustomer customer -> >>>>>> (Just CustomerUpdateRequested, callServerWithCustomer customer) >>>>>> >>>>>> ... >>>>>> >>>>>> updateModel: Evt -> Model -> Model >>>>>> ... -- implementation as previous >>>>>> >>>>>> maybeUpdateModel: Maybe Evt -> Model -> Model >>>>>> maybeUpdateModel evtOpt model = >>>>>> case evtOpt of >>>>>> Nothing -> >>>>>> model >>>>>> >>>>>> Just evt -> >>>>>> updateModel evt model >>>>>> >>>>>> update : Msg -> Model -> (Model, Cmd Msg) >>>>>> update msg model = >>>>>> case msg of >>>>>> Action act -> >>>>>> let >>>>>> (eventNow, command) = doSideEffects act model >>>>>> in >>>>>> (maybeUpdateModel eventNow model, Cmd.map Evt command) >>>>>> >>>>>> Event evt -> >>>>>> (updateModel evt model, Cmd.none) >>>>>> >>>>>> So this should apply an event immediately if one is needed for the >>>>>> action. But it still keeps the model updating events separate. >>>>>> >>>>>> These immediate events would be seen by a userland event-store >>>>>> implementation (which is underneath updateModel), but I bet the TTD >>>>>> wouldn't see it since it doesn't come from Elm. >>>>>> >>>>>> On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote: >>>>>>> >>>>>>> So you really are wanting to hard device events into two different >>>>>>> ones, those that can *only* alter the model, and those that can *only* >>>>>>> send >>>>>>> commands (which may call ones that alter the model). Unsure if it >>>>>>> might >>>>>>> actually happen but might have to take into account possible race >>>>>>> conditions for if other messages appear before your other expected ones >>>>>>> are >>>>>>> processed through? Easier to do that atomically all at once? >>>>>>> >>>>>>> >>>>>>> On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman >>>>>>> wrote: >>>>>>>> >>>>>>>> doSideEffects above would also have to map Cmd Evt to Cmd Msg. >>>>>>>> >>>>>>> -- 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.
