These are chat archives for jdubray/sam

26th
Apr 2016
Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:03
@imnutz The WebSocket implementation would be implemented like HTTP. The actions are the entry point of the reactive loop, they would need to pass a reference to the WebSocket to the Model, then to the State which will compute the response and then return it to be displayed by the client.
Now, SAM's architecture allows you to run each element of the pattern where it is best suited. So you could decide to run the actions on the server and present data to the model which runs on the client.
You could also run the model on the server and it is the model which will publish the response to the WebSocket
Nathan Ridley
@axefrog
Apr 26 2016 00:05
State is segregated into "pure" state components that do nothing other than react to inbound data and project transformed state accordingly. An example of such a component might be "authentication and authorization", or "chat messages". The inputs to each component are the sources of data that they care about, and their outputs are a stream of their resultant state as it changes, and an optional stream of requests that must be processed in order for them to do their job. An authentication component is an example of a component that is generally only relevant to the client, whereas a chat messages component is based largely on external data. The former would emit requests when it determines that there is a need to transition the current authentication state. Its output state would be a representation of the current authentication state. The latter would only emit requests when there is a need to publish new messages to the server. It would emit state representing the stream of inbound messages and changes to previous messages.
Any state component can take another state component as input, or a transformed stream thereof.
UI components take state components as input as needed, and transform their data for local needs.
When a form of "pure" state is only relevant within a branch of the UI, its lifecycle is managed within that branch. If it turns out that it's needed in other branches, you hoist the management of that state component up to a higher level.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:09
The way I implement authentication is via an action which will decide wether the user is authenticated or not and present the result to the model { authenticated: true/false}
When presented with data, the model would respond very differently (of course). However it is the State function which will render the View in each case.
Nathan Ridley
@axefrog
Apr 26 2016 00:10
Sure. There are many ways to skin a cat, of course. I've just found that I quite like the way a graph of streams gives you an implicit separation of concerns in the way the data "trickles down".
Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:12
Now, I understand that you may want to prevent the execution of actions if "unauthenticated", the way to do that is through "allowed" action computed by the state function.
Not sure if you have seen the SAFE middleware.
Nathan Ridley
@axefrog
Apr 26 2016 00:12
will look
The biggest problem I've encountered with a cyclic/streams-based approach is that complex streams are hard to debug because no diagnostic tools exist for this kind of architecture. I'm writing one right now though, so hopefully that issue will go away.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:13
There is actually not so many ways to skin the mutation cat, TLA+ offers, I believe a robust and possibly the simplest way
My concern with Streams from a state machine semantics perspective is that they seem to ignore the very semantics of State-Action
you simply cannot arbitrarily apply actions to the model (or you will have to write a lot of code in the model to decide whether that action is expected at that point in time)
When you look at TLA+ you see (and that's a bit counter intuitive if you are not familiar with TLA+) that it describes the semantics of a State Machine in something that looks "imperative"
Nathan Ridley
@axefrog
Apr 26 2016 00:15

you simply cannot arbitrarily apply actions to the model

do you mean that as a statement of lacking, or a statement of opinion? i.e. "one shouldn't", or "one should, but is unable to"?

Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:17
I believe it is more than an opinion, Streams do not seem to offer a simple way to filter the allowed actions. As in software everything can be done, but every code sample I have seen so far simple to apply regardless of the underlying state machine
Not sure if you have seen that presentation from Netflix where they explain they moved away from highly observables models: https://www.youtube.com/watch?v=5sETJs2_jwo
Nathan Ridley
@axefrog
Apr 26 2016 00:19
At some point I'm going to write up my thoughts on how to approach a cyclic architecture properly. I think one problem is because this particular approach is still quite young and also is quite difficult to understand for newcomers, given the need to "rewire one's thinking", there are a lot of people applying the pattern non-optimally. There is a lack of reading material on what a well-designed application would actually look like if implemented correctly, so people fill the gaps with patterns that they're used to.
Thanks for the link, I'll take a look.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:22
Again, for me there are three perspective that need to be kept distinct:
  • programming model / semantics (what is an Intent/Event/Action, what is a Model and in the case of SAM, what is State)
  • wiring (streams, ...)
  • architecture (where can the components run, is your code isomorphic)
There is no reason for instance that whatever code you write could not be isomorphic. If it is the case with the framework you use, I would highly recommend you use another one.
Same thing, if the programming model of your framework depends on a particular form of wiring then you should be looking at another framework
Nathan Ridley
@axefrog
Apr 26 2016 00:23
fwiw, my code is all isomorphic
Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:24
that's a great step forward. When you look at React, it's quite difficult to write isomorphic code.
Nathan Ridley
@axefrog
Apr 26 2016 00:31
I think one problem with React is that typically you have the "outside" and the "inside", which means when you hit logistics issues midway through the render graph, there is a tendency to use React components to implement solutions to those issues. An example is React Router. React is a renderer, but it's being used to fill all kinds of other needs in the process. I think when you're having to use a tool designed for a specific purpose to fill an orthogonal need, then either the common wisdom on best practices needs to evolve, or the tool needs to be looked at more critically.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 00:32
Yes, 100% agreed
devin ivy
@devinivy
Apr 26 2016 01:09
that made for good reading @axefrog @jdubray :)
Stardrive ENGG
@HighOnDrive
Apr 26 2016 01:11

@axefrog "At some point I'm going to write up my thoughts on how to approach a cyclic architecture properly". That is challenging when things constantly change, like isolation did again over the weekend. There are good solutions to state and increased performance for the xstream library and even better isolation being brought forth but also being kicked under the rug as fast as they arrive.

Maybe its not a question of reasonableness and community but rather an issue of someone's rockstar ego that is frustrating the evolution? Without doubt we have a Beetle In Software Engineering (box with pain inside) situation where everyone is defending their own version of the beetle.

https://medium.com/@fagnerbrack/wittgenstein-s-beetle-in-software-engineering-dcea89a5db92#.7ib85z19c

devin ivy
@devinivy
Apr 26 2016 01:12

That is challenging when things constantly change, like isolation did again over the weekend.

what are you referring to @HighOnDrive?

Stardrive ENGG
@HighOnDrive
Apr 26 2016 01:14
The API for isolation in CycleJS, it was completely rewritten again.
IHMO, I think going as frameless as possible is the very best way to go, especially if you want to get something actualized with minimal pain and to it's full potential.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 01:36
Sorry, I have to laugh. I hear your pain though.
@HighOnDrive I would argue that there is one human language that is formal enough to describe a beetle: it is the language of patent claims.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 01:47
As I mentioned before on this list, I have felt that this language provides a conceptual that spans from strategy to problem definition to solution specification and programming. It is all semantically aligned, it has to be all semantically aligned.
(you may have looked at it already)
Jean-Jacques Dubray
@jdubray
Apr 26 2016 02:00
For instance, the STAR conceptual framework can make easier to come up with this kind of conclusion.
https://lists.w3.org/Archives/Public/public-ws-chor/2006Jun/att-0013/WS-CDL.equals_Pi4WS__paper.pdf
This is a real case, because I was invited expert at the W3C on the WS-CDL working group and, with one simple diagram, I was able to shut down the conversation that the Pi-Calculus semantics were enough to describe Service/API choreographies. Apparently Mr. Bouché did not know about that discussion.
All these comparisons between formalisms remain at the level of "opinions" which contribute to the confusion.
Stardrive ENGG
@HighOnDrive
Apr 26 2016 02:12

I'm laughing too, as I tear into the joy of my work :smile:

Like this from Bolt, "Every action we take (you, me, everyone) connects two
states: a low value state and a desired high value state."

The Bolt introduction looks very concrete and comprehensive, will give it a good read after my session tonight! Right now I'm in high drive working on a exceptional "desired high value state" :fire:

Jean-Jacques Dubray
@jdubray
Apr 26 2016 02:18
I am glad you picked that quote, that's the most fundamental one of the document. Happy to hear your feedback.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 03:32
The article "Why I no longer use MVC Frameworks" has been translated in Chinese
http://www.infoq.com/cn/articles/no-more-mvc-frameworks
Jean-Jacques Dubray
@jdubray
Apr 26 2016 03:43
@axefrog Nathan, not sure if you caught that presentation. It distills very well the principles of Reactive Programming, which I feel are used abusively in a world that is, for all intent and purposes, mutable. It's a bit like saying we are going to explain how the universe works by making a copy of its state at any arbitrary point in time. You might run into a few issues along the way.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 04:04
@axefrog A couple of quotes about KVO:
https://twitter.com/s_m_mcguire/status/683894598784057344

From a discussion on HN:

This is actually roughly what knockout and ember (pre-glimmer) do. They are known as KVO (key-value observer) systems and have implementation challenges of their own: knowing when to batch operations, dealing w/ computed properties and rx glitches (in reactive systems, a "glitch" is the name given to temporary inconsistencies that occur between stable states), and added complexity in terms of requiring the model layer to be observable-based (as opposed to POJOs in Angular/React/friends).
Also, high quality KVO systems are far more difficult to implement. To my knowledge, Vue is currently the fastest KVO-based javascript library in existence and in order to support its POJO-like model API, it's significantly larger than Snabbdom (which is one of the fastest vdom implementations currently, despite clocking at a mere 200-300 LOC)
AFAIK, most of the challenges faced by KVO system have not been as extensively explored (at least by the javascript community) as virtual dom algorithm optimizations have, so currently I believe high quality virtual dom libraries are likely to perform better at various real life scenarios than current state-of-art KVO systems.

Jean-Jacques Dubray
@jdubray
Apr 26 2016 04:11

That is my main conceptual issue with stream-based Reactive systems

in reactive systems, a "glitch" is the name given to temporary inconsistencies that occur between stable states

I am certain that there is a large class of systems where "glitches" are nothing to worry about, but, I am just as certain that front-end architecture does not belong to that class.

Roman NL
@rnique
Apr 26 2016 04:58
@jdubray Isn't the problem with glitches a design problem, like the lack of "waiting" state or something similar? Also, isn't SAM pattern also vulnerable to glitches or race conditions, when not properly designed/implemented? Like with the rocket launch example, if the rocket is on the moon and we send commands from earth, we must consider at design time that our "abort" action may be received after countdown ends, so we would implement some checking/confirmation logic.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 05:03
yes, this is correct but Streams make and KVO in particular make it really hard to eliminate them.
It is true that SAM is vulnerable to the same glitches, but it has a conceptual foundation that makes dealing with them much easier.
if you look at the SAFE middleware you will see that it is rather trivial since no component is allowed to access the model and any mutation is serialized until the State is computed
that's problem of not having a state function in your architecture, and thinking that the application "state' us just a series of key value pairs.
all these semantics are not arbitrary at all
Roman NL
@rnique
Apr 26 2016 05:10
I will give a look at SAFE, I do consider important to manage state, that's what I like in SAM. Strange enough many projects using FRP have the state as second class citizen.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:16
I'd argue that pretty much any programming formalism since Abstract Data Types have built on the approximation that State ~ Property values.
weepy
@weepy
Apr 26 2016 08:19
Would you recommend against OO type classes when working with SAM?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:19
I understand the rationale, since that approximation is, roughly speaking, true 99% of the time, but the 1% left is like poison. In Front-End architectures this is more 80% so your code becomes unstable very quickly.
Again, SAM is a pattern, it can be implemented with OO without any difficulty, but these days I view OO as a hindrance rather than an enabler.
weepy
@weepy
Apr 26 2016 08:20
Yes I meant as in "all things being equal".
Can you elaborate
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:22
There are three programming models to choose from these days:
  • strongly typed / imperative (Java, ...)
  • weakly typed / declarative (~DSL)
  • weakly typed / imperative (JavaScript)
