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.