Think we posted replies about the same time. For it to work, I think Msg 
alone would not suffice. There would have to be two message types.

On Thursday, August 11, 2016 at 1:37:06 PM UTC-5, OvermindDL1 wrote:
>
> So it seems that you would have something like a `commands` callback send 
> out commands, one of those would be a command just for sending messages to 
> `update` without sending the original message?  (Also, it is already easy 
> to make commands from messages although Cmd.fromMsg would be shorter).  So 
> you are thinking of something like:
> ```elm
>
> commands : Msg -> Model -> Cmd Msgcommands msg model =
>   case msg of
>     Something blah -> Cmd.batch
>       [ doSomething
>       , Cmd.fromMsg MyUpdateMsg blah
>       ]
> update : ChangeMsg -> Model -> Modelupdate msg model =
>   case msg of
>     MyUpdateMsg blah = { model | blah = blah }
>
> ```
>
> I am unsure about making model changes be a command like that to be 
> honest.  I'd probably opt for something more like:
> ```elm
>
> commands : Msg -> Model -> Cmd Msgcommands msg model =
>   case msg of
>     Something blah -> Cmd.batch
>       [ doSomething
>       ]
> update : Msg -> Model -> Modelupdate msg model =
>   case msg of
>     Something blah = { model | blah = blah }
>
> ```
> Where the commands happen first then the model update, however you will 
> often have to do the same calculations in both to figure out something when 
> a message causes both (as some of mine do), which is duplicating effort.
>
> Something that might work that I could see would be something like with 
> the filters callback I propose:
> ```elm
>
> filters : BaseMsg -> Model -> ( Msg, States Model Msg )filters msg model =
>   case msg of
>     ReceivedAMsg blah ->
>       ( Something (blah+42), States.enableAll )
> commands : Msg -> Model -> Cmd Msgcommands msg model =
>   case msg of
>     Something blah -> Cmd.batch
>       [ doSomething
>       ]
> update : Msg -> Model -> Modelupdate msg model =
>   case msg of
>     Something blah = { model | blah = blah }
>
> ```
> But even that does the returning two things that you mention but in 
> filters, although I think they are inextricably tied together so they make 
> sense, maybe change `filters` to a different API like:
> ```elm
>
> filters : BaseMsg -> Model -> States Model Msgfilters msg model =
>   case msg of
>     ReceivedAMsg blah -> States.enableAll |> States.sendMsg (Something 
> (blah+42))
>
> ```
> Although then you have to pass forward every single message manually, 
> which might not be a bad things all considered, but definitely more wordy 
> and not really any more clear.  Maybe make `BaseMsg` just be `Msg` again 
> and have States control whether the original message is overridden or not, 
> that seems more clear to me, if no override is specified for the message 
> then it just passes through the original.  I still do not think I like that 
> though.
>
> Cannot think that commands could be a one-off subscription either.
>
> Eh, I am not really sure, decoupling Commands from the Updates is going to 
> cause a lot of code duplication, which you could resolve via a filters 
> function but then you get a lot more Message types, which although would 
> make things clear, not sure of how it should follow out to the end there 
> yet...  Maybe if filters had a way to send out more messages than just one, 
> or different types of messages...
>
>
> On Thursday, August 11, 2016 at 12:03:47 PM UTC-6, Kasey Speakman wrote:
>>
>> It was just something that bugged me when I first saw it in the examples, 
>> and I just came to the realization of why. And I am wondering out loud what 
>> it look like if they were separate things.
>>
>> In your example case, you could make a 3rd command that did the issued a 
>> new message InfoConnectIdAssigned to separate the model bit out. The 
>> tradeoff is isolation of model changes vs increased boilerplate (issuing a 
>> no-effect command). I think a shortcut method could be in order like 
>> Cmd.none, but something like Cmd.fromMsg.
>>
>> On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:
>>>
>>> I guess what you are proposing is separating a Message into a 'commands' 
>>> and 'update' callbacks?  That could work well too...  I could add that as 
>>> an option to my ProgramEx testing library (where I test with extra 
>>> callbacks) if you want to play around with it?  Do you propose that 
>>> `update` would be `Msg -> Model -> Model` and `command` would be `Msg -> 
>>> Model -> Cmd Msg, running in sequence of command before update?  I can see 
>>> a lot of them having a lot of duplicate code though, but I guess that could 
>>> be removed from my currently testing `filters` callback to clean up the 
>>> message into more pure stateful messages.  Though if I did that I really 
>>> think I would want to make two different message types, one for filters and 
>>> one for consuming, however that may make larger API changes than would be 
>>> easy...  What precisely would you want it to look like?
>>>
>>>
>>> On Thursday, August 11, 2016 at 11:48:21 AM UTC-6, OvermindDL1 wrote:
>>>>
>>>> Just as an aside, but I quite often return a mutated model *and* 
>>>> commands, such as this for the shortest example I am finding:
>>>> ```elm
>>>>
>>>>             InfoConnect uid ->
>>>>                 ( { model | uid = uid }
>>>>                 , Cmd.batch
>>>>                     [ connect_roomlist 0
>>>>                     , connect_roomlist uid
>>>>                     ]
>>>>                 )
>>>>
>>>> ```
>>>> So when we connected to the server, got an InfoConnect message back 
>>>> with the unique ID of the user, they then are allowed to connect to both 
>>>> the public and their personal room lists, so I submit those connection 
>>>> requests.
>>>>
>>>>
>>>> On Thursday, August 11, 2016 at 11:37:48 AM UTC-6, Kasey Speakman wrote:
>>>>>
>>>>> Hi all,
>>>>>
>>>>> I'm getting to know Elm. I recently read this article 
>>>>> <http://marcosh.github.io/post/2016/07/09/elm-event-sourcing.html> 
>>>>> about event sourcing in Elm. Essentially, the time-traveling debugger is 
>>>>> event sourcing. But it's a pattern that could be used in an app for other 
>>>>> great things. (Lots of literature on that in the internet. One particular 
>>>>> interest of mine is producing a complete failing use case from live 
>>>>> running 
>>>>> app -- it's just all the events. Obviously wouldn't work for real-time 
>>>>> apps... too many events... but for most of mine it would.)
>>>>>
>>>>> However, one thing that is a hindrance (to the TTD as well) and that 
>>>>> has always bothered me about the Elm examples is this signature.
>>>>>
>>>>> update : Msg -> Model -> (Model, Cmd Msg)
>>>>>
>>>>>
>>>>> Because an update returns both a Model and Cmd, for instance, the 
>>>>> time-traveling debugger "...needs to tell the runtime not to perform any 
>>>>> side-effects during replay to avoid these issues"[1]. An event-sourcing 
>>>>> implementation would have to figure a way to do the same without runtime 
>>>>> hooks.
>>>>>
>>>>> This part of the architecture mixes concerns by returning a model and 
>>>>> effects. And usually (not always) you see each message returning one or 
>>>>> the 
>>>>> other, not both. From the docs:
>>>>>
>>>>> update : Msg -> Model -> (Model, Cmd Msg)
>>>>> update msg model =
>>>>>   case msg of
>>>>>     Roll ->
>>>>>       (model, Random.generate NewFace (Random.int 1 6))
>>>>>
>>>>>     NewFace newFace ->
>>>>>       (Model newFace, Cmd.none)
>>>>>
>>>>>
>>>>> Here, Roll does an effect, but nothing with the model. NewFace returns 
>>>>> a new model but no effects. You do have cases where you want to update a 
>>>>> UI 
>>>>> element when an outside effect happens, like activating a spinner when 
>>>>> sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
>>>>> One that immediately returns a separate message affecting the model's 
>>>>> spinner. And another to do the HTTP request.
>>>>>
>>>>> So it seems to me that there are really two concepts at work here. 
>>>>> There are "events" which have happened and can be used completely 
>>>>> deterministically, and there are commands which interface with the 
>>>>> outside 
>>>>> and may produce events.
>>>>>
>>>>> I think it's something worth pointing out and considering for the 
>>>>> future. What do y'all think?
>>>>>
>>>>> Kasey
>>>>>
>>>>> [1] source <http://debug.elm-lang.org/>, section "How Elm makes this 
>>>>> possible", subsection "Purity", last paragraph
>>>>>
>>>>

-- 
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