These are chat archives for jdubray/sam

18th
Feb 2018
Jean-Jacques Dubray
@jdubray
Feb 18 2018 00:08 UTC
@foxdonut yes, that's SAM! I'd be curious to see alternatives to if/then/else
Daniel Neveux
@dagatsoin
Feb 18 2018 07:13 UTC
A switch!
Victor Noël
@victornoel
Feb 18 2018 11:58 UTC
@jdubray when looking at the code from @foxdonut, I wonder something: do you think it is important for the model to receive one datastructure containing the proposal or would it be ok, a bit like with the actions, to have an event id associated with data?
Daniel Neveux
@dagatsoin
Feb 18 2018 12:28 UTC
You mean like in sam-safe witj an id representing the step ?
Victor Noël
@victornoel
Feb 18 2018 12:32 UTC
I mean instead of presenting to the model a datastructure "proposal" with a propery "a" containing some data, you present to the model an event "a" with some data in a "proposal" variable: the difference only seems syntactic, but I'm not sure if there isn't something else behind the whole idea of a proposal presented to a model that I didn't grasp
i.e. the model has a present function that takes 2 arguments, the first one is the type of the event and the second is the data. While in most examples we see of SAM, the model has a present function that takes 1 argument with each property being usually handled independently. But I may be wrong about that last part, hence my question :)
Jean-Jacques Dubray
@jdubray
Feb 18 2018 14:41 UTC
@victornoel I actually add an action label to each proposal but I never feel that's the right way to trigger an acceptor.
@dagatsoin the step number is just a counter, not an identifier
@victornoel there was a time when we were writting (assembly) code without a function, it was just memory addresses, registers and operators. (I am not that old). So we should not get caught up on the syntax, but really discuss the semantics.
If there is a better syntax I'll take it, but from what I can see after two years coding that way, the decoupling is very healthy.
Jean-Jacques Dubray
@jdubray
Feb 18 2018 14:49 UTC
I was also thinking some more about stateful components and again, I don't use stateful components (as you guys define them). I fold the local state into the global state. It's not a problem because the component model I use (what I call building blocks) is not tangled in the global state. In other words, as long as no one knows about my props, for all intent and purpose that state is local to me. So granted that it's not hard to fold local state into global state, the benefit you get is that you can now use functional HTML all the time. I'll try to finish the code sample I am working on today.
And again, the syntax won't be pretty, but we should always remember that there was a time when programmer didn't have a "function" construct, so if a construct is useful, a syntax will come to make it easy to use.
@devinivy also came up with another interesting approach
Using some kind of label as @victornoel suggested is another possibility.
To be honest, though, I still prefer the initial approach of named functions.
I understand your point of decoupling, but I would only decouple that much if/when I reached a point where that decoupling would give me something in return of the additional code needed to handle proposals.
Fred Daoud
@foxdonut
Feb 18 2018 15:11 UTC
I would venture that the initial approach does not have any real disadvantages in at least some applications.
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:21 UTC

@foxdonut yes, that's an interesting way, but there is still too much coupling (or you are limited to a one property condition) because you really want to trigger the acceptor from a condition not from a label. But that's clearly better than one-to-one.
The reason why I say to much coupling because you can always structure your proposal with:

{ a: { b:0, c:1} ...

and route on a being present, but if b triggers another acceptor, then you'll have to add it to the proposal in another area

Victor Noël
@victornoel
Feb 18 2018 15:24 UTC
Intuitively, I would have made as many method on the model object as there are ways to propose something to it. My question is not about advantages or which syntax is better: originally I'm asking because I don't know if it is important that the API exposed by the model is based on the way the model is internally structured. For example, I feel like the way you, @jdubray, usually present data to the model has the advantage that you can propose many changes at once or just one, and the model can handles them atomically. If you use a proposal in the form of an event label + data, then it means you have to present multiple labels when you need to propose many changes.
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:24 UTC
@devinivy implementation is nice, but it would suffer from the same problem, I use full conditions (at least 30-40% of the time) to discriminate between acceptors. The reamaining 60-70% are unique properties.
Victor Noël
@victornoel
Feb 18 2018 15:25 UTC
I think the important point to keep in mind is what you just said @jdubray: "because you really want to trigger the acceptor from a condition not from a label" and that's what I was missing
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:26 UTC
All the acceptors are private to the model. No other element of the pattern is allow to invoke them directly.
That allows you to structure the mutations in reusable/independent units of work.
Victor Noël
@victornoel
Feb 18 2018 15:26 UTC
ok, and so the thing that is presented, the thing that is used to decide which acceptor are trigerred, what do you call it?
and another question: is there so semantic link between this "thing" and the state? For example is this "thing" that is presented to the model a subset of the state? or not at all
"so" -> "some"
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:28 UTC
It's part of the acceptor, just a non functional way to call a piece of code
in theory you want the properties of the proposal to match the properties of the model one-to-one, but in practice, I am not necessarily doing that.
What it is important during the mutation is to keep track of primed variables vs non primed variables.
Victor Noël
@victornoel
Feb 18 2018 15:29 UTC
so the acceptor itself is private, but its "API" is public in a way?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:30 UTC
Primed variables contain the new value at Step N, non primed variables contain the value of the same properties at Step N-1
Victor Noël
@victornoel
Feb 18 2018 15:30 UTC
the old/new value in the model, right?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:30 UTC
The model only has one public method, present
Victor Noël
@victornoel
Feb 18 2018 15:31 UTC
why is that important? to keep track of primed vs non primed? since the model is atomically doing its work
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:31 UTC
precisely because many acceptors can be triggered!!
you also have cases where you need both values to compute/accept the new value.
Victor Noël
@victornoel
Feb 18 2018 15:32 UTC
ok, makes sense
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:32 UTC
That's really the kinds of temporal logic constructs that are missing in programming languages today.
Victor Noël
@victornoel
Feb 18 2018 15:33 UTC
and regarding "one public method, present": the type of what present accepts is part of its API which is also public, so in a way, this is exposing the acceptors API, no?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:33 UTC
Of course we can always code it, but unless you are conscious about it, you'll create a big mess.
I use an "any" type. I don't keep track of individual proposal structures.
Victor Noël
@victornoel
Feb 18 2018 15:35 UTC
so how do you now what an action can present to the model?
know
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:35 UTC
This is how you code in a service-oriented-architecture, you have one message payload that could trigger a service orchestration. It's kind of the same concept. Each service would then pick what they need from the original message.
Victor Noël
@victornoel
Feb 18 2018 15:36 UTC
or does it mean that the model's present method is designed based on the existing actions, and not the opposite?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:36 UTC
There is a bit of design and coordination that needs to happen, but that's not a lot work. It's not as rigid as a function call, but if you prefer, proposals could be typed. That's not a problem, it's just the argument of the present method is any.
The way I implement the SAM pattern is thinking the model as structured and the proposals to be just key/value pairs of what I want the model to accept.
Victor Noël
@victornoel
Feb 18 2018 15:37 UTC
I'm trying to understand the SAM developer though processs during design :)
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:37 UTC
Yes!
Victor Noël
@victornoel
Feb 18 2018 15:38 UTC
yes to what? ^^
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:38 UTC
If the action and the acceptors are coded by two different teams, you may decide to type your proposals.
Yes, I understand you are looking at the design process.
Victor Noël
@victornoel
Feb 18 2018 15:38 UTC
ah ok ^^
and do you think the heart of the proposal meaning would be more coming from the model or the actions? from what you said I feel like the answer would be the model
the model is in a way the heart of the application
Daniel Neveux
@dagatsoin
Feb 18 2018 15:40 UTC
For my part I have a type for each value that can be proposed to the model. My proposal is like Array<Proposal<any>>
And a proposal is like
Proposal<T> {
  type: string;
  data: T;
}
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:44 UTC
Yes, the action is only a mediator between the event and the model. Everything is about view/model with the understanding that the view and model can never ever align with each other. So the action's proposal is not something that stands on its own, it's better to make it as close to the model as possible. In TLA+ an action's role is to compute the primed variables. I am (of course) happy with that definition and general direction.
Though in practice you might need to bend it to include additional props, not part of the model.
The model would then calculate the primed variables, from these props.
@dagatsoin yes, there is nothing that prevents you to add structure to the proposal, it's just a good practice to keep in mind primed vs non primed variables.
Victor Noël
@victornoel
Feb 18 2018 15:46 UTC
so the action can directly present a primed variable to the model and the latter will just use it (if it makes sense in its current state)
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:47 UTC
yes exactly, because the model may not know how to calculate it (or it could be user input of course). The model's responsibility is just to accept it or not.
There might of course be implications when the model accepts it, such that other properties need to be updated as well.
You don't want the action, this time, to know about these implications.
Daniel Neveux
@dagatsoin
Feb 18 2018 15:48 UTC
I don't get what is a primed variable...
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:48 UTC
that's why it's so important to create that interface between action and model.
A primed variable represents the value of that variable that you want the model to accept, the non primed variable is the current value before the model mutates.
The Action and Acceptor logic/role are very different in nature, when you cobble them together in an event handler your code is likely going to be difficult to maintain and evolve.
Victor Noël
@victornoel
Feb 18 2018 15:51 UTC
This whole discussion is highly enlightening :)
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:52 UTC
I don't want to make it sounds like I brag about something or trying to hipe SAM, but the number of defects in my software is nearly zero, and I can come back six months later and change that code rather drastrically and still achieve the same defect free result.
That's because the code becomes much easier to reason about (granted the wiring syntax is not great, but if you keept that aside).
That of course includes API calls as well.
Victor Noël
@victornoel
Feb 18 2018 15:53 UTC
what do you mean by that last sentence about API calls?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:54 UTC
the back-end API calls, all my projects have a complex back-end.
Victor Noël
@victornoel
Feb 18 2018 15:54 UTC
and you mean the backend also follows the SAM pattern?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:54 UTC
No, I was talking about having API calls in the actions and the model.
It's of course possible to use SAM in the back-end, but when your back-end is a Data Access Layer, then the database plays the role of the model and the APIs create proposals (SQL statements) to update the model, which can be accepted or not.
Victor Noël
@victornoel
Feb 18 2018 15:56 UTC
and if the backend role is to access data but not to write data?
the APIs are what?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 15:57 UTC
I would need SAM if I was doing complex orchestrations/compensations. Then I have to manage some state that's not in the database
the APIs exposed by the back-end (endpoints).
Victor Noël
@victornoel
Feb 18 2018 15:57 UTC
yes, I meant: what are the API (in the SAM lingo) when the backend is there only to access data from the db and return it to the frontend?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 16:01 UTC
actions
they also create the state representation
but all that is rather trivial in the back-end
Victor Noël
@victornoel
Feb 18 2018 16:02 UTC
ok
so it is less trivial when the backend has some complex state (in the general sense of the word) that is not coming from the db, for example let's say there is some kind of heavy computation in the backend, so the backend can be either idle, computing or result is ready, but it's not stored somewhere, it's there in memory and thus there is the need to distinguish those differente states, and so you would use SAM to implement that also in the backend?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 16:07 UTC
SAM is a direct replacement for every event handler. The problem is that the "model" is more aligned with the concept of session. So you need to rehydrate the model for every call you receive, then you can implement SAM as usual, no difference, what is an API call from the browser would become a SQL statement.
SAM-SAFE has a dynamoDB connector to dehydrate/rehydrate the model for a given user (or agent).
Victor Noël
@victornoel
Feb 18 2018 16:09 UTC
yes, I was putting this question of hydratation aside
Fred Daoud
@foxdonut
Feb 18 2018 16:49 UTC
@jdubray yes I agree that the alternatives I showed are limited, they are adapted to that simple example. Of course in a more complex application the code would change accordingly.
I see your point about a single present function and a plain object as a proposal. There are pros and cons to that approach, same as having named functions has pros and cons. I don't think either solution is the best for every application. I would weigh the pros against the cons in an application depending on the pertinent use cases, and choose the approach based on the results of the analysis.
boris sabadach
@bsabadach
Feb 18 2018 17:06 UTC
@foxdonut I like your implementation of model update without if/else. It really suits my way of thinking
Fred Daoud
@foxdonut
Feb 18 2018 17:15 UTC
@bsabadach happy to hear that, thanks!
boris sabadach
@bsabadach
Feb 18 2018 17:17 UTC
@foxdonut and your example on glitch is very close to the SAM semantics; worth be on the SAM site. Next step: how do you plan to test this code?
Fred Daoud
@foxdonut
Feb 18 2018 17:25 UTC
@bsabadach as in writing unit tests?
devin ivy
@devinivy
Feb 18 2018 17:27 UTC
luckily it is very testable!
boris sabadach
@bsabadach
Feb 18 2018 17:27 UTC
yes I don't want to start a discussion now on this topic but whe have to talk about it sooner or later. Whatever the FW or design pattern application should be unit testable
VaseJS
@VaseJS
Feb 18 2018 17:29 UTC
@bsabadach there is an article on the site about testing SAM somewhere
Jean-Jacques Dubray
@jdubray
Feb 18 2018 17:30 UTC
It's probably this one, explaining that the math is not in favor or unit tests
That being said, the build blocks of the pattern are much easier to unit test because they have well defined responsibilities.
boris sabadach
@bsabadach
Feb 18 2018 17:38 UTC
@jdubray yes if each of the responsablity is putted in a single js file, unless I don’t understand how u can unit test an index.html file.
Jean-Jacques Dubray
@jdubray
Feb 18 2018 17:39 UTC
SAM implementations are 100% componentized
boris sabadach
@bsabadach
Feb 18 2018 17:40 UTC
@jdubray what do you mean.
VaseJS
@VaseJS
Feb 18 2018 17:41 UTC
@jdubray i read that article and thought it was great
Jean-Jacques Dubray
@jdubray
Feb 18 2018 17:41 UTC
What's left in index.html is just wiring
VaseJS
@VaseJS
Feb 18 2018 17:42 UTC
it was an eye opener, however i don’t believe people are moving that direction. the dogma has set in long time ago.
boris sabadach
@bsabadach
Feb 18 2018 17:45 UTC
@VaseJS completly agree. las t year I was in company where ’80%’ code coverage was the ultimate target, whatever the architecture
Jean-Jacques Dubray
@jdubray
Feb 18 2018 17:46 UTC
@VaseJS that's the problem of any communication/discussion, we come with our own biases, "common knowledge" and triggers that polarize the discussion. It's best to try to limit the scope of the discussion, that limits the number of dogmas you have to deal with at any given time.
VaseJS
@VaseJS
Feb 18 2018 17:48 UTC
@jdubray i agree. its why i’ve been having a hard time with finding certain things and part of the reason I found you in the first place. i objectively look for whats effective
without needed to learn temporary skills (like some frameworks)
SAM can be implemented in vanilla JS, i’m there!
Jean-Jacques Dubray
@jdubray
Feb 18 2018 17:49 UTC
yes! It's still a big bet but I believe that is the future.
Functional HTML, lit-html and factoring like the SAM pattern have the potential to make it possible.
VaseJS
@VaseJS
Feb 18 2018 17:54 UTC
i’ve studied companies who decided with certain projects not to use frameworks, and they are all happy with the decision. Other companies who do use frameworks are not unhappy but the common pattern is high maintenance cost if/when the framework team makes upgrades. I’ll pass. I’ll happily pay more upfront to have smooth sailing on the tail end of things
SAM handles the front-end, but not quite the back end in the same manner so I’m still and the hunt to a degree. I have figured that out, but I have to keep my eyes open for thing like same to help with backend work
Jean-Jacques Dubray
@jdubray
Feb 18 2018 17:56 UTC
?
Not quite sure I understand your last comment
VaseJS
@VaseJS
Feb 18 2018 17:57 UTC
About SAM not handling backend server side issues?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 17:57 UTC
yes
image.png
VaseJS
@VaseJS
Feb 18 2018 17:59 UTC
so if i understand this chart in the context of what my question is/was, are you implying that SAM can do what ExpressJS does?
Jean-Jacques Dubray
@jdubray
Feb 18 2018 18:01 UTC
No, sorry, that's not what I meant
I don't think it's possible to not use a framework on the back-end
VaseJS
@VaseJS
Feb 18 2018 18:02 UTC
thats what i’m looking for. I know of two companies that use Node raw and are happy doing it that way
Jean-Jacques Dubray
@jdubray
Feb 18 2018 18:02 UTC
The problem is the activation of the code and resources upon recieving a request
VaseJS
@VaseJS
Feb 18 2018 18:02 UTC
but 2 is a small number
Jean-Jacques Dubray
@jdubray
Feb 18 2018 18:02 UTC
I can't use node without a framework like express. It provides just too many capabilities that I need.
Fred Daoud
@foxdonut
Feb 18 2018 18:36 UTC
@VaseJS you might be interested in hapi
devin ivy
@devinivy
Feb 18 2018 18:44 UTC
it is a rather large framework, but i am a big fan of it. it's very flexible and, related to folks' interests in this channel, it encourages writing framework-agnostic code. for example, controllers/handlers are functions that return a value (rather than providing a response by calling something like res.send() or res.json() in express). if anyone is interested in it feel free to reach out to me.
Fred Daoud
@foxdonut
Feb 18 2018 18:52 UTC
@devinivy I'm using it for a personal project, I combined it with crocks and I love the result :thumbsup: