I entirely missed that.  ^.^

Hmm, is interesting.  Flags take Json'able types so those would not be 
passable there, would need to convert first, but not hard.



On Friday, August 12, 2016 at 12:53:36 PM UTC-6, Kasey Speakman wrote:
>
> I did that if you look at link to marcosh's github I posted above.
>
> On Friday, August 12, 2016 at 1:50:12 PM UTC-5, OvermindDL1 wrote:
>>
>> Hmm, I'd be curious if you could whip up a full compileable example, say 
>> a Multi-Counter project example we could paste into elm-try.  Perhaps mark 
>> things that are boilerplate and could be hoisted out to a parent library 
>> too so we can ignore those?  :-)
>>
>>
>> On Friday, August 12, 2016 at 12:15:20 PM UTC-6, Kasey Speakman wrote:
>>>
>>> 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.

Reply via email to