Btw, the "event compression" only works for sequential messages of 
identical type (assuming idempotence). So Incremented 1, Incremented 2 
could compress to just Incremented 2, but Incremented 1, Decremented 0 
could not compress obviously. The counter example is bad here as it doesn't 
express how different the events can affect the model in orthogonal ways... 
all these events are affecting the same piece of data, so they could all be 
compressed down to the last event. But that's not a guarantee you can make 
in general.

On Wednesday, August 17, 2016 at 1:22:20 PM UTC-5, Kasey Speakman wrote:
>
> Thanks for the comment!
>
> - I think it would be better to store in the parameter of the Fact's the 
>> increment, and not the state of the application. It looks to me that you 
>> are mixing two concerns, i.e. the state of the applications and the events 
>> that happens to it
>>
>
> The counter example is too simple to properly express this, but the Fact 
> doesn't store the whole application state, only data applicable to the 
> event. For instance, imagine the apply function was `NameChanged name -> 
> {model | Name = name }`. It doesn't change the whole model, but it changes 
> a part of the model it applies to. In the counter example, the part 
> unfortunately happens to be the whole model.
>
> If the data instead carried the increment instead of the final value, then 
> the logic of how the counter works is decentralized... part of it (model + 
> 1, model - 1) is in the apply function now. You wouldn't put other kinds of 
> logic in the apply function (e.g. HTTP call). Storing the increment in the 
> event is also no longer idempotent. Idempotence is typically something you 
> want on the back-end because it allows you to deliver a message more than 
> once with no ill effects. However, it is valuable in the UI because it 
> could allow you to "compress" events to prevent history from getting too 
> large. For example, say someone spammed the Increment button 100 times, 
> giving you Incremented 1... Incremented 100. When applied in order, the 
> result is the same as just applying the last event of the same type; 
> Incremented 100. Now you are loosing history that way (and undo-ability), 
> but you can choose to make that trade-off for space without a deep 
> understanding of the events. In order to do the same if you were carrying 
> the increment, you would have understand what the event was doing and apply 
> logic to the messages to figure out the "compressed" message's data (add 
> the increments), so you have another place where you are putting logic.
>
> However, the compression benefit is probably mitigated by Elm not having a 
> way to determine if two union cases are the same type (no metaprogramming 
> that I know of). You'd have to manually check for specific sequential 
> messages you want to compress.
>
> - if I'm not mistaken, from you implementation it seems that only Act's 
>> (and not Fact's) can generate new Cmd's. I think that is some applications 
>> there could be the need to react automatically with a new Cmd to some 
>> events that happened
>>
>
> This (events to commands, aka Process Manager aka Saga) is not covered in 
> my example. Seems like the easiest way to accomplish this is to have 3rd 
> method which is called after `apply` that checks the model (or the part 
> where the process manager has been keeping track of state) to see if a new 
> Act needs to be issued. Maybe something like this:
>
> propose : Model -> Cmd Act
> propose model =
>   if model.orderProcess.orderPlaced && model.orderProcess.paymentFailed 
> then
>     CancelOrder model.orderProcess.orderId |> actCmd
>   else if model.orderProcess.orderPlaced && model.orderProcess.paidInFull 
> then
>     ShipOrder model.orderProcess.orderId |> actCmd
>   else
>     Cmd.none
>
> That's assuming your `apply` method is updating the model with those flags 
> in response to the appropriate events. Of course, this particular logic 
> doesn't make sense on the front end, but this type of pattern could.
>
> On Wednesday, August 17, 2016 at 11:32:27 AM UTC-5, Marco Perone wrote:
>>
>> Hi!
>>
>> I was eventually able to read carefully the thread and give some thoughts 
>> about it.
>>
>> @kasey, I had a look to your Gist and it looks really interesting! Some 
>> notes about it:
>>
>> - I think it would be better to store in the parameter of the Fact's the 
>> increment, and not the state of the application. It looks to me that you 
>> are mixing two concerns, i.e. the state of the applications and the events 
>> that happens to it
>>
>> - if I'm not mistaken, from you implementation it seems that only Act's 
>> (and not Fact's) can generate new Cmd's. I think that is some applications 
>> there could be the need to react automatically with a new Cmd to some 
>> events that happened
>>
>> To make everything clearer in my mind, I wrote my own implementation of 
>> something similar to what you did. You can find it here:
>>
>> https://github.com/marcosh/elm-escqrs/blob/master/EsCqrsMain.elm
>>
>> It should be just a functional transposition of a standard es/cqrs 
>> architecture (I actually used also es/cqrs jargon), adacted to the Elm 
>> Architecture.
>>
>> I'd really like to know what you think of it. Let me know if something is 
>> not clear enough
>>
>> On Sunday, August 14, 2016 at 7:37:25 AM UTC+2, Kasey Speakman wrote:
>>>
>>> So, I made a Gist 
>>> <https://gist.github.com/kspeakman/109475ecdd3068a022b59f7f73c9485a> of 
>>> the helper stuff which splits Facts and Acts. I call the helper Factor... 
>>> (Fact or Act ~=> Factor). There is a subsequent comment with an example 
>>> program explaining the helper's usage.
>>>
>>>

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