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.