These are chat archives for jdubray/sam

10th
Feb 2016
Jean-Jacques Dubray
@jdubray
Feb 10 2016 05:11
I started to discuss the relationship between SAM / Redux / Redux-with-Sagas and Cycle.js in the sam-architecture room
gmariani
@gmariani
Feb 10 2016 14:46
Hello, I'm trying to wrap my head around thie SAM concept. I would say I'm your target market here, a front-end developer who wants to use simple javascript rather than large frameworks. What I'm struggling with is how to convert your sample into a real world application. I don't follow the TLA+ nomenclature that well so please correct my misunderstandings. With that said, this is my basic understanding of SAM:

`// SAM
// V = S( vm(M.present(A(data)), nap(M)))
// Action/NAP -> Model -> State -> View

// Model
// Contains data, has no knowledge of state representation or nap
// Based on Actions, has logic to modify data then triggers State render

// View
// Contains only UI, has no logic

// State
// Based on Model, has logic to decide which State it is in and View to render

// Actions
// Logic to handle interaction, process data before presenting to Model`

So i'm trying to build a simple user management form. It lists users, you can add, edit, delete, and it has to talk to the backend to update the database. So I would think it would need the following states: ready/init, add, edit, delete, processing. Processing being used while the data is being updated to the database and before we have a result of success or not.
gmariani
@gmariani
Feb 10 2016 14:51
In your rocket example, each state re-rendering all the HTML which I think is a bit much, especially as a program gets larger. But where would I put logic to add/remove listeners on the generated view? Would that go in the state after the view spits out the content to be rendered? What happens when you just want to update a view with new data from the model? I don't want to destroy everything redraw it and re-add listeners every time. Also in your example you called the action function where the form submits. But if there are two buttons that doesn't work anymore.
Again, I really love the concept of SAM, but trying to translate it into a real-world working scenario
Heck, I'm also trying to figure out how confirmation/alert/info modals fit into all of this as well. Since they would be in between states, or in addition to a state at any point. Say when a user is deleted, it would call actions.delete but I would want a confirmation to popup before actually deleting. So would that logic be in actions? To trigger the modal, get confirmation and then trigger the model change?
Gunar Gessner
@gunar
Feb 10 2016 16:15
So i'm trying to build a simple user management form. It lists users, you can add, edit, delete, and it has to talk to the backend to update the database. So I would think it would need the following states: ready/init, add, edit, delete, processing. Processing being used while the data is being updated to the database and before we have a result of success or not.
Are theses states like routes in your example?
In your example/app, are these states like routes?
Jean-Jacques Dubray
@jdubray
Feb 10 2016 20:40
@gmariani happy to help. The first thing I would emphasize is don't get caught up on state machine. It is important to keep it in mind because when you need it, that's going to prove handy, but you don't need it that often. The state machine example is here to show that the SAM pattern "scales" to real-world application, that it can deal with extremely complex logic without losing a bit, but at the same time you can use it without it, when you don't need it.
From the View perspective, SAM works like React: V = Sr(M), the problem with react.js is precisely because they don't have the other aspects clearly defined A,M,S, nap, you end up creating a massive mess that you quickly regret
Not sure if you saw that other snippet of code I published, a contact me form: https://bitbucket.org/snippets/jdubray/jna7B/sam-sample-app-on-nodejs

// Action/NAP -> Model -> State -> View

nap() is invoked by the state after the view is rendered

nap invokes the "next-action" which generally triggers changes to the model, unless you want to create a repeating action (which is not impossible) until something else happens. But again, you don't need nap() that often. You can easily know when you need it, in general you will feel that the model needs to call an action, or an action needs to call the model.
Jean-Jacques Dubray
@jdubray
Feb 10 2016 20:46
That has been the problem of MVC, the controller would then to "nap" arbitrarily in your code (or any architecture that is not based on TLA+). It's easy to see that if you nap() at the wrong time, from the wrong place, bad things will happen.
So nap() is important to keep in mind, but you will rarely need it. You may ignore it for now.
gmariani
@gmariani
Feb 10 2016 20:49
I'm not overly familiar with Node but I'll check it out, i'm sure i'll have more questions, thanks!
Jean-Jacques Dubray
@jdubray
Feb 10 2016 20:49
Now, going back to the user management app you are building, I see the following states:
  • display (with add and delete actions, there could be also page+/- actions)
  • edit (submit changes)
To add a user, I am assuming there is always an empty row at the end of the list where you can type values and submit these value to create a new user
So the model would look at bit like that:
{ display: true, edit: false, users: []}
the user structure would be something like:
{ id: '', name: '', tel: '', city: ''} whatever
There would be the following actions:
  • init
  • add
  • delete
    ( page +/-)
Jean-Jacques Dubray
@jdubray
Feb 10 2016 20:55
You don't have to render the entire page, functions can be designed as components, actually I would highly recommend doing that.
The question then becomes how much appetite do you have to position these components manually or whether you prefer using a virtual-dom
I am not convinced you need a virtual dom, frameworks tend to deliver less value than they claim they do because of their one-size-fits-all-black-box behavior. I like to retain as much control as I can as long as the amount of code I write is reasonable.
Depending on how comfortable you are with HTML / Javascript, I would try to render the page entirely first in these two states and then breaking it into components that change and then mount the state representation in the page furniture. That's generally trivial.
Would that answer your question?
gmariani
@gmariani
Feb 10 2016 21:02
That does help break out the states better. I agree on the add user row, that's a bit simpler than what I had in mind. I currently use the same edit form as I do for add, except the labels change. In my head i figured there were two different states, not so as you explained.
Jean-Jacques Dubray
@jdubray
Feb 10 2016 21:14
They could! you could have an "add" button on the display state that opens up a new form, in that case the component would return nothing in display state and a form in "add" state.
The beauty I see in React.js (and hence in SAM, which does is with plain javascript function) is that you can now think about your UI in terms of components and states (each component individually being state aware), rather than in pages. This is a much cleaner way to build your UI (including very complex UIs) rather than reasoning at the page level / template level.
gmariani
@gmariani
Feb 10 2016 21:14
With that said, what i still don't feel comfortable with is the actual organization of logic. I haven't had a chance to look over the Node example yet (i'm at work right now). But where should UI logic live in order to stay true to SAM. I was working a bit more on my application (skipping SAM structure until I understand it better) and had some AJAX functions on button interactions. I pondered on that for a bit, does that go in the Model after an action triggers it or in the action and only updates the model once the result is available? The latter I'm thinking? There seems to be a lot of non-important miscellaneous logic that doesn't fit neatly into the SAM model (alerts on form validation, ajax calls, etc.)
Jean-Jacques Dubray
@jdubray
Feb 10 2016 21:16
On the paper you'll see on figure 9 that you can compose easily SAM instances, especially between client and server. So what you call "UI logic" would be in the client instance of SAM, but the beauty is that the same "view" can wire server actions as well, you break nothing in doing so. You just have to clearly decide how the client side model is passed to the server and how the server state representation gets propagated to the client. I favor a nap() call to pass model property values to the server and a full rendering of a new state representation initiated from the server. That more fine grained behavior are possible as well, including simple model synchronization
The key is truly to keep the "View" (aka State Representation) logic free. It just triggers actions. You'll see that's a much cleaner way to think about front-end architecture
This is what React got completely wrong, this is what Cycle.js is doing separating logic from effect. This is really what you should aim at
gmariani
@gmariani
Feb 10 2016 22:01
about to head home, but where is figure 9 that you are referring to?
Jean-Jacques Dubray
@jdubray
Feb 10 2016 22:12

In the article

fig9