📜 ⬆️ ⬇️

Three Zena reactive extensions

Reactive Extensions is more than a framework. If only because there is a practically identical implementation (adjusted for the particular language and the corresponding optimization practices) for each popular PL. Yesenin argues that "a great thing is seen at a distance." In this note I will move away to different "distances" and describe what I see.

Zen first


I see the push version of the classic implementation of Iterator 'a GoF. I already wrote about this, so without details.

A brief retelling for those who are too lazy to read
The point is that Observer is (almost) a “mirror image” of the classic Iterator implementation. Why "almost" - explained in a post on a previously given link. Important note: “mirror reflection” is a mathematical definition without five minutes and can be formalized strictly .

At this distance, the difference between the push and pull systems is clearly visible. After this insight, every git push and git pull causes almost reverent awe. You start to rummage around the code and ask sacred questions about duals.

Zen second


“Something continues” (method next), “something completed” (method completed), “everything went wrong” (method error) - three statements that can describe any process that develops over time. Moreover, it is easy to abstract from physical time, replacing it with a “sequence of states” (in which the system turned out to be). Rx allows you to reduce a variety of algorithms to a single interface (in the sense of "agreement" of the programmer with other programmers and, more importantly, with the machine), without imposing any restrictions on the expressiveness (the number of possible states), nor on (optional: synchronous , asynchronous or multi-threaded) execution.
')
Hence the most important conclusion: one rx is one process. And if a complex process consists of n subprocesses, then ... one "higher order" rx, which controls the work of "first order" n rxs. By analogy with higher order functions .

Zen third


Similar to the functions? Yes, by functions. The last and most powerful insight is that rx is just a decoration of a function — programmer’s, not mathematical: the latter live out of time; the usual function is able to do return result; only once. And next (result); - this is a “reusable” version of return. Hence the most important conclusion: everything that can be done with mathematical (pure) and ordinary OO functions (including currying , composition , and many other things, which this essay does not cover), can be done with rx. Functions are blocking and asynchronous: rx too. Functions can return functions: rx too. Functions can be recursive: rx too. Function calculations can be cached: in rx too.
It is curious that at this stage of understanding you involuntarily return to ... functional programming. Not for the sake of declarativeness, not for the sake of immunity - these are all (optional) bonuses. In the "functional" because I have to think in terms of functions and their compositions; and according to the immutable law “one rx is one process”, namely functions (and not classes, abstract classes, interfaces, or whatever else is there) become the “starting point” in design.

That's all I wanted to say.

Source: https://habr.com/ru/post/441452/


All Articles