These are chat archives for jdubray/sam

5th
Jul 2017
Nivani
@Nivani
Jul 05 2017 05:54
I just read the article and I like it. The way it is implemented is much closer to the classical use of Angular than your previous examples. That way the step to start using it for existing Angular users is much smaller.
As it happens, I've written down some ideas in the last week to implement something similar for wiring SAM pattern borrowing ideas from ngrx/store and this article I've linked you before: https://vsavkin.com/managing-state-in-angular-2-applications-caf78d123d02
Victor Noël
@victornoel
Jul 05 2017 07:32
vsavkin made a talk about that in May (see https://www.youtube.com/watch?v=brCGZ8Lk-HY and https://github.com/vsavkin/state_management_ngrx4) but I was a bit disappointed by his presentation. There was though a very interesting point: the relation between the router and the state and how they can be well integrated
also it shows how a modern SPA is made with angular and ngrx
This article about architecturing SPA in angular was better done I think: http://blog.mgechev.com/2016/04/10/scalable-javascript-single-page-app-angular2-application-architecture/
Victor Noël
@victornoel
Jul 05 2017 07:50
@jdubray nice article on medium, but there is many sentences that are not grammatically correct :P also, I think you should adopt a non-callback oriented programming in your examples, it makes things much more complex to read, especially when two paragraph before you presented it as a composition of functions! Basically, I'm sorry but I think the example are not clear enough for someone that discovers SAM :)
Nivani
@Nivani
Jul 05 2017 08:49
@victornoel thanks, I will check it out
Jean-Jacques Dubray
@jdubray
Jul 05 2017 13:34
@victornoel sorry, hopefully I corrected most of them. I don't understand your point about non-callback. The SAM pattern is a reactive loop, there is no callbacks.
Victor Noël
@victornoel
Jul 05 2017 13:38
@jdubray sorry, I wasn't clear at all, I don't have the correct vocabulary :) I meant that accept calls render, the actions call accept and so on. Instead of having actions being pure functions returning a proposal, accept mutating the state, etc, and an external loop calling each of these function in turn as in State( Model.present( Action( event ))). then( nap )
Jean-Jacques Dubray
@jdubray
Jul 05 2017 13:39
@victornoel sorry, I don't want to have this discussion again, it simply makes no sense, this is syntactic, not semantic.
there is absolutely nothing that says the syntax of a pure function must be output = f(inputs)
semantically a pure function is a mapping between two sets (inputs, outputs)
Jean-Jacques Dubray
@jdubray
Jul 05 2017 13:45
anything else is some Cargo Cult that some guy came up with and everyone else believed it
Even functional programming itself is a Cargo Cult
Jean-Jacques Dubray
@jdubray
Jul 05 2017 14:25

Sorry to be a contrarian, but there are two points of view you can adopt for the route:

  • it points to a particular application state (aka the source of truth)
  • it is an action (which results in a given application state)

I believe a route is an action, not a pointer. There is no "pointer" in SAM. You should not add semantics arbitrarily because it looks cool or seem to address a particular use case. Breaking semantics should be done with great care and my experience is that you always end up in a corner and you regret making that choice.

The problem with the router being with the source of truth is that we all know that's not true. We can never put the application in a particular state given a route. Please note that I am not saying that routes are useless, they are useful, but not with the semantics that Victor presented. These semantics are a dead end. He is generalizing a point of view that is not generalizable.
Fred Daoud
@foxdonut
Jul 05 2017 14:45

@jdubray I wouldn't say you are a contrarian. I think you are correct in your statement of the two possible approaches of routing, and I agree with your point of view. I have been considering routing lately and have also come to the conclusion that treating routing as an action is a much better design than trying to have a router as a source of truth. A route change becomes an action much like any other action, and the rest of the code works the same.

A different way of putting it is that most of your application should be the same with or without routes. You could add routes as an additional way to trigger actions, but then you should also be able to remove routing without much impact on the rest of your application. This goes back to the tweet you posted, saying "make your code easy to delete".

The author of router5 says the same thing in his presentation -- routes should be actions. (I find router5 itself to be too complex, too much setup and moving parts to align to get it working, but that's just my personal opinion.)

Jean-Jacques Dubray
@jdubray
Jul 05 2017 14:51
@foxdonut thank you

You could add routes as an additional way to trigger actions

yes, it's ok to use as "pointers" too, but it's really an action that results in a repeatable state, even though it looks like a pointer, it is not.

Victor Noël
@victornoel
Jul 05 2017 14:56
@jdubray I just meant that it wasn't making thing clears in terms of pedagogy in this article, not that you should use one or the other…
Jean-Jacques Dubray
@jdubray
Jul 05 2017 14:56
from a programming model perspective you really have to give things clear, even "back" is an action.
The problem is that REST and the browser has created semantics that work well with documents. They are actually actions that apply to documents, but unfortunately they do not apply well to application state.
That's why I emphasize the point of view of semantics and always ask the question what are the semantics, very often given a single use case the semantics will overlap and that's where things can go south as you apply some semantics to new use cases, then it no longer works.
Victor Noël
@victornoel
Jul 05 2017 15:43
Concerning the routes, I like your analysis! I was expecting you to react when I posted the link :P
Marcus Feitoza
@mfeitoza
Jul 05 2017 16:43

two cases:

  • synchronous req/resp: NAP has limited use, only synchronous (you can run an additional action before you return the response)
  • one day everything will be asynchronous and we will no longer use HTTP1,2,3,4,5... because, well ...you know... the world is not just resource-oriented and nobody really cares about the hyper part, that day we'll use proper protocols such as Websocket and in that case we'll nap all we want.

I think in case when you need to send an email or sms for example:

  • intent: createOrder
  • accept: orderCreated
  • nap: in context of request
  • nap: out of request like send email or sms

Or actions like this should be responsibility of another part?

Jean-Jacques Dubray
@jdubray
Jul 05 2017 20:18
that sounds reasonable. If it's a "fire-and-forget" action. You can also update the model with the result, with the understanding that the UI would not be updated until the user queries the state representation.
@victornoel I am not a big REST fan, I understand it's attractive, looks almost right, but in the end "document" semantics don't make up a programming model. That was clear from the beginning, it took 8 years or so to start seeing articles doubting REST.