These are chat archives for jdubray/sam

9th
Jun 2016
Jean-Jacques Dubray
@jdubray
Jun 09 2016 00:30
@edmulraney There is framework, it's SAFE. I don't promote it too much because I don't want to discourage people to use the pattern in any way shape or form they want. The problem with frameworks is that you have to pick the wiring and the architecture. For instance, SAFE sets the wiring and half the architecture (client or server, but nothing in between).
Jean-Jacques Dubray
@jdubray
Jun 09 2016 01:05
You can also see what's going on with Redux, there is now a plethora of micro libraries which have emerged to solve specific (or imaginary) problems. I'd argue that the need for libraries emerges when you pick the wrong factoring to implement the solution. For instance, Redux's actions are really just events, you can't mutate state from intents, generally an event is translated into an intent, and the intent triggers an action. So what happens next in Redux? the actions and the model are coupled in the reducer (the store has no business logic of its own), but that coupling is way too strong to handle long running actions. So what happens? you have to use thunks. It doesn't occur to Dan that having two definitions for an 'action' is probably not right, semantically, it would be much better to pick one. MobX picked one. Cycle.js and Elm directly wire events to mutation (intent->model).
Unfortunately, we cannot have any discussion with Dan or Andre. The second I pointed to Dan and Yassine that Redux-Sagas were breaking their principle #1 (Single State Tree), that second they stopped any discussion.
I have no agenda, other than finding the proper programming model and identifying options for wiring and architectures.
devin ivy
@devinivy
Jun 09 2016 01:43
they just stopped responding to you once you started talking about sagas?
wow!
Jean-Jacques Dubray
@jdubray
Jun 09 2016 01:50
Yes, I can show you the tweet where I pointed out to Yassine that he was breaking that principle, and he responded so what and that was the end of the discussion.
Jean-Jacques Dubray
@jdubray
Jun 09 2016 02:28
Very interesting presentation, including the limitations of immutability (Reducer) https://www.youtube.com/watch?v=xN7yg95AwXU
Jean-Jacques Dubray
@jdubray
Jun 09 2016 02:45
This presentation illustrates how Cerebral optimizes SAM's state function, in some cases where the model is large and changes are always small, then I could see how this is useful.
The way SAM reduces the need for this kind of framework is always to first compute the current control state (which is generally a very cheap computation) and then render only the components in that state (just like "sliding" as we spoke earlier)
Jean-Jacques Dubray
@jdubray
Jun 09 2016 02:51

If needed, the Model could also keep a list of the properties it changed in the current step to optimize the State function, you don't really need a library for that.

model.changes = []
...
model.changes.push("prop1")

Then in the state implementation you could keep a list of components interested in prop1

A very interesting debugging approach from Cerebral, again, very well aligned with SAM, the state function and the view components can easily be configured to implement that.
https://www.youtube.com/watch?v=Jvn_Gh1pEgY
Jean-Jacques Dubray
@jdubray
Jun 09 2016 05:53
I got an Angular2 implementation working, using "compilation", after @brusand suggested I look at that post. The solution in the post is outdated, Google changed the DynamicComponentLoader API, but after a couple of iterations it seemed to work just fine.
Edward Mulraney
@edmulraney
Jun 09 2016 08:12
@jdubray good example of the difficultly in understanding SAM - it seems you redefine State, Model and other common terms. I think this only confuses people
@judbray "Redux's actions are really just events, you can't mutate state from intents, generally an event is translated into an intent, and the intent triggers an action. So what happens next in Redux? the actions and the model are coupled in the reducer (the store has no business logic of its own"
the model is definitely not coupled to the reducer in redux. that is an antipattern
your reducer contains a state representation of entities. this does not necessarily map 1 to 1 for models
your models are defined in your selectors
you "select" pieces of state to create a model
also, we never used redux-sagas. we didn't like this approach
Edward Mulraney
@edmulraney
Jun 09 2016 08:19
instead I made an action type SEQUENCE which allowed you to create an action composed of multiple actions
weepy
@weepy
Jun 09 2016 08:19
"... redefine State, Model and ... " - I've brought this up before, but @jdubray wasn't keen on changing them (partly because it ruins the acronym - which surely is not a good reason).
@edmulraney isn't the limitation with SEQUENCE that you have to decide upfront that you want a sequence ?
Edward Mulraney
@edmulraney
Jun 09 2016 08:24
is that a limitation? that was our only use case of it
example would be, ADD_CLIENT
immediately after this youd want to get GET_CLIENTS
not greatest example but hopefully illustrates it
Edward Mulraney
@edmulraney
Jun 09 2016 08:29
we weren't using graphql so some of the limitations of RESTful API led us to wanting to write SEQUENCEs
it removed the need for sideEffects, or the next tick hacks
Edward Mulraney
@edmulraney
Jun 09 2016 08:36
probably worth mentioned this built on top of XHR_REQUEST middleware we built which was a simple state machine that handled: REQUEST, SUCCESS, FAILURE
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:36
@edmulraney My question is how do you call "started" or "stopped" when you speak about a car.
Edward Mulraney
@edmulraney
Jun 09 2016 08:36
so XHR_SEQUENCE was just built on top of that
@jdubray not sure I follow, dispatch start/stop actions?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:37
No, I mean in English, how would you call "started" / "stopped" (a state?)
My car is in the state "started"
My car is in the xxx "started"
Edward Mulraney
@edmulraney
Jun 09 2016 08:38
{
  car: {
     state: "started"
      ...
or engine: states.started ?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:39
So you call it a "state" ? that why I use the word "state" which is separate from what people call "application state"
In general application state means "assignment of property values"
I need another word to describe what "started" is, the only word I could come up with is "state"
Edward Mulraney
@edmulraney
Jun 09 2016 08:40
ah i see
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:40
The true "state" of the system is the combination of the assignment of property values and a function that translate these property values into a ... state such as started.
In modern cars, started might mean RPM > 900. Such car would not let you switch to drive if RPM < 900, you could damage the car, and most likely would signal an error condition.
There are two problems in computer science:
  • there is no clear definition of what is a programming step
  • there is no "state" (what I call state) to which you can attach what you can and cannot do
For instance you mentioned "Sequence", what guarantee do you have that the second action in the sequence is still allowed?
Edward Mulraney
@edmulraney
Jun 09 2016 08:44
the 2nd is only allowed if the first succeeded
and so on
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:44
Well, that's not enough, the mutation (assignment of property values) could have resulted in a "state" that disallow the second. How can you be sure?
That's the problem that SAM solves. SAM implements "sequences" with the nap() function
Edward Mulraney
@edmulraney
Jun 09 2016 08:45
would that state be considered a SUCCESS state or a FAILURE state?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:45
No because other properties may have been assigned values that brings the system into a "state" where the second action is disallowed
success/failure is not enough, sometimes it works, sometime is doesn't
Edward Mulraney
@edmulraney
Jun 09 2016 08:46
okay, how does nap guard against that?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:46
the next-action predicate computes for a given "state" (my state) if there is an automatic action. If there is then it gets executed.
You get the sequence, but you also get the control that, that particular action is still allowed.
Let's say you have a long running sequence
Edward Mulraney
@edmulraney
Jun 09 2016 08:47
you can do that manually right be checking state? like this
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:48
And you want to allow to cancel that sequence
You'd process a "cancel" action (proposing a value like {cancelMyLongSequence: true}
nap() would be in the position to take the right action.
Edward Mulraney
@edmulraney
Jun 09 2016 08:49
SEQUENCE: {
    ...,
    fnFirstAction,
     state => { if (state.blah) { return fnSecondAction(state) } else { return cancelAction(state) }
sorry will format in 1 sec. brb
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:51
Yes, but here you are implicitly stating that state.blah was mutated properly.
This is an event ordering problem, each time you'll use somewhat imperative semantics (Sagas, Sequences...) you'll have difficulty implementing these patterns. SAM provides a structure that works all the time.
The propose/accept/learn is the flow of the pattern, SAM says you cannot arbitrarily change that flow, otherwise your program becomes very hard to reason about.
Edward Mulraney
@edmulraney
Jun 09 2016 08:52
learn = fail states handling?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:52
no, learn = [createStateRepresentation(model), nap(model)]
Edward Mulraney
@edmulraney
Jun 09 2016 08:53
is nap() attached to single actions? so you cant compose a flow in a single place?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:53
nap is about "automatic" actions, things that need to happen without a user input
You have to be opinionated about a few things: what is an action?
You are still thinking action = line of code
Edward Mulraney
@edmulraney
Jun 09 2016 08:54
event
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:54
action -> start a "step"
You have to define precisely what an action is
Edward Mulraney
@edmulraney
Jun 09 2016 08:56
we originally solved the sequence problem like how youve done nap (if i understand correctly)
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:56
Sorry, I have a 30 min meeting starting in a couple mins, I'll have to drop off.
Edward Mulraney
@edmulraney
Jun 09 2016 08:56
but we found the problem with that is you dont want to couple nap to a single action
okay np, i really appreciate the discussion
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:56
Actions can be functionally composed: A(B(C(data))) but only one proposal to the Model
Sorry have to go
Edward Mulraney
@edmulraney
Jun 09 2016 08:57
no problem, thanks for discussing :)
Jean-Jacques Dubray
@jdubray
Jun 09 2016 08:57
thank you!
Edward Mulraney
@edmulraney
Jun 09 2016 09:06
so we have a REQUEST action type, which consists of three types START, SUCCESS, FAILURE. we have a SEQUENCE type which consists of REQUESTs. we can compose a new action LOGIN_SEQUENCE which consists of actions A, B, C, completely decoupled. And at any time in the sequence we can observe state and determine whether or not we want to issue the next action in the sequence. The action "A", doesn't need to be told to immediately do B, because in some instances we don't want to do B straight after A, so we avoid coupling it.
typical use case for this is http requests, but also ui dialogues (propose, yes, no), etc.
anything with "steps"
Edward Mulraney
@edmulraney
Jun 09 2016 09:11
you could replace the "S" in sam with Step, Status, Condition, Transition?
it looks like your definition of model is persisted entity? is that right?
Edward Mulraney
@edmulraney
Jun 09 2016 09:17
perhaps the "S" in SAM needs a prefix? X-state. what is X?
generally state means "application state" or "model state", but in SAM it seems to mean transition
Daniel Neveux
@dagatsoin
Jun 09 2016 13:41
@edmulraney application status is my best definition of the S
Jean-Jacques Dubray
@jdubray
Jun 09 2016 13:50

@edmulraney

it looks like your definition of model is persisted entity?

yes

@edmulraney @dagatsoin Status would be the closest, otherwise, I can also call it PAL (Propose/Accept/Learn)
Daniel Neveux
@dagatsoin
Jun 09 2016 14:25

@edmulraney
it looks like your definition of model is persisted entity?

@edmulraney And it is a way to do composition with sub models. For example In my MMO project each EntityModel is a part of the global WorldModel. Ant it was the best selling point of SAM for me.

Edward Mulraney
@edmulraney
Jun 09 2016 15:05
if model in SAM = DB entity, where do models and view-models live, or get created?
Daniel Neveux
@dagatsoin
Jun 09 2016 15:10
For me a model is class instance, not a DB entity (like in mongoDB)
Edward Mulraney
@edmulraney
Jun 09 2016 15:10
it must be modelling something, persisted entity, domain object, etc.
sounds like a regular domain model in that instance?
The SAM pattern graphic had the database symbol over the Model layer is what confused me
on the homepage the examples are more difficult to understand due to the theme singleton
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:15
+1
SAM does not preclude the model to be a class, as long as methods are private except for accepting new values (you are not constrained to a single present method).
Edward Mulraney
@edmulraney
Jun 09 2016 15:18
the example is difficult to understand because of the unexplained intents[] array
so youve moved the responsibility of updating the model, into the model, rather than the reducer (in React)?#
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:19
intents are just a way to wire actions to an otherwise generic UI component
yes, React does not make a distinction between propose and accept. There is the Reducer and the Store (and thunks and Sagas)
Edward Mulraney
@edmulraney
Jun 09 2016 15:20
what does the proposing in SAM? or where? (the "reducer" equivalent, event handler? )
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:21
Actions propose values to the model
That would be the equivalent of thunks.
Most often actions would need to validate and enrich the event/intent from the view
Edward Mulraney
@edmulraney
Jun 09 2016 15:22
in redux an action is simply a description of an action that will happen. in SAM is an action something that is directly executable and proposes the result to the model? (i.e. no dispatcher() )
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:22
Validation happens in the Reducer, Redux does not officially support enrichment
yes, exactly
because Redux describes what will happen, it couples the proposal with the acceptance,
the store must accept the output of the reducer
Edward Mulraney
@edmulraney
Jun 09 2016 15:23
what is the equivalent of the dispatcher in SAM? how do i execute an action?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:23
You can add a dispatcher or you can use intents
SAM makes a distinction between:
  • programming model
  • wiring
  • architecture
In SAFE I have implemented a dispatcher, but that's not necessary intents are a perfectly good way to wire the pattern.
Edward Mulraney
@edmulraney
Jun 09 2016 15:24
I like the sound of that
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:25
at a minimum you don't want the wiring to influence the programmin model
or the programming model to control the architecture
I believe SAM gives full flexibility. For instance I have shown that the same (JavaScript) code runs in the browser, in node.js or in AWS Lambda, unchanged.
You can even have 3rd parties running actions (say with an OAuth token) and presenting values to the model
Sorry, I have another long meeting starting now
Edward Mulraney
@edmulraney
Jun 09 2016 15:27
thanks again :)
enjoy the long meeting :P
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:28
Actually to talk about SAM!
pure joy
devin ivy
@devinivy
Jun 09 2016 15:29
:) aw!
rest assured some of us are out there reading it!
Jean-Jacques Dubray
@jdubray
Jun 09 2016 15:32
I was able to add directives to SAM's view this afternoon !
Edward Mulraney
@edmulraney
Jun 09 2016 16:56
what type of directives? angular style?
Jean-Jacques Dubray
@jdubray
Jun 09 2016 16:59
yes !!!
@edmulraney This is the "autoGrow" directive added to a SAM view component and it works, the code that I produced uses DynamicComponentLoader and the directive works as if it was in a template!!! :
// State representation of the ready state
view.ready = function(model) {
    return (
            `<p>Counter:${model.counter}</p>
            <form onSubmit="return actions.start({});">
                <input type="text" placeHolder="AutoGrow Directive" autoGrow/><br>
                <input type="submit" value="Start">
            </form>`
        ) ;

}
Edward Mulraney
@edmulraney
Jun 09 2016 17:06
nice!
Michael Terry
@formido
Jun 09 2016 17:35
why not Status Action Model?
looking around, when people are forced to make a distinction between state and status
status is even more closely aligned with control state
Edward Mulraney
@edmulraney
Jun 09 2016 18:47
are there an example projects that demonstrate a well organized SAM project?
i.e. folder structure
more than one model
clear separation of concerns
actions folder etc
Edward Mulraney
@edmulraney
Jun 09 2016 18:55
or preferably a SAFE project
if people are going to adopt it, it needs a framework
weepy
@weepy
Jun 09 2016 19:07
I like P/A/L
it encompasses better the outlines of the project
also sounds like something you need (a pal) :-)
@edmulraney agree it needs an example framework - but of course it's a pattern so need to be careful it's not too big
from my readings of this it seems that Propose/Accept/Learn is the most important idea that's presented and is different
Edward Mulraney
@edmulraney
Jun 09 2016 19:26
needs framework examples*
Edward Mulraney
@edmulraney
Jun 09 2016 20:09
I'm combining the sam-todomvc and sam-redux examples
@weepy agree with you on PAL
Fred Daoud
@foxdonut
Jun 09 2016 21:21
Greetings, friends, excellent discussion :thumbsup:
I am currently working on Meiosis, which can serve as a library to implement SAM (or PAL, I like that too, propose-accept-learn is the key to SAM): http://meiosis.js.org/gd/sam.html
I will be adding more examples and docs. The goal is to let you choose what you want for the view (React, Snabbdom, jQuery, plain HTML, etc.) and just write regular JavaScript functions for the State/Model/nap(), and Meiosis wires them together so that your components become regular functions view = f(model). The library supports the Single Model principle, and also has a Tracer (similar to redux devtools).
devin ivy
@devinivy
Jun 09 2016 21:29
@foxdonut consider me interested!
Jean-Jacques Dubray
@jdubray
Jun 09 2016 21:47
+1
@all PAL it is
If I had a choice, I would have chosen PAL as well, but I thought of it only a few weeks later.
devin ivy
@devinivy
Jun 09 2016 21:50
@foxdonut what what the impetus for creating meiosis? what were you not satisfied with elsewhere (nuclearjs, react+redux, elm itself, etc.)? clearly SAM is important to meiosis. do you have similar gripes with redux as @jdubray ? just curious to see how others are thinking!
Jean-Jacques Dubray
@jdubray
Jun 09 2016 22:38
@devinivy @foxdonut I briefly talked to Christian Alfoni yesterday and he has big reservations on immutability. You should look at how Cerebral's model implementation.
Fred Daoud
@foxdonut
Jun 09 2016 23:16
@jdubray again, I never said anything about immutability, I am fine with mutable models.
Jean-Jacques Dubray
@jdubray
Jun 09 2016 23:18
I was talking about Redux, Elm
Fred Daoud
@foxdonut
Jun 09 2016 23:20
@devinivy I'm trying to build something simple that wires things together for you but keeps almost all your code free of any specific tie-ins. Only the view is library specific -- and that is whatever library that you choose to use. Also, although I like some of the ideas behind SAM and I am trying to make Meiosis a SAM-compatible library, it is an optional pattern. In the end my goal for Meiosis is to have a way to build components that are just functions.
Fred Daoud
@foxdonut
Jun 09 2016 23:27
My problem with Cycle and other reactive libraries is that your code gets locked in to that reactive library, and it gets too complicated too fast. Everyone asking the same questions on the Cycle channel is a good indication that it's not particularly intuitive. And that's for simple examples.
As for the Elm architecture, something was lacking there because it was not straightforward to build independent components. I wrote an article about that which was well received by some, but either way, I still found it lacking. The Elm language itself is another story, it definitely brings many great features to the table vs regular JavaScript.
With Meiosis I am trying to build something simple, drawing from some of the ideas that I liked while exploring all these other great libraries and frameworks, but in the end hopefully cutting back on complexity while still giving a good structure to building webapps.
devin ivy
@devinivy
Jun 09 2016 23:40
cheers– thanks for the insights!
Fred Daoud
@foxdonut
Jun 09 2016 23:53
@devinivy thank you for listening :) ultimately I want to write good docs, but mostly produce code examples that will do all the talking :sunglasses: