These are chat archives for jdubray/sam

29th
Oct 2016
Fred Daoud
@foxdonut
Oct 29 2016 00:41
@metapgmr_twitter when you separate the model from the state representation, i.e. the function that shapes the model into something else that will be used to render the view (computed/derived properties), how do you do it in code? If you have S(M), how do you produce the result (in code)? If you add properties to M, then you are mutating the original model.
If you produce a new object, then it's almost like "immutability", i.e. always creating new objects for every step.
What do you do, practically, in JS (or TS)?
That is, if, say, some of the properties of the model are actually ok to be used by the view as-is, but others are not, and need to be shaped by the State representation.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 01:07
In theory, no model properties can be assigned in the state function. The state function computes the state representation from the model property values but that state is transient. Once it has been displayed nothing remains in the state function, it is a pure function. In SAFE I keep track of the allowed actions in the current state/step, but that's an optimization, we could theoretically compute the allowed action in the dispatcher.
It's a bit like MobX computables. That's what the State function is and that's why I often say the model is missing in MobX. You have the actions and the state functions but no model (Michel wires actions to computables).
The view in MobX is wired to the observables, but again, that should be decoupled from the model.
In general what I do in the state function is instantiate a state representation object
state.representation = (model) => {
    var representation = 'oops... something went wrong, the system is in an invalid state' ;

    // This is where the State decides which component of the View should be displayed
    // here the we designed the application with a single (control) State (~page)
    // In a real-world application there would be many control states and which
    // would trigger the display of different components    
    if (state.ready(model)) {
        representation = state.view.ready(model, actions.intents) ;
    } 

    // complete the reactive loop
    state.view.display(representation) ;
} ;
I also use status function state.ready(model) to decide on the structure of the state representation
There is not a case where the state function would assign some properties of the model.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 01:14

some of the properties of the model are actually ok to be used by the view as-is, but others are not, and need to be shaped by the State representation.

The state function helps with the decoupling V-M, since we can shape the model into properties of the view, sometimes, they match, sometimes you need to do some computation

You can also see that nap() would not be well handled at the level of the view. It's better to trigger nap() at the state function level.
Fred Daoud
@foxdonut
Oct 29 2016 01:25
but that state is transient. Once it has been displayed nothing remains in the state function, it is a pure function
That makes more sense to me now. So the computation of derived properties would be done in the same function that produces the representation, in temporary variables, is that correct?
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 01:29
yes, absolutely.
Fred Daoud
@foxdonut
Oct 29 2016 01:30
I guess I was thinking more in terms of a separate function, S(M) that produces the state, and then the view as V = f(S(M))
Thank you Jean-Jacques.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 01:35
You can have multiple articulations State function, View and what I call "theme". In case of Angular and React the state function's role is to produce the props and let the framework do the rest.
You are welcome!
Fred Daoud
@foxdonut
Oct 29 2016 01:42
Reason I ask, is that I am considering making the State function more prominent in Meiosis. There is already a View function, so I think it would be a better fit for the State function to derive and produce the State from the Model, and that would be passed to the View function for rendering.
The added benefit would be to enable seeing this object, the result of S(M), independently of the view. Would be good for debugging and testing.
I still think this is in line with SAM, i.e. the model M is the single source of truth. S(M) produces the data in the shape that the view needs, and V is the function that produces the view.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 01:48
as I said, the format of the state representation might to dependent on the framework. The most important aspect is to have an area similar to MobX computables where you can derive component properties from the model to avoid shaping the model with the component's structure.
The other aspect is that the "state" of the application might decide which view structure to display (say something like a page in the old days). IMHO, it's preferable to have this kind of decision made by the state function rather than the View.
Fred Daoud
@foxdonut
Oct 29 2016 02:10
Agreed
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 02:12
I would argue, the whole point of the pattern is to isolate the mutation of the application state, to the lowest level possible and push logic not involved in mutation either in the actions or the state.
Fred Daoud
@foxdonut
Oct 29 2016 02:13
When you say application state, is this the model, or the data produced by the state function?
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 02:13
sorry, the model...
at least that's the model that defines the boundary of application state mutation.
Fred Daoud
@foxdonut
Oct 29 2016 02:14
No apology needed, it's fine, I just wanted to make sure I understood correctly. Because, for example, say you have a tabbed view and you need a property to indicate which tab is active. Would this go in the model?
It's a property relating to the view, but I would still call it part of the application state. Further, if this property was not in the model, but rather, derived by the state function, then what property(ies) of the model could the state function use to determine which tab is active?
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 02:18
Only if it is material to the application state (sorry). You could think that this is part of the private state of the tab component. There could be cases where the order in which you go through the tab is relevant to application state, or for performance reason, you may not want to render all the tabs at the same time.
I'd say it is either in the model or it is in the view component. You really want to avoid any "state" in the "state" function (sorry).
Fred Daoud
@foxdonut
Oct 29 2016 02:21
Everything you said makes sense to me, except for the last part for which I am not sure:
You really want to avoid any "state" in the "state" function
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 02:23
I meant the application state is in the model, the state function is a pure function. Even though it could be tempting to store the current tab in the middle (state function).
Fred Daoud
@foxdonut
Oct 29 2016 02:25
Ah, I see. Yes, I absolutely agree with that. I thought you meant that the state function cannot derive any state values. But yes as a pure function the computed values that it derives from the model may have to do with the "state", such as "allCompleted: true" which can be computed from the todos in the model. I think we are on the same page.
Zach Dahl
@schtauffen
Oct 29 2016 02:36

I have a remaining question regarding async actions: In the video of netflix's use of Rxjs + redux, one of the benefits of the epics is that you can cancel the async event (note: not just ignore the result, cancel the event to prevent any further activity over the network);

how would this look in SAM, considering we want the async actions to be "stateless" ?

I also wonder how routing would work in SAM. Is it like a second "model" that state has access to, but doesn't necessarily have to be stored on model?
Or would it be best if the implementation fired events which the model accepts or rejects before letting state decide if it needs to pushState and update relevant paths?
Is it a semantic violation for the model to be unaware of the router?
Edward Mulraney
@edmulraney
Oct 29 2016 08:47
@metapgmr_twitter "You really want to avoid any state in the state function" seems the state funcion is poorly named. really its just a transformation of the model, you can pick, enrich etc.
hence why redux called it "mapStateToProps"
Fred Daoud
@foxdonut
Oct 29 2016 12:47
@schtauffen for routing, what I am doing is having 2 types of proposals: LocationChange (for a user action that triggers a url change), and UrlChanged (for the browser's back button and the initial url): https://github.com/foxdonut/meiosis-examples/blob/library/examples/library/src/client/common/urlHandler.ts#L72-L77
I'm using history to handle the location bar, and crossroads to parse the url. I am still at the beginning of the example (work in progress), so right now the url just determines which tab is active.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 14:16
@schtauffen SAM doesn't work well when some valuable state leaves in other parts of the code. If you truly want to "cancel" the action then you have another instance of SAM managing the state of the action and nap() should be in the position to send a cancellation action to that SAM instance (yes SAM works really well when it comes to inter-process communication). The other case where SAM would not work well is, if you wanted to cancel a long running calculation within an action. For many scenarios, ignoring the proposal is good enough. In case of Netflix, there may even be value to keep that proposal because the user might want to navigate back to that view.
@schtauffen @schtauffen When you look at "routing" closely, it's no different than a mouse action, you just have to translate that into a proposal to the model. If your SAM instances run on the server that's no big deal, when it runs on the client, you need a routing library that will trap the request and route it as an event to the corresponding action. Sometimes routing means a whole new application state reconstructed solely from the path (eg /purchaseorders/1234), sometimes it is an action applied to the existing application state. Is that an ok answer?
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 14:26
@edmulraney My intent was to express that what we call "state" is not enough, a list of property values is not enough to access the application state. What you do is you access the state representation of the system and to do that you call a function on the model (the property values).
I talked with Dr. Lamport about that very point because you will notice than in every TLA+ sample there will be a special variable called PC (program counter, in reference/honor to Von Neumann), but in essence there is something beyond property values.
I understand your point but I don't have a good answer, other than perhaps calling it "State Representation" rather than "State". But for me that is the true "State" that you are looking for. Imagine, if I were handing you the property values of the model, you'd have to have some logic on your side that tells me if the car is "started" or "not". That would not work, right?
I was waiting for the community to grow a bit more to put it for a vote, personally, I don't care whether it is called PAL, SAM or something else. I did try to submit pal.js.org but could never get the pull request right, at a couple of tries I gave up.
I understand that this is maybe the most foreign concept to SAM, people can understand SAM/TLA+ definition of Action, MobX has the same definition but not Redux.
People can understand the delineation between action and model (proposal vs assignments)
But I would expect people to have difficulty getting familiar with the difference between model and state (representation).

https://en.wikipedia.org/wiki/Program_counter

Use of a PC that normally increments assumes that what a computer does is execute a usually linear sequence of instructions. Such a PC is central to the von Neumann architecture. Thus programmers write a sequential control flow even for algorithms that do not have to be sequential. The resulting “von Neumann bottleneck” led to research into parallel computing,[8] including non-von Neumann or dataflow models that did not use a PC; for example, rather than specifying sequential steps, the high-level programmer might specify desired function and the low-level programmer might specify this using combinatory logic.
This research also led to ways to making conventional, PC-based, CPUs run faster, including:

  • Pipelining, in which different hardware in the CPU executes different phases of multiple instructions simultaneously.
  • The very long instruction word (VLIW) architecture, where a single instruction can achieve multiple effects.
  • Techniques to predict out-of-order execution and prepare subsequent instructions for execution outside the regular sequence.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 14:36
I guess similar techniques can be applied to SAM (pipeline through different branches of the model), an action submitting multiple proposals, actions spawning future actions that will present their results to the model at a later time (for instance to pre-fetch additional data based on a user intent based on the most likely path). All this becomes possible because you have the notion of "linearized" your code.
Fred Daoud
@foxdonut
Oct 29 2016 14:51
@schtauffen indeed as @metapgmr_twitter said, I am trapping the event and translating it into a proposal: https://github.com/foxdonut/meiosis-examples/blob/library/examples/library/src/client/mithril/root.ts#L33-L38
As for location change, such as the browser back button, I am trapping that as well as per my previous code reference. It's working well, and makes routing a part of SAM/Meiosis like any other proposal, even works with tracing -- if you "rewind" with the tracer, you see the location bar and the view change accordingly.
routing.gif
Fred Daoud
@foxdonut
Oct 29 2016 14:56
Above is a demonstration, notice that the back button works, and that rewinding with the tracer also works, and the browser's location bar also changes accordingly.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 14:57
that looks fantastic! :thumbsup:
Fred Daoud
@foxdonut
Oct 29 2016 14:58
thank you!
@metapgmr_twitter I am working on updating Meiosis, as I mentioned, hoping to make State more prominent as you have suggested. I also want to reference the SAM pattern on the front page.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 29 2016 14:59
thank you!
I can only encourage you to use as many ideas as you want, and improve them too. What's exciting is that our industry has come up with a true replacement for MVC, thanks to React/Elm/Redux. Let's not be complacent and believe we are done, let's get it right, if SAM can help ask some good questions, great, but in any case, let's ask questions, let's not rely on one or two guys to define a practice that will be here for decades.
Fred Daoud
@foxdonut
Oct 29 2016 15:41
Well-said :thumbsup:
devin ivy
@devinivy
Oct 29 2016 15:51
:pray: