These are chat archives for jdubray/sam

24th
Aug 2016
Jean-Jacques Dubray
@jdubray
Aug 24 2016 01:09
@riccardoferretti nice video on Leslie Lamport, just wish people would show a bit more interest on his work.
Riccardo
@riccardoferretti
Aug 24 2016 08:42
@jdubray thanks for the pointers
Fred Daoud
@foxdonut
Aug 24 2016 18:00
@chiwoojo and all, I have added a Meiosis example of components that manage their own state. They are nested within the single-state model, but do not need to be aware of where they are located in the model. They only work with their sub-part of the model. The example also demonstrates validation. http://meiosis.js.org/examples/temperatures/index.html
Notice there is a "temperature component" that is used twice, one nested at store.temperature.air, and the other at store.temperature.water. But the component only needs to work with model.value and model.units.
There is also an "entry" and a "date" component to demonstrate validation. Each component manages its own state, with its own receive function. The "form" component manages the root model.
For example, this is the receive function of the temperature component: https://github.com/foxdonut/meiosis-examples/blob/master/examples/temperatures/temperature/receive.js
Notice that it manages its own state and only deals with model.value and model.units. Now, here is where the higher-level form component creates two instances of the temperature component and nests their models at store.temperature.air and store.temperature.water: https://github.com/foxdonut/meiosis-examples/blob/master/examples/temperatures/form/main.js#L22-L23
Fred Daoud
@foxdonut
Aug 24 2016 18:06
I'm using object-path for convenience of setting nested properties on the model, and validate.js for validation.
I hope this is helpful, and would appreciate any comments/feedback/discussion, thanks.
Jeff Barczewski
@jeffbski
Aug 24 2016 20:24
@riccardoferretti @jdubray I'll take the opposing viewpoint here, I think immutability does help with preventing unexpected updates. If you use eslint-plugin-immutable and related eslint rules, they will help you prevent mutations in your code. You can even go the route of freezing objects in development if you really want to prevent changes (like seamless-immutable) does, but I don't think that is necessary. There is still good benefit in what we an achieve just with the tools like eslint. You get to a place where most of your code is immutable and that just makes things easier to reason about. I haven't spoken to anyone who is having scalability issues with Redux, everyone speaks very highly of using it. If someone were to have issues with the size of the Redux state tree and copies, then immutablejs would likely be a good solution since it works well when the objects and arrays get large. Besides immutablejs there are some other nice libraries like timm and updeep which make working with immutable objects easier. Just my $0.02, your mileage may vary.
Jean-Jacques Dubray
@jdubray
Aug 24 2016 21:57

@jeffbski What is the difference between:

var m = new Model();
m.accept(proposal).then(access)

and

access(m = accept(m, proposal))

There might be some legitimate cases for making some part of the model "immutable", because they are truly immutable but there reality is that the whole point here is to mutate application state, one way or another.

The biggest issue I have with Redux/immutability is that it conflates proposers and acceptors and assignments with mutation. There is tremendous benefits in deconflating proposers from acceptors and assignments from mutation.

How does immutability help with that goal?

Jeff Barczewski
@jeffbski
Aug 24 2016 22:00
In your example, the difference would be that the original value is still what it was to start with so it is still available if you wanted to use it for comparison or to revert, etc. When calling pure functions you don't have to worry about them influencing your data in an unexpected way.
Yes obviously under the covers some data is mutated but not by our code, so things are easier to reason about. It's a similar argument to why using pure functions is easier to reason about than using object oriented code where data can be changed by any number of parents. While with a pure function it is really all right there, inputs and outputs.
Jean-Jacques Dubray
@jdubray
Aug 24 2016 22:04
But in SAM, nobody can mutate the application state, one can only present proposals.
The biggest lesson behind TLA+ (I don't want to say SAM, because SAM is merely using TLA+) is that factoring is everything, when you get the factoring of your code wrong you enter a maze that you will most likely never exit.
Jeff Barczewski
@jeffbski
Aug 24 2016 22:13
Redux does allow you to break up your logic, so that you can separate out the various parts. You would use middleware to pull out your business logic, leaving your mutations to be very simple. My redux-logic library is one way to do that, but custom middleware could work similarly. There are lots of nice features that are enabled by an event sourced architecture like Redux. Event sourcing has shown its power on the backend with distributed systems and now we can extend it to the front-end as well. It is exciting times.
I'm confused by when you say in SAM, nobody can mutate the app state. Since SAM is a pattern that we implement, we mutate the state with our code that accepts the proposal, correct?
Jeff Barczewski
@jeffbski
Aug 24 2016 22:20
I agree with factoring and finding the right abstractions, once you find the right ones, things just work beautifully. I'm feeling this way with my current functional JS, React (using stateless function components), Redux, redux-logic approach.
Jean-Jacques Dubray
@jdubray
Aug 24 2016 22:26
yes, sorry what I meant is that there is no direct way to mutate/access state outside the model when you implement the pattern correctly. The model accepts proposal and then request the state function to render the state representation, when the mutation is complete.
The problem I have with Redux is that its programming model is not prescriptive enough. You may end up using the right way, but de facto operating mode is event -> reducer -> view, the number of additional library required to use Redux correctly is now comical.
Jean-Jacques Dubray
@jdubray
Aug 24 2016 22:44
considering that non are required, including Redux itself
Jeff Barczewski
@jeffbski
Aug 24 2016 22:47
For redux, I currently just use redux, react-redux (if I am using React), and redux-logic so it seems reasonable to me. I mean if having separate things is an issue, you can simply create a package which includes whatever ones you are using and exports the functionality, then you'd have just one dependency.
Jean-Jacques Dubray
@jdubray
Aug 24 2016 22:53
Ultimately, Back-End and Front-End have to align, this is what SAM delivers above and beyond any Web framework I know:
blob
In React or Angular, an API call is just a call, there is no particular good way to call an API from them, "it depends", then you have to consider these discussions about side-effects precisely because now your reducer is a pure function. Sorry, I really don't see the light.
I know you are trying to find a middle ground, but I don't really see one. My expectation is that React/Redux will "peel off" as Facebook releases version after version, until they are no longer there.
That process has already started as people have started to realize that a React component is "just a function". That was predicted by SAM, the remainder of the library/framework will dissolve just as fast.