New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What does the T(transparent) in TFRP mean? #220

Closed
AriaFallah opened this Issue Apr 27, 2016 · 11 comments

Comments

Projects
None yet
2 participants
@AriaFallah

AriaFallah commented Apr 27, 2016

When I looked up Transparent Reactive Programming and Transparent Functional Reactive Programming, I was linked back to MobX, which was unproductive, and this 10 page paper which said

In a transparent frp language, the primitive operators are implicitly lifted, so they construct graph nodes when they are applied to time-varying values.

Is this paper the motivation for calling MobX transparent? If it is, is the @observable decorator what lifts your values?

Finally does this make MobX functional? Since it's so dependent upon mutation instead mapping new values like one would typically see with FRP libraries it's a bit confusing for me.

@mweststrate

This comment has been minimized.

Member

mweststrate commented Apr 27, 2016

The lifting is not done by the @observable decorator, but by the autorun, @computed and @observer methods. Where in normal FRP you have to explicit subscribe to the observables, and need operators to combine the different subscriptions, this is done implicitly in the case of MobX and other TFRP libraries; while running your reactive functions it observes which data you access, subscribes to them and in that way construct a graph of nodes that depend on each other.

Where the F in FRP in general stands for puzzles me a bit in the first place. Change values over time and reaction to that is imho always achieved using side effects in the first place. But well FRP is a much debated term. For example in the Rx family the purity is easier to spot, most operators require pure functions. Put purist even don' t call that FRP. Similarly, derivations in MobX (except for autorun), should be pure functions as well, not pure in terms of their arguments, but still pure and side effect free in terms of the closure it uses.

So the T is easily explainable, on the rest of FRP, well there is must debate about that in general even without MobX :)

@AriaFallah

This comment has been minimized.

AriaFallah commented Apr 27, 2016

@mweststrate agreed on the F. I tried looking up the difference between FRP and RP, but no one ever made the distinction. I just assumed FRP was RP in a functional programming language, and thus it carries the pure function style and immutability.

@AriaFallah

This comment has been minimized.

AriaFallah commented Apr 28, 2016

@mweststrate I just realized that everything in MobX is basically a stream, but just perhaps lacking the iteration properties of streams (unless I'm wrong in this assumption 😅 ). As you said you've just removed the need to explicitly subscribe and emit.

Does this mean you can conceptualize non transparent FRP libraries such as RxJS as graphs as well? If you derive streams from streams for example?

@mweststrate

This comment has been minimized.

Member

mweststrate commented Apr 30, 2016

All observables are stateful streams in fact. Set(ters) are emitters, get(ters) and observe are subscribers. Observables and computations are all "cold", and reactions are observers as well.

RxJs streams can be conceptualized as graphs as well, const c = a.combineLatest(b) gives the samee same dep tree as const c = computed(() => [a, b]) in MobX

@AriaFallah

This comment has been minimized.

AriaFallah commented Apr 30, 2016

@mweststrate While I have you attention in another thread 😅 ...I thought cold observables were generally not a good thing? For example, the guy who made cycle.js is now making xstream so that every stream is hot instead of cold.

Is there any advantage to cold streams?

@mweststrate

This comment has been minimized.

Member

mweststrate commented Apr 30, 2016

Yeah it is a bad comparison, as RxJs are event streams and MobX has value streams. What I meant by it: all 'streams' evaluate lazily; computations won't run if they are not used by some reaction. From every stream you are always able to get the 'latest' value, and only exactly that.

@AriaFallah

This comment has been minimized.

AriaFallah commented Apr 30, 2016

@mweststrate could you let me know where you learned about FRP, TFRP, value streams, event streams etc. ? Are there any sources that you looked at when you were writing MobX to help guide you?

I'd really like to learn more about this, but I know you're not exactly free so would it be possible for you to point me towards some resources to learn and the foundations and the related concepts that you built MobX upon?

@mweststrate

This comment has been minimized.

Member

mweststrate commented May 1, 2016

MobX algorithms are a bit more sophisticated, but this Tracker manual is I think one of the best explanations of TFRP. To understand the difference between computed and autorun check Knockout computeds. Rx I learned from some book I think, that is quite a while back.

Besides that a lot of ideas in MobX came just from googling on issues people run into with Knockout computeds / Tracker. It's how I figured that MobX should be synchronous, atomic, glitch-free, have pure derivations and minimize re-runs to make it predictable.

In short I discovered that you learn quicker about a framework when googling for its limitations then when googling for it's possibilities 🐹

@AriaFallah

This comment has been minimized.

AriaFallah commented May 1, 2016

@mweststrate what are the limitations of MobX? 😛

@mweststrate

This comment has been minimized.

Member

mweststrate commented May 2, 2016

The benefits of immutable data, like time travelling, those are harder to achieve.

@mweststrate mweststrate closed this May 2, 2016

@AriaFallah

This comment has been minimized.

AriaFallah commented May 2, 2016

@mweststrate

What are the benefits of immutability though? Normally I've heard

  1. Read only data with multiple threads. Also helps to implement something like STM.
  2. referential integrity. Like this quote from ImmutableJS

Subscribing to data events throughout your application creates a huge overhead of book-keeping which can hurt performance, sometimes dramatically, and creates opportunities for areas of your application to get out of sync with each other due to easy to make programmer error. Since immutable data never changes, subscribing to changes throughout the model is a dead-end and new data can only ever be passed from above.

  1. undo/redo

But if you think about these benefits:

  1. The JS you write runs on a single thread so those don't apply.
  2. MobX provides referential integrity.
  3. Undo/Redo is actually pretty easy since MobX provides observe. It took about 40-50 lines for me to do in mobx-store.

MobX is making me question the case for immutability in JS haha.

newraina pushed a commit to newraina/mobx that referenced this issue Nov 24, 2018

Merge pull request mobxjs#220 from alessioscalici/match-observable-ar…
…rays

Allow Mobx observables as snapshots
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment