These are chat archives for jdubray/sam

25th
Oct 2016
Fred Daoud
@foxdonut
Oct 25 2016 02:10
@schtauffen I did not try with the rewrite, I prefer to wait for official releases :) but if it's not compatible, I'm sure it would be trivial to adjust; all it needs is to call m.render.
Fred Daoud
@foxdonut
Oct 25 2016 11:58
@schtauffen ok because of you I will try the rewrite :)
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 13:03
I was looking at this presentation yesterday, quite interesting: https://www.youtube.com/watch?v=AslncyG8whg
I don't find the combination amazing, but I am biased.
Fred Daoud
@foxdonut
Oct 25 2016 13:27
Netflix can make their own amazing TV shows but cant seem to film (or record audio) better than a high school student. haha
Edward Mulraney
@edmulraney
Oct 25 2016 13:38
@metapgmr_twitter this is why @jeffbski's redux-logic library is so great. https://github.com/jeffbski/redux-logic
devin ivy
@devinivy
Oct 25 2016 13:41
i haven't tried it, but it is an impressive lib! it pulls in rxjs, doesn't it?
i imagine reading the code of redux-logic might inspire some other ideas...
Edward Mulraney
@edmulraney
Oct 25 2016 13:43
yeah it does all the rxjs for you behind the scenes
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:03
Yes, Jeff's solutions sounds a lot more flexible. It looks like Netflix solved one use case, just another 100 to go.
Edward Mulraney
@edmulraney
Oct 25 2016 16:05
there's a lot more than one use case solved
what are the ones that aren't solved?
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:11
If you consider a database analogy for the actions/model, there is a potential to encounter most of the use cases covered by an average SQL engine.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:17
Wiring events to code is not so much the problem to solve, what's more important is to be as flexible and smart as to when the corresponding action can present a proposal (or not). I noted by Jay, Redux is very inflexible with that regard. I am not sure Rx, alone, adds too much.
The big use case that SAFE solves is introducing the concept of a "step", not understanding which step a particular action (instance) is part of cannot scale well. I don't see how that can be achieved with Rx.
I'd say, again and again (apologies for rehashing), you simply cannot ignore the underlying mutation, connecting events to assignments is the problem, not the solution.
Edward Mulraney
@edmulraney
Oct 25 2016 16:21
sure, but clearly that's not the problem they were trying to solve specifically
async/side effects
what is this step that SAFE introduces?
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:23
well, it's part of the broader picture, you cannot find a solution for one problem and then ignore the related ones.
Edward Mulraney
@edmulraney
Oct 25 2016 16:23
of course you can! thats how progress is made :)
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:24
SAFE keeps track automatically of which "step" you are in (a simple increment for every tuple of (actions,update,state representation).
It keeps track of the actions triggered in a step (which have not yet presented their proposal)
Edward Mulraney
@edmulraney
Oct 25 2016 16:25
and prevents new actions presenting theirs?
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:25
when a proposal is processed, and a state representation is created, we are in a new "step"
In particular you can be smart about actions instances of the same step
you can reject all the other proposals
that's how you do generic cancellations
since a "cancel" actions will propose immediately
but you could have situations where it's ok to continue accepting other proposals
All I am saying is that too much rigidity at that level (say like Redux) is not scalable, you need to offer flexibility in the ways actions are triggered (in response to events) and more importantly how these actions present their proposal to the model.
Edward Mulraney
@edmulraney
Oct 25 2016 16:28
don't SAM apps have a step notion enforced implicitly? we cant dispatch two actions without the first completing and updating state? (unless the proposal is to cancel an action for example)
without SAFE library
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:29
You can imagine that a user interface can be "muti-threaded" in the sense that different parts of the UI don't necessarily interfere with each other.
No, not at all, the step is conceptual.
To enforce it, you need to write some code (i.e. SAFE) that tags every action instance with a step id.
Edward Mulraney
@edmulraney
Oct 25 2016 16:29
i like that concept
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:30
yes, me too...
You can look at the code, it's not my average garbage. I was pretty proud of it.
Edward Mulraney
@edmulraney
Oct 25 2016 16:30
i will :)
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:31
The other important use case that Jeff/SAFE covers and Netflix doesn't seem to cover is "allowed actions"
Edward Mulraney
@edmulraney
Oct 25 2016 16:32
is that to catch edge cases? in general you render a ui which can only make allowed actions
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 16:34
The problem these days is that server events are becoming prevalent (Twitter, Facebook...) all kinds of stuff happens all the time, the user can also starts something (like watching a video) and start doing something else. All that creates a complex environment. I believe that's why Facebook started working on React. Their front-end code was too buggy.
In other words, you cannot expect the view components to be reflective of the correct application state.
When that happens you need to check for allowed actions.
Edward Mulraney
@edmulraney
Oct 25 2016 16:37
yeah that makes sense, actions coming in from server events
Netflix offer store.getState() in their Epics so you could make the decision to not allow an action based on your model
const incrementIfOddEpic = (action$, store) =>
  action$.ofType(INCREMENT_IF_ODD)
    .filter(() => store.getState().counter % 2 === 0)
    .map(increment);

// later...
dispatch(incrementIfOdd());
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 17:05
Fair enough, but I still don't see the big deal of Rx wiring in Front-End architectures. The rules are far more important than the wires. Generic "filtering" mechanism are not the kind of rules that are relevant.
Edward Mulraney
@edmulraney
Oct 25 2016 17:11
sure but it greatly reduces boiler-plate, minimizes opportunities for bugs and simplifies code. its like using ramda or lodash but for async stuff, incredible useful. the thing not really discussed in the netflix video was that this works because you are in middleware land so you can dispatch new actions within your "epic" (epic=async action, in this case)
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 17:16
I just don't see it (perhaps I am missing something), it's very simple for very simple use cases. For instance he talks about API orchestration. Just coordinating two API calls with roll-back is already difficult and callback hell is the least of the problems. SAM makes that manageable too: http://www.ebpml.org/blog15/2015/06/designing-a-reliable-api-call-component-with-sam/
devin ivy
@devinivy
Oct 25 2016 17:44
@metapgmr_twitter in redux this could be handled with middleware
that's where a "step" would live
Charles Rector
@chuckrector
Oct 25 2016 19:33
Huh. So I was having a hard time understanding why proposals and the ability to refuse them is valuable, until I just now watched a handful of RxJS videos by Jay Phelps and Ben Lesh, where they visualize a Netflix use-case for a customer choosing a video to play but then changing their mind and backing out to choose another one -- of course, they were pointing out the ability to cancel in-flight requests rather than wasting resources and running them to completion (due to Promises).
I wasn't actually thinking of SAM at all until I also then watched https://www.youtube.com/watch?v=L_eb7QqtE-I and then it became clear. I feel like synchronous toy examples, even somewhat less-trivial explorations like my little scene editor, make it hard to understand to the value of proposing changes to the model, which can be rejected. Async definitely makes the value more obvious, for me at least.
Edward Mulraney
@edmulraney
Oct 25 2016 19:38
@devinivy yeah you could tag an action in middleware, but what exactly does that enable you to do? simply prevent the next action until (for example) a previous async action resolves?
i can see its usefulness in optimistic UI updates (automatically queues actions until promise resolves)
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 19:42
@chuckrector yes, ultimately it boils down to:
an event happens -> how can we understand the context well enough to make sure what to do. That's what we are all after. UIs have become complex distributed systems. That's why in general I have doubts when people focus on wiring, wiring does not bring much to solve that problem. Personally, I like Pub/Sub. It's very flexible and does not get in the way. Streams seem to be a lot more rigid.
As you point out, you have to be careful of trivial cases, everything works in a trivial case.
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 19:52
@chuckrector for games context must be super important
devin ivy
@devinivy
Oct 25 2016 19:58
but even in your scene editor there is a good example, right? when dragging don't two actions need to be fired at the same time to avoid a glitch?
"coalesced"
@edmulraney middleware can intercept actions and dispatch them later, or discard them altogether
Edward Mulraney
@edmulraney
Oct 25 2016 19:59
sure - i mean what does tagging an action enable you to do?
Charles Rector
@chuckrector
Oct 25 2016 20:00
@devinivy hmm, i don't believe so. the visual "glitching" of the animations was purely a result of how the DOM was being modified (whole shebang vs VDOM diffing)
devin ivy
@devinivy
Oct 25 2016 20:01
what is "tagging an action"?
Charles Rector
@chuckrector
Oct 25 2016 20:01
i saw and understood how refusing proposals could be used in the way you used them, but because it could easily be done without, it was a bit "weak" in terms of "why refusing proposals is useful in general"
I'm definitely interested to grok more thoroughly how refusing proposals can provide a more critical value in a synchronous app. maybe reading huge files synchronously or something... not sure
or maybe the entire point is that only non-synchronous actions benefit from proposal rejection?
devin ivy
@devinivy
Oct 25 2016 20:05
@chuckrector the idea (i think) is that the UI might fire an action, but the UI might also not know if it's an appropriate time to fire that action. so someone needs to make sure the action is not one that brings you into an invalid state of your application.
Charles Rector
@chuckrector
Oct 25 2016 20:06
ah, hmm
Edward Mulraney
@edmulraney
Oct 25 2016 20:06
@devinivy tagging an action is what enables the "step" concept
devin ivy
@devinivy
Oct 25 2016 20:07
oh yes. so i meant middleware would enforce the steps, not necessarily just tag actions with step count/ids.
Charles Rector
@chuckrector
Oct 25 2016 20:07
so from that view, then the question is perhaps more -- how to know that it is best to reject a proposal, rather than preventing it at the point you would construct the proposal. for example, is having the action construction "know" about when is proper time to propose a bad idea in general in SAM? that is, the model should ideally be solely responsible for all validations that would impact model changes?
building more apps is probably the best way for me to answer that question :^)
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 20:26

@chuckrector @devinivy absolutely

how refusing proposals can provide a more critical value in a synchronous app

it helps building view components that no nothing about your application. You may not always be in the position where the publisher of the events knows if it is ok or not (event an event coming from the server via webSocket)

The action may even be allowed, but result in a proposal that is not acceptable. All this logic is better factored in the model. If you push it in the view or the action, you'd always have to make sure it's up-to-date with cross component communication for instance.
Zach Dahl
@schtauffen
Oct 25 2016 20:53

Food for thought: redux disallows actions based on composition. For example,

const todos = (state = [], action) => {
  switch (action.type) {
    case 'TOGGLE_TODO': return state.map(x => todo(x, action))
    ...
  }
}

won't trigger the "todo" reducer when todos is empty.
Array methods are logic flow in FP land

Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 20:57
Does that happen inside the reducer?
Zach Dahl
@schtauffen
Oct 25 2016 20:58
the rxjs + netflix got me interested in streams, with my preferred implementation now being mithril 1.0's m.prop (since it comes with my favorite view library :))
I'm currently working on a wiring library but hope to include a bunch of stream utilities which will allow cancellation, etc
yes, that is in the reducer
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 20:59
you should look at SAFE for generic cancellations
Vincent Jo
@inrix-vincent-jo
Oct 25 2016 21:00
@metapgmr_twitter hey JJ, the sync-http thing ... I looked at the npm website for the project and it says that it is quite unstable and not to use in production, I hope your blog will be okay
Zach Dahl
@schtauffen
Oct 25 2016 21:01
thanks, I'll check it out later this evening! I plan to check out meiosis still as well, :)
Jean-Jacques Dubray
@metapgmr_twitter
Oct 25 2016 21:01
@inrix-vincent-jo ah ah, it's just my blog, so far so good! thank you though, that's a good piece of information. Thank you.
SAFE is complementary to meiosis, at some point, I am hoping @foxdonut will add it to meiosis ;-)
@inrix-vincent-jo it kinds of proves that's completely non trivial
Fred Daoud
@foxdonut
Oct 25 2016 21:04
@metapgmr_twitter ;)
Fred Daoud
@foxdonut
Oct 25 2016 21:31
@schtauffen at first glance mithril/rewrite seems to work fine with meiosis. :thumbsup: