These are chat archives for jdubray/sam

Dec 2018
Jean-Jacques Dubray
Dec 02 2018 01:53
@nerdo I use the word "state" for a couple reasons:
  • to make a clear difference between Model and State Representation, so you should really think of State as State Representation which is always computed from the Model
  • to also emphasize that we need to have a clear view of the Control State which is also computed from the Model.
I don't think it would be fair to compare it to MPV.
  • SAM has a unidirectional dataflow
  • the State Representation is separate from the model
  • The next-action-predicate (NAP) provides an a good factoring of automatic actions
  • SAM is completely decoupled from the view and promotes a functional (i.e. stateless) representation
Dannel Albert
Dec 02 2018 12:59
@dagatsoin Now I see why you renamed it that way. For some reason it took me a while to
Whoops, sorry, I’m on mobile and the interface is a bit wonky
It took me a while to realize that all these things, State, Model, are functions. Using “computeState” does clarify it in my mind quite a bit more
@jdubray Thanks for clarifying. I think I understand the pattern now, but I’ll find out for sure once I start writing some code. SAM may be the missing piece of the puzzle I’ve been looking for to decouple business logic from the view and have a truly clean architecture...
Dannel Albert
Dec 02 2018 13:51
I have another question. In the description of Actions on, the first sentence reads “Actions are pure functions which accept a dataset (event) and return a dataset (proposal). ” but then in the code it says that it doesn’t return anything because of the reactive loop. I’m assuming the code is correct as the action would be presenting thr change to the model, right?
The other question I have relating to that is if the action does present the change to the model, would it be wrong for the action to return a promise that would be rejected if the action was rejected (either by itself or the model didn’t accept the proposal). If the promise were to resolve it would mean it got accepted, but wouldn’t actually resolve to any specific data beyond that
That way the view could do something like show a loading indicator as it waits for an action to be fulfilled
Jean-Jacques Dubray
Dec 02 2018 15:57

@nerdo sorry, sometimes I am not very clear. It depends how you factor the pattern. The "wiring" of the pattern is a reactive loop, but because of that wiring an action would not return anything, it would simply pass a proposal to then in response to an event. The true definition of an action (from TLA+) is that it's a pure function that takes non prime variable and return prime variables, which I interpreted as taking an event and create a proposal (the concept of prime variables is key and worth spending some time to understand as most of us would be unfamiliar with it). So here is how it looks in code:

function myAction(event) {

myActionProposal is the "true" action, while myAction is the wired version of that true action.

Daniel Neveux
Dec 02 2018 16:05
the current description of the pattern states only on the data path. In that, the pattern is implemented as a reactive loop.
But nothing prevents you to add some features like a container which has a more global scope for purpose like warn the view of the processing or rejection of an intent.
It is outside the scope of SAM imho.
Jean-Jacques Dubray
Dec 02 2018 16:17
I don't think a promise would work well because accept/reject can be partial. I use these words to show that the action is not in control of the mutation, unlike in the case of MVC. At first it seems a bit redundant, but in practice you will experience the power of decoupling the computing of the proposal from the business logic of the mutation.
If you want to write a large application you will need to choose a component model. I have documented one of them, it has worked well for me, but you should think if that's what you want to do.
After decoupling events from proposals, the second key decoupling of the pattern is isolating mutations from any other kind of business logic (computing proposals, computing state representations or computing next-state actions).
Personally, I prefer a reactive loop implementation, I am not certain promises would add much to the wiring, but I may be wrong.
I have created a sample of a loading indicator using an old version of react. I believe this can be easily adapted to any framework.
Jean-Jacques Dubray
Dec 02 2018 16:23
@dagatsoin yes, a container works too, I just want to point out that the pattern works with no library at all, it is of course no scalable to a large application and at a minimum you will need a component model and possibly a container as well. I have created a micro container with SAM-SAFE.
The pattern can easily be refactored at any time (because of the decoupling) and pieces can move to the server or back to the client as needed, you can even easily weave 3rd party actions, not to mention create parent/child SAM instances (but don't abuse it).
Dannel Albert
Dec 02 2018 19:52
@jdubray @dagatsoin Thanks for your responses. Your comments confirm my thoughts, including the partial rejection of a proposal. I don’t know how feasible (or useful) it would be but the thought of having the model also return a promise crossed my mind, though I don’t know how a partial acceptence would be handled. In most cases I think it would just be useful for the view to know if processing is in progress or complete (rejected, accepted, or something in between) In any case I really just wanted to clarify the point about the return value and see if it actually was a necessary constraint of SAM.
Daniel Neveux
Dec 02 2018 20:05
In this case I think that reporting the generic result of the proposal in the State should be enough. As your View will react to this intent result.
The problem with returning a promise from the model to the view is that you will break the decoupling view/model. In that case it is still the responsability of the SAM loop to impact the next State.