These are chat archives for jdubray/sam

16th
Nov 2017
Jean-Jacques Dubray
@jdubray
Nov 16 2017 00:10
@devinivy that's how I parsed his comments, they are a bit convoluted. Perhaps "irrelevant" is too strong, but it seems to imply that encapsulation alone is not enough, and global state is not necessarily bad.
@pfurini there is no problem having parent/child SAM instances, however you cannot arbitrarily decompose the model (IMHO) Actions and State are integral part of a SAM instance.
Jean-Jacques Dubray
@jdubray
Nov 16 2017 00:16
With that in mind, yes, as we spoke earlier, it's perfectly fine to have a component SAM loop, it's actually desirable because some components can have a lot of state to manage outside the scope of the application state (a wizard that captures complex datasets).
devin ivy
@devinivy
Nov 16 2017 04:29

in the end that's not so different than properties/methods

hmm at face value, i can't totally get behind that. who calls the methods? what do the methods live "on"?

Holger Winkelmann
@hwinkel
Nov 16 2017 07:24
This Wizard example reminds me about one of the use cases of UI State Management. Which I would like to see mapped to the SAM pattern. Lets say the Complex wizard has a number of steps for filling in data. Now the User Device disconnects or baterie runs flat. The User comes back, this might even on a different device or Browser. From a UX perspective I like to have a continuity here to drive the UI to the rigth Step in the left wizard. A Similar example would be to drive the user to a UI Interaction which is driven by a server Statechange. Lets Say the Application requires two more sets of data or a confirmation Dialog. This should work with SPA sites too
Paolo Furini
@pfurini
Nov 16 2017 08:55
@devinivy a component should expose at least one read-only property (or a get method, that's irrelevant) to peek the current state bag of the component itself. Write properties are forbidden. If the dev wants to expose, in addition to the entire state bag, single read-only properties to peek some leaf nodes of the state bag, that's fine too
as far as methods are concerned, they should map to public intents (in the SAM terminology) that are aimed to be used by the host's SAM loop. Not ALL intents are published , we should distinguish between private intents (to drive the internal workings of a complex component), and public ones (like intents to control the step of a wizard, for example).
Paolo Furini
@pfurini
Nov 16 2017 09:03
Then, we need a public intent, say setState(stateBag) (or reset, or whatever), that can be called every time (not only at construction). This is an intent that carries, as
its payload, the entire state bag, and proposes it to the model. Here we will validate the consistency of the entire bag, compute the state representation, and render (or re-render) the entire component.
The benefit of being able to call that setState intent at every time, is that we can implement a reload pattern every moment.
Paolo Furini
@pfurini
Nov 16 2017 09:11
do you see a well-known pattern here? I do.. these are plain old OOP principles, call them how you want, but that's it. What makes the difference is to avoid common pitfalls in component development, and SAM/TLA+ helps doing that. For example what changed my vision much, is the idea that the current state of a component should never be set by a myriad of disconnected write properties, or single set... methods, because it becomes nearly impossible to maintain internal consistency.
by giving a single setState method to the host, I can assure the consistency of the model as a WHOLE, and reject and accept it with confidence
Paolo Furini
@pfurini
Nov 16 2017 09:16
then, I think about the public interface of my component as a set of intents, that could be accepted or refused, and that drive a well-documented FST embedded in the component. The component's state bag is not hidden, but exposed as read-only to the host, so that it can be part of the host's state bag as a sub node
Paolo Furini
@pfurini
Nov 16 2017 09:21
every time the component's state bag changes, the host can reinstate the new bag in its own tree. Giving that state changes could occur by internal intents (for example a click event is a common external input, mapped only as a component's private intent), the component will implement an Observer pattern to notify the host when the state bag is changed. The only purpose of such notification is for auditing, logging, or, as said above, for reinstating the component's tree into the host's tree
that's more or less my vision of SAM driven components.. I'll try to write a couple of components with this in mind, starting for the simplest ones
Paolo Furini
@pfurini
Nov 16 2017 09:27
(ERRATA: FST was FSM, but I can't edit anymore :smile: )
Paolo Furini
@pfurini
Nov 16 2017 09:37
regarding mutability, I clearly see a big hole here if when peeking the internal state (model) of my component, I simply give back the root of my internal object. I can simply say "please don't touch this", but apart from that I should make a deep clone of my model before passing back to the caller
arbitrary mutability IS a danger, and it is one of the main pitfalls of OOP architectures in the last decades
global state IS a danger, whilst read-only global state, with segregated sub-trees that are written only by the owning components (component = UI component/app component/entire screen, etc.) is a good way to go IMHO
Paolo Furini
@pfurini
Nov 16 2017 09:45
it's more or less the same debate around type-safe and dynamic languages: dynamic languages rely primarily on the "good citizens" pattern for cooperating components, and a lot of low-value unit tests just to see if I haven't misspelled something.. on the mutability/global state side, I can rely on my colleagues not fiddling with writeable state, and hope in the best, or embrace controlled mutability (and hence public/global immutability) to enforce state consistency
Paolo Furini
@pfurini
Nov 16 2017 09:53
sorry if I insist on this "component" story, but sometimes when writing academic articles or proof-of-concept code, we forgot that we need reusability. No shop out there is willing to start from scratch with every app they build, so we need a way to efficiently decouple big UIs into smaller reusable and pluggable components, and the global state should only be used to drive the real unique "business" logic of the host application. In my vision even a wizard to create a new user in an application should be pluggable in every app I use, or even a multi-screen component, like the entire "user management" story/epic
in this case I could embrace a central state pattern, but only with segregated subtrees like said above. Every component should be responsible for writing own tree, whilst an observer should always be read-only
Jean-Jacques Dubray
@jdubray
Nov 16 2017 11:40
@hwinkel Yes, this is a very important use case. I was at a conference on PouchDB last week-end and I plan to create some sample code to illustrate that. Of course SAM really helps in that case because the model could have different state representations (one per device). The idea is to store the model in PouchDB, which replicates to a CouchDB server. This framework makes it easy to implement: http://hood.ie
Jean-Jacques Dubray
@jdubray
Nov 16 2017 11:45

@pfurini yes I think that's the core of the argument:

by giving a single setState method to the host, I can assure the consistency of the model as a WHOLE, and reject and accept it with confidence

even when we don't use big words like OOP, FP or even taking SAM off the table, we should have a discussion about mutation vs setters and methods. Unfortunately React does not go all the way and "setState" is tied to rendering, not mutation.

Jean-Jacques Dubray
@jdubray
Nov 16 2017 11:50
@pfurini in SAM the reusability is in terms of "building blocks" not components. Themes, actions, acceptors and reactors are all reusable and can easily be assembled into an application. IMHO "components" create an unwanted coupling. The whole point of SAM is to decouple the business logic from the view (and avoid horrific things like data binding), with that in mind, there is no "component" model possible in the traditional sense.
There is also another notion in SAM that is foreign to pretty much all programming paradigm I have seen so far, it's the notion of "step" and consequently the fact that a consumer of the "State Representation" will only be able to get a snapshot at that particular moment in time, at the end of the step. From there the consumer can reason about its own state and the state representation, trigger actions and so on, but it's critical, absolutely critical to think in term of steps and state representation.
Fred Daoud
@foxdonut
Nov 16 2017 12:08
@formido ah yes I did that one in this Meiosis example
Paolo Furini
@pfurini
Nov 16 2017 13:52

there is no "component" model possible in the traditional sense

I'm not sure about that, a "componentization" is always possible, just need to define the correct boundaries, and reason about the allowed interaction patterns

I have a couple of partners that builds so called data-driven back-office systems, with heavy data entry interfaces, and willing to go mobile, and/or have lighter interfaces to be consumed by clients, partners, agents and so on.. they ask for a streamlined way to build UI/UX that can drastically reduce the amount of time to assemble this new UIs, and having a "library" of reusable app components is at the heart of this strategy
everything that cannot be "automated" in some way, or at least made straightforward for the average developer, is not a solution from my POV
Paolo Furini
@pfurini
Nov 16 2017 14:09
please note that to me the "component" is an orthogonal concept... a component could be an entire "appointments" module for example (just received a call about that), comprised of headless components (business components, or call them services if you want), and several views, that can be hoisted in a container app as a whole.
This fat component must be comprised of many other sub-components, but at the end we can always reason in terms of inputs and outputs.
If that I/O is in the form of public intents that will map to internal actions (inputs), or peeking state representation changes after each step PLUS visual/external side-effects (outputs), I can always call that a "component", even if it is not a traditional one..
Jean-Jacques Dubray
@jdubray
Nov 16 2017 14:26
I have pounded on that question for 20 years and the best answer I can give is that only building blocks are reusable, not assemblies of building blocks. That is a myth. That's why Depency Injection became so popular, though it never focused on the granularity of what was injected. I have seen no evidence at all that we could reuse anything at a higher level of granularity in all the projects I have built or analyzed. Dynamic typing and message oriented interactions are key to building these assemblies. Everything else is just a house of cards from the evidence I have seen.
Paolo Furini
@pfurini
Nov 16 2017 14:39
that's the point, the way we assemble higher level components.. there could never be one-size-fits-all components, but having in mind the constraints from start is a good starting point
Jean-Jacques Dubray
@jdubray
Nov 16 2017 14:41
I see a difference between building blocks and components.
Paolo Furini
@pfurini
Nov 16 2017 14:54
I only see a difference in terms of different constraints and patterns (and terminology)
Michael Terry
@formido
Nov 16 2017 17:43
@formido ah yes I did that one in this Meiosis example
Very cool!
Paolo Furini
@pfurini
Nov 16 2017 17:58
@jdubray re https://twitter.com/addyosmani/status/912556308649304064 (dynamic import).. I had that a lot of time ago thanks to SystemJS ;)
(they are integrating systemjs import pattern right into the browser, that was the same exact way I was dynamically importing universal modules with SystemJS, couple that with HTTP/2, and progressive loading is a breeze!)
Jean-Jacques Dubray
@jdubray
Nov 16 2017 18:21
I am just trying to illustrate that "the platform" is coming together and people should take notice. Things are changing across all dimensions, for the better.
Michael Terry
@formido
Nov 16 2017 19:04
What's an example of a typical component that has an unwanted coupling?
Jean-Jacques Dubray
@jdubray
Nov 16 2017 19:11
The most horrific example I know is when someone makes an API call from a (view) "component" even when it is wrapped in a "service" say like in Angular.
Michael Terry
@formido
Nov 16 2017 19:18
as opposed to an event on the component triggering an action that makes an API call or
Jean-Jacques Dubray
@jdubray
Nov 16 2017 19:18
yes
No far behind is the coupling of the application state "encapsulated" in the view component, what if another component need bits of that application state? they use a getter? Oh my...
We need to switch the paradigm from components to building blogs.
Just like Web/GUI Frameworks, there is not a component model that stood the test of time.
Jean-Jacques Dubray
@jdubray
Nov 16 2017 19:23
Event something as low level as DRY is being questioned now
Michael Terry
@formido
Nov 16 2017 19:23
nothing has stood the test of time
just functions and procedures
when I use components, I don't necessarily tie it to being stateful
Jean-Jacques Dubray
@jdubray
Nov 16 2017 19:25
Isn't that a problem? They will be challenged too... It's time for a young generation of Software Engineers to turn all these concepts on their head.
Michael Terry
@formido
Nov 16 2017 19:25
and I do like having all my I/O sequestered away ini one part of my code, away from any components
I use them as prefab UI with defined behaviors
Jean-Jacques Dubray
@jdubray
Nov 16 2017 19:26
What I am trying to say is that semantics are key, creating an artificial boundary called "component" which has no semantic foundation is bound to fail.
Michael Terry
@formido
Nov 16 2017 19:26
they seem useful that way
yeah
Paolo Furini
@pfurini
Nov 16 2017 19:26
@jdubray as you already know, I do not agree with these anti-components statements.. there's only a need of a new generation of architectures to glue together a new generation of components
there will never be a UI world free of components, they are just here to stay.. driving in the opposite direction will take a young dev without a job, probably
Jean-Jacques Dubray
@jdubray
Nov 16 2017 20:02
Paolo Furini
@pfurini
Nov 16 2017 21:36
well, indeed it sounds interesting.. with a couple of beers it could even be better! :smile: :sparkles: