These are chat archives for jdubray/sam

7th
Apr 2017
Jean-Jacques Dubray
@jdubray
Apr 07 2017 03:16
@pfurini I took a look at datatables and I don't see why it would not work with vanilla.js/SAM
I'd be happy to help you build a PoC if you are interested
Paolo Furini
@pfurini
Apr 07 2017 06:10
@jdubray thanks, that'd be great! But I think I should try myself at first, just to grab the whole concept with a real example.. what I'd like to do is replicate the same sample grid with some interactions, both in vanilla js and in other UI frameworks (for example in React with the meiosis lib I posted before)
but.. if I find myself stuck on something, may I ask you for some guidance? I'll post my exercise in a gist or in a repo, just to share the (horrible) things I'll do.. :smile:
Paolo Furini
@pfurini
Apr 07 2017 15:35
@jdubray I was studying the fishing example (https://github.com/jdubray/sam-samples/blob/master/js-rectangle/rectangle.html) by follow along your 10 minute video about SAM.. but I found a bit of disconnection from the first 5 minutes (the diagram) and the code example, because of the different naming used (for example accept vs present for the model part)
This is very confusing for starters.. just my 2c
Paolo Furini
@pfurini
Apr 07 2017 15:42
and I have a newbie question about composition of the pattern in larger apps.. I imagine that every "component" (or just piece of app that can be isolated in terms of model data) could potentially have its own SAM container (much like this implementation for Mythrill https://mfeitoza.github.io/same-container/index.html), but what could be the best practice for wiring a lot of such components together? Just a parent SAM container that has a glue model and treats the view as a composition of sub-components like black-boxes?
Daniel Neveux
@dagatsoin
Apr 07 2017 15:44
Yes could be fine to clarify the composition with components tree. It is my next concern 😄
Jean-Jacques Dubray
@jdubray
Apr 07 2017 15:46
@pfurini yes, apologies, the naming has slightly evolved. Actions present a proposal to the model which accepts it. The main reason for this confusion is the similarities between SAM and the Paxos protocol which I identified after the fact. I first focused on TLA+ which has no such language (proposals, acceptors, learners...). Dr. Lamport is the author of both TLA+ and Paxos protocol. I felt Paxos provided maybe a cleaner wording.
I would not recommend using a SAM instance for each "component". SAM fully decouples the App logic from the View components. I would design them separately and then wire them. This is a bit unconventional, but having turned my back on OOP altogether, I feel that's the right approach. SAM is neither OOP nor FP. It's based on the semantics of TLA+ which I feel are a much better foundation to software engineering. It suggests a different grouping.
Paolo Furini
@pfurini
Apr 07 2017 15:51
But what about dynamic apps? I mean apps that are designed to be changed at runtime, for which components isolation is a must..
Jean-Jacques Dubray
@jdubray
Apr 07 2017 15:51
SAM instances can be composed in a parent/child relationship that works well, that's when you are executing a task that is somewhat ancillary to the main model and you just want a "submit" action that will create a proposal with the result of that task. Think of a complex wizard form.
You can still mount actions, acceptors (the blocks that update the model), State and Nap(), my advice is to think of the view components and the app logic as something separate even if sometime it would make them to have them work in lockstep.
SAM works well to implement dynamic apps, I don't see a contradiction. The State function is the one that is responsible for handing the dynamic aspects. It's actually very clean because the State function is responsible for, given a model (as property values) decide what "state" the application is in and rend it accordingly.
I think a lot of people in this forum like the model/state separation.
Paolo Furini
@pfurini
Apr 07 2017 15:56
I'm kinda a practical guy.. for now I'm only able to see the small picture, but not the "big" one I fear..
Jean-Jacques Dubray
@jdubray
Apr 07 2017 15:57
it's ok to ask question, we all learn. Happy to answer them.
Paolo Furini
@pfurini
Apr 07 2017 15:59
I mean, I'd like to see a practical example of dynamic composition like: I have a dashboard of X widgets, my client loads a new component plugin, that needs to consume model data, propose new actions, react, etc.
Paolo Furini
@pfurini
Apr 07 2017 16:04
I know maybe it's a silly example, but I can't formulate a better one now, it's a complex matter.. I just started a collaboration with a company that has written a framework to compose dynamic data driven apps (like CRM, ERPs etc.), and they used "classic" techniques on the client (JS), like MVC, services, dependency injection, etc. It's not a clean architecture, and it's somewhat limited, but if I wanted to try a new approach I must guarantee the same "dynamism"
Paolo Furini
@pfurini
Apr 07 2017 16:11
Like @dagatsoin asked few minutes ago, we are all more or less "concerned" with the composition of highly complex interfaces, and the "components tree" pattern, along with a blackbox approach on constructing them, is clearly the most natural approach on solving the problem.. I know there could be (which?) better ways of solving the composition problem, but I have yet to see a practical/large/production ready proposal for them
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:20
It's an important question. I'll prepare a little summary tonight, I don't have time now. But the best way to look at it is by thinking of you app as building blocks not "components"
for instance one action could trigger multiple acceptors in the model or multiple actions could send a proposal to the same acceptor.
Paolo Furini
@pfurini
Apr 07 2017 16:23

So when you say

SAM instances can be composed in a parent/child relationship that works well, that's when you are executing a task that is somewhat ancillary to the main model and you just want a "submit" action that will create a proposal with the result of that task. Think of a complex wizard form.

it's like having a "reactive SAM loop" nested into the main loop. So, I agree not calling them "components" (in the sense of a view component, like an autocomplete field), but they are in essence composable pieces of app logic

Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:24
Then you have concerns like "actions cannot logically be composed" that would break the pattern where a single step is action->model->state, a new action can only be triggered after that step completes.
yes, parent/child sam instances are logically composable and child instances are expected to be reused in different projects, or simply for clarity/cluttering of the parent model.
view components can be found in the examples in the theme.js file, and not surprisingly an app can work with different "themes".
Paolo Furini
@pfurini
Apr 07 2017 16:26
and it should be ok to reuse also the view? I'm thinking of plugin systems
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:26
yes, themes can be reused the other way. That's the State function that provides the glue, it "adapts" the model to the theme.
SAM is providing a 100% decoupling between view and model.
It would be strange to start coupling them in a "component"
Paolo Furini
@pfurini
Apr 07 2017 16:27
so one could potentially swap another view (theme) by adapting the state function
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:27
yes, or if the properties (signature of components) are compatible, you don't even need to change the state function.
Paolo Furini
@pfurini
Apr 07 2017 16:28
it's a must if your system needs "pluggable" piece of logic + ready-made view
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:28
I say compatible between because they don't have to match 100%, they can consume more of less properties.
yes, the idea is that the interface between the view and the app logic is a set of properties (prepared/computed by the state function) and events wired (dynamically) to actions.
Paolo Furini
@pfurini
Apr 07 2017 16:30
well, so that's totally compatible with a plugin system..
one could even provide headless plugins (no views), and bundle a set of swappable views that can consume the same state representation
Paolo Furini
@pfurini
Apr 07 2017 16:36
so, if I got the big picture right, what I called "components" (autocomplete box, a grid, a chart, etc.) could be expressed in terms of view functions that given a state representation, produce a visual representation (whatever media), and respond to outside events by pushing actions (with payload) to some model function (that I'd like to decouple, I mean I'd like to be able to dynamically select the model to dispatch the action to)
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:38
yes exactly. I use "intents" passed to the view components to wire events to actions, but any mechanism you will do.
Paolo Furini
@pfurini
Apr 07 2017 16:38
regarding the last part, the dynamic dispatch, for a highly dynamic and disconnected system, it could be delegated to hierarchical service, much like a hierarchical dependency injection container
intents like the ones in android?
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:40
sure, SAM does not prescribe any solution. It just requires that the model be decoupled from the properties of the view components. It's cleaner to group that kind of logic away from the model which focuses on accepting proposals.
intents is just a broad term that refers to the "true" flow view triggers events, events are translated into intents and intents are wired to an action. That being said, it just refers to any mechanism you want to use that would dynamically connect a view component event to an action. You don't want your view component to know too much about actions.
Intents are provided by the State function to the view components.
Paolo Furini
@pfurini
Apr 07 2017 16:44
so the state function plays also the role of "intents container", mapping intents+data to actions+data
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:45
it's the glue. An app logic "component" might mount its intents to the state functions. It is the State function which passes the intents to the view components.
Paolo Furini
@pfurini
Apr 07 2017 16:46
I see
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:46
In the fishing game sample, I show how the state function generates three types of "state representations": HTML, properties and a clojure executed by the view components
Jean-Jacques Dubray
@jdubray
Apr 07 2017 16:51
You really don't have to think of model, state and nap as one big function. It's easier to start that way to quickly grasp what SAM is about, but they are and need to be decomposed as individuals acceptors for the model and states for the state function. The themes are usually very decoupled, naturally.
Paolo Furini
@pfurini
Apr 07 2017 16:52
the fishing sample is a bit more coupled than what we discussed now, and that's what worried me about composition.. for example the actions functions rely on the global model variable, but in a more dynamic solution the model should be passed as a parameter of an action constructor, and wired by the outmost app logic

but they are and need to be decomposed as individuals acceptors for the model and states for the state function

yeah, I see the point now. that could be a factored using composition of pure functions, like the elm approach (even if it could lead to large master functions anyway, for big projects)

Paolo Furini
@pfurini
Apr 07 2017 16:58
But if you carefully separate the app logic in more small manageable pieces, the functions should remain manageable in terms of complexity
Phew, this is a lot for a single evening! better to take some time to elaborate on this.. :smile:
Thank you very much @jdubray for all your time!
Jean-Jacques Dubray
@jdubray
Apr 07 2017 17:06
exactly! but you get the added bonus of the many-to-may relationship, it's not one-to-one (one action to one acceptor to one state). I think this three way many-to-many relationship brings a lot of efficiency in coding a project.
Edward Mulraney
@edmulraney
Apr 07 2017 17:09
@pfurini the easiest way to understand SAM imo is that it is redux + componentDidMount from React. and for async actions you can use whatever async library you prefer or just the default redux-thunk
componentDidMount=nap
nap = automatic actions based off state
Paolo Furini
@pfurini
Apr 07 2017 17:12
I haven't worked with redux before, only know some theory behind it.. but I thought it introduces more coupling than pure SAM
Edward Mulraney
@edmulraney
Apr 07 2017 17:13
which parts become more coupled?
if you havent worked with redux before then that will be a useless helper! sorry haha. I assumed you'd used redux for some reason
Paolo Furini
@pfurini
Apr 07 2017 17:16
I refer to this comment @jdubray made on his article on infoq: https://www.infoq.com/articles/no-more-mvc-frameworks#anch133152

and this particular sentence:

With SAM, actions are external to the model and as such can be reused across models and even implemented by third parties. In Redux, actions are merely intents. The implementation of the action is in the model (reducer). That is wrong.

and that was the same reaction I had when I first seen the theory behind redux itself.. sorry if that impression was wrong, can't really judge it since I never use it practically..
Paolo Furini
@pfurini
Apr 07 2017 17:28
IMHO the best way to grasp it fully, is to try implementing it in a FP style, in terms of composition of pure functions. Doing so, one can clearly see all the inputs and outputs as pure functions parameters, without resorting to some global state, like window.vars
I'll try my best in my spare time..
Radosavljevic Slobodan
@radosavljevic
Apr 07 2017 17:35

@pfurini

MHO the best way to grasp it fully, is to try implementing it in a FP style, in terms of composition of pure functions. Doing so, one can clearly see all the inputs and outputs as pure functions parameters, without resorting to some global state, like window.vars

I know everybody would be grateful for such an effort.

Edward Mulraney
@edmulraney
Apr 07 2017 17:42
Theres no more "external-ness" to actions in SAM vs redux. That comment is more about jdubray disputing what redux calls an "action". when you remove the naming from the concepts in redux/SAM you have the same thing. the only thing missing is automatic actions which you get with React. i dont know anyone using redux without a UI library capable of doing NAP
Jean-Jacques Dubray
@jdubray
Apr 07 2017 19:15
@edmulraney then why not finish our discussion what "truly" is an action? It would be really helpful if our industry would create a broad agreement around it. A game changer.
Marcus Feitoza
@mfeitoza
Apr 07 2017 19:27
Hi JJ, how do you approach with forms and validation?
Daniel Neveux
@dagatsoin
Apr 07 2017 19:42
@mfeitoza I have deal around form with a login/register form. So not a big one but I would love to discuss about it.
1- My form submit send an intent with login/password.
2- The action check if empty/case/etc.
3- The model check if the user exists and reject/accept the login/password.
4- The state generates a new viewModel {formError: { login:{}, pass:{}} from the model which I pass to the view (The nap do nothing here).
5- The view refreshed
Daniel Neveux
@dagatsoin
Apr 07 2017 19:55
For me an action is something who acts on something else without guarantee the result. Exemple: if you fire with a gun on a stone, the stone is not guarantee to break. It is the role of the structure of the stone (is it already weaken? what is the material?) to decide to break or not. The gun could do nothing for that.
(sorry, playing overwatch in same time...)