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