OO brings a lot of ceremony to any solution you build.
For instance, just being about to create functions which interface is {...} f( {...} ) is a huge step forward
OO languages never realized OO in the sense that structure won over message passing. JavaScript is so powerful because you are passing messages. So in a sense JavaScript is possibly most OO language you could find, since its core data structure is a message, but most people would not call that OO
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:27
People feel that OO is about Data Types and Encapsulation, that's what I no longer use
But I would not recommend "against" OO, it's just I feel a lot more comfortable using JavaScript.
weepy
@weepy
Apr 26 2016 08:29
You can do OO with JavaScript
I don't quite follow the last point
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:30
Yes I know, it's even worse since I don't see any difference between Closures and Classes. Writing a Closure in JavaScript is just a different way of writing a class.
As I said, JavaScript supports a "message passing" style that I cannot find in traditional OO languages.
Doug Crockford changed the programming paradigm in ways that will probably take decades to unfold, but ultimately, JSON may well remain one of the most enduring programming paradigms ever.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:37
After that, there are a lot of simplifications inherent to functional programming that you don't find in traditional OO languages, though the barrier starts to blur.
weepy
@weepy
Apr 26 2016 08:37
You mean that json is arbitrary so JS can support a different architect than most static or typed languages ?
Testing is easier if you can just do test(User.auth(userData))
Than creating a new User etc
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:39
sorry, I don't understand your question, but if I do, yes, I would say that it is JSON that sets JavaScript appart from any other programming language I know.
Sure, JSON also makes polymorphism work properly.
weepy
@weepy
Apr 26 2016 08:48
So your typical style is pure functions that accept json data. No typeof, this, or instanceOf
Well maybe typeof
And no prototype?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 08:49
Yes, I do a little bit of typeof but otherwise that's pretty much it, no prototype either.
I am a "service oriented" guy, I was building software in a service oriented way back in the early 90s with NeXTStep and Objective-C which collection classes would allow you to build your own flavor of JSON. I have never found a better programming model (or be able to adjust to a better one if you prefer)
Of course nowadays Objective-C is so rusty that developers walked away instantly when Swift was released, but at the time, it was quite something.
weepy
@weepy
Apr 26 2016 09:16
Do you namespace your functions like say User.auth, User.login etc
In terms of organisation
Jean-Jacques Dubray
@jdubray
Apr 26 2016 09:24
yes, that's what I have done with SAM code samples (actions.xxx, state.yyy, model.zzz ...)
weepy
@weepy
Apr 26 2016 09:58
Ah ok. Thanks that makes a lot of sense
weepy
@weepy
Apr 26 2016 10:07
I wanted to ask a question about the limit of UI state. If for instance I wanted to do momentum scrolling. Should the current position of the scroll and the current velocity be part of the model ? - i.e. the UI is stateless.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 10:09
That's a hard one, I am not an advanced UX expert, I have expressed that I tend to be involved in the design of OmniChannel apps (one back-end serves multiple, slightly varying front-ends).
All I can say is that the Action -> Model -> State is general enough to be used everywhere, that being said, I am not sure how this will play with advanced UI concepts such as momentum scrolling.
weepy
@weepy
Apr 26 2016 10:13
or how about an element that I drag around ?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 10:13
SAM does not rule out state in components, I have expressed that configuration parameters are perfectly fine. For me application state is about controlling its mutation (propose/accept/learn). When mutation is straightforward, SAM becomes overhead.
So if I were to answer your question without doing further research, I would say that current position and velocity are more component state than application state. They will be used to render the application state properly.
weepy
@weepy
Apr 26 2016 10:14
ok that makes sense
Jean-Jacques Dubray
@jdubray
Apr 26 2016 10:15
Dragging elements is 100% application state IMHO, the ability for a component to be dragged and then dropped somewhere meaningful need to be both controlled from a propose/accept perspective
weepy
@weepy
Apr 26 2016 10:15
so touchmove handler => action.move => ...
Jean-Jacques Dubray
@jdubray
Apr 26 2016 10:16
yes, that's what I would do.
There is this excellent article from SmartDraw. Did you see it?
weepy
@weepy
Apr 26 2016 10:16
yes i think so.
weepy
@weepy
Apr 26 2016 10:26
Thanks for the help ... it's slowly becoming clearer
Jean-Jacques Dubray
@jdubray
Apr 26 2016 10:27
no worries, hopefully this is helpful.
weepy
@weepy
Apr 26 2016 11:29
helpfully it's hopeful
Roman NL
@rnique
Apr 26 2016 14:11
@jdubray Can you recommend a kind of approach to design APIs for SAM; I know the data/message can be anything since it's decoupled from view, but too much freedom makes me wonder how to take best advantage of that, maybe building services (micro-services) around business capabilities shared by several UIs?
dnson
@imnutz
Apr 26 2016 14:15
@jdubray @brusand @rnique Thanks for advice!
Jean-Jacques Dubray
@jdubray
Apr 26 2016 14:16
The CRUD operations are completely decoupled from the view, that means you are free to adopt the API that you'd like.
When you deploy your actions on the server then their interfaces would be pretty much like events.
Generally people are shocked when I say with SAM you make an AJAX request and you get some HTML back (since that's what the view will display).
devin ivy
@devinivy
Apr 26 2016 14:18
or it could send the state representation of the view, right?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 14:19
but again that would really depend on the architecture you adopt. As I mentioned earlier you could have actions+model running on the server, and the state function on the browser, at that point the call would look more like a traditional AJAX call
devin ivy
@devinivy
Apr 26 2016 14:19
This message was deleted
@jdubray for your own purposes, do you think of the clients as being part of a distributed system? a la pouchdb, etc.?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 14:20
yes, exactly you have full flexibility
yes, I do think the client as part of the distributed system.
devin ivy
@devinivy
Apr 26 2016 14:21
any suggestions for keeping clients in sync?
it simply takes code to make that work, right? it's a subtle issue.
so i wondered if you ever use a larger tool for it, like gun or pouchdb.
Jean-Jacques Dubray
@jdubray
Apr 26 2016 14:22
they'd be polling the state function?
I guess the beauty of SAM is that it implements a true State Representation
Roman NL
@rnique
Apr 26 2016 15:01
@jdubray Thank you for advice, yes exactly I was planning to have actions+model on server + state on otherwise headless client
brusand
@brusand
Apr 26 2016 15:26
How modèle call state render ? Via websocket ?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 15:27
That would be an HTTP request to the action and the model with handle the response which will be handled by the State function
brusand
@brusand
Apr 26 2016 15:30
OK that s what i have in mind ouf :)
Jean-Jacques Dubray
@jdubray
Apr 26 2016 15:33
There are some sample code in the SAM-SAFE middleware repo, for instance:
function dispatch(data) {
            // client side
            //model.present(data) ;
            // server side
            $.post( "http://localhost:5425/app/v1/dispatch", data) 
            .done(function( representation ) {
                $( "#representation" ).html( representation );
            }        
            );
 }
The action is called on the server, which goes through the whole reactive loop and returns HTML
We could just as well returned the model (or parts of the model) and call state.render(model), with the State function being executed on the client.
The nap() function would work well too since it would potentially invoke another action on the server and trigger a rendering once the response is received.
If the State function was running on the server, and we needed to "nap" we would have to use something like webSockets to render the State properly.
dnson
@imnutz
Apr 26 2016 15:38
@jdubray how does SAM handle the case when multiple actions propose data to model?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 15:39
The SAFE middleware implements a "hang back" mode where the first action to present wins
Logically we cannot present another action until the reactive loop has completed with the execution of nap()
What's nice with action "hang back" is that you can cancel long running actions
Fred Daoud
@foxdonut
Apr 26 2016 15:40
neat!
Jean-Jacques Dubray
@jdubray
Apr 26 2016 15:40
I got the idea from Netflix
They said it was quite difficult to let users cancel these long running actions (searches, ...)
With SAM that's just a few lines of JavaScript
I'd say, just for that feature it's worth decoupling proposers and acceptors
Fred Daoud
@foxdonut
Apr 26 2016 15:42
so for example, cancelling a long-running AJAX request wouldn't (couldn't!) cancel the request itself, but would unblock the UI, let the user continue doing other stuff, and would ignore the request response when it finally came back, is that correct?
Jean-Jacques Dubray
@jdubray
Apr 26 2016 15:42
yes, exactly.
I keep a "step counter" so when the second action completes, and tries to present its data, it gets rejected because the step has already presented some data.
It's really trivial to implement but I would argue the effects are spectacular from a UX perspective
The code even handles the case where a new action of the same type could be triggered in the next step, while ignoring the same action type in the previous step. Heck you could even do some smart things like changing the step id on the fly it made sense, so you could reuse the result of an older action in the new step.
Fred Daoud
@foxdonut
Apr 26 2016 15:48
So, how do you differentiate present(data) that comes the user doing something after cancelling, from present(data) coming from now-cancelled ajax response?
dnson
@imnutz
Apr 26 2016 15:48

im in a situation that:
1) Listen for data coming from websocket
2) Fetching data from REST API

I had 1) in action which propose data from websocket to model 2) in model because it is CRUD.
Both of them are result in calling _state.render
now im in a infinite loop :(

my question is which is a proper way to implement this situation?
it is not exactly a infinite loop, but i think the data from REST API never has chance to call _state.render
Jean-Jacques Dubray
@jdubray
Apr 26 2016 15:58
@foxdonut as I mentioned, I use "step id", cancel will be presented immediately and the step counter will be incremented, such that a new action can be presented shortly after, as part of the new step.
@imnutz you should not be in an infinite loop... first, technically the Read operations could be performed in the action and presented to the model. I am not sure if it also true "logically".
second, the action cannot call render. The action would present query parameters to the model, the model would execute the fetch and accept (or not) the result of the query, then call render
When the model makes async calls, the render needs to be called once these calls return.
It's a bit late here, so I am going to disconnect.
dnson
@imnutz
Apr 26 2016 16:06

second, the action cannot call render.

yes, when i said _state.render I meant it is called from model

It's a bit late here, so I am going to disconnect.

ok, see ya. Thanks

Fred Daoud
@foxdonut
Apr 26 2016 16:08
got it, thanks @jdubray , good night.
dnson
@imnutz
Apr 26 2016 16:55
@jdubray the problem is in my code though, I figured it out.
brusand
@brusand
Apr 26 2016 17:52
Sam ne bugue jamais :) sorry french play on word (sam never bugged instead of this never bugged)
Jean-Jacques Dubray
@jdubray
Apr 26 2016 21:08
"ce qui se concoit bien, se code facilement et les instructions pour l'ecrire viennent aisément"?
brusand
@brusand
Apr 26 2016 21:11
+1