Introduction to ReactiveX without saying Functional or Reactive
This post is the self translated article of what my wrote in Japanese as my test posting to Medium.
In nowadays, I saw many articles which talks about Reactive Extensions (Rx or ReactiveX). They uses a shining word like “functional” or “reactive” to explain Rx. But I feel also there are not any good articles to describe Rx for people who are a foreigner about reactive or functional programming (e.g. Haskell, Scala, Lisp, OCaml, or etc…). Most of blogs about Rx displays a usecases but I feel they’re very specialized to describe it and so it’s difficult to understand the benefit in days. Why they talking about only data binding? It’s just the one of usecases! “Stream is just a ‘river’”. Oh, it’s too poetic!
Perhaps, .NET community has already told about this context with more clear or beautiful words. They originates this paradigm, but I could not find it…… So I’ll to introduce Reactive Extensions as more generic context in programming and for foreigner about reactive or functional programming.
It’s known widely as classical Observer pattern that there are “Receiving an event, and invoking a callback which is registered before”. This pattern is useful to notify “something are changed” and catch them. The typical usecase is GUI programming. We could observe user’s clicking action as an event, and process some operations. The callback which is invoked by a network response is same pattern if we treat “a response is an one-time event”.
Event pattern is useful to code to watching some state. If we don’t use its pattern, we need to polling whether a state is changed or not. It’s very messy :(
By the way, this classical “event pattern” has a problem. A event is asynchronous inherently, comes suddenly, and they are scattered without their relationship (in other words, we might be able to express that they’re discrete). There’re a minimal rules which is a network request comes after the network response is dispatched, but they don’t have any information about when a event is produced and relationship with others.
If all events are scattered in arbitrary timing for each of them, a programmer who uses their events have to manage their order queue by using a flags by self. Let’s enable flag A’ if you receive a event A, and enable flag B’ if you receive a event B, and check their flags to try to continue the next steps. Oops, sorry, you should check a new flag C’ with waiting 300 ms after you enable the flag A’…… I’m living in the hell!
This problem that is “increasing events and they have a relation in them” will be grown to a big matter in programming, e.g. GUI programming. Each of GUI change or user interaction will be a new event and they chains to produce a new events…. Furthermore there are more events in a mobile device. network connection status, environment light, receiving SMS, battery, etc. On a server side, there also many event source. pub/sub logs, status of nodes in large cluster, a request from a client is also the event!
ReactiveX — was called as “LINQ to Events” — propose a solution for this complex problem. It’s that all events a relational data set based on a time and they’re queryable by some relational expression. Like some above examples, if they’re scattered without any information at first sight, all events have some relation in them implicitly. Rx enables to express their relationship as human readable code, just query a data. As the result, we can create a new event easily with using other relationships.
Rx also introduce a scheduler terminology to control a timing of events. It enable to unify an asynchronicity of thread models into ReactiveX.
Furthermore, Rx makes an event to an object rather than string/symbol or one-time value in callback arguments. This change transforms an event from goto jumping to a obvious relations ship as a code. We can treat an event as first class object so we’re able to analyze them as a syntax or a method call that preserves semantics in a program by this change. Finally, we can visualize a events relationships, or refactoring them by safe with using IDE.
A difference to Promise<T> is that, Promise can change the status by self only once but it means we can only use Promise for an one-time event (so this also means Promise needs pull-based invoking). Thus we cannot apply Promise to an events which might be produced many times in the future.
By the way, implementations of ReactiveX create many objects to manage a complex async events relationships, so we may feel this approach lacks a balance of performance payments and programming benefits. But this is
imaginary fears. Now we can avoid their penalty as costs in a application layer by evolving hardware resource, a progress of compiler/virtual machine, and the great benefits of programming model abstractions. If you cannot avoid such regression cost, you can use a conventional approach. We can take them as before. Switching a programming language (e.g. JS->Java/C#->Cpp) may resolve this performance problem. So there’re no problem.
And more, we can dispatch a newly events cheerfully by decreasing a burden of event processing. Therefore, we can produce a side-effect easily if we really need it. The one of problems of side-effect is that the following processing group depends on a some previous state cannot handle their assumed previous state change correctly. This problem will be resolved if we can notify their assumed state change to following state as an event and recompute the new assumption. Then we can process the following processing group. (Of course, a side-effect usually should be restricted) (This thought is stand on the above “we can avoid the cost”, if the recomputing will need a large cost, then we should not recompute it.)
Ah, you might be better to read the introduction of ReactiveX.io. They say:
It is sometimes called “functional reactive programming” but this is a misnomer. ReactiveX may be functional, and it may be reactive, but “functional reactive programming” is a different animal.
Roughly like this?