Reactive programming and its implementation
Another approach to languages that facilitates the description of the system, and therefore the real world.
Definitions of reactive programming are similar to mathematical ones and are contrasted with procedural (or imperative) programming describing command lists.
For example, when in classical procedural language it is written::
a = b + c
The value of a does not depend on b and c, but on the values that they have when the processor encounters this line. It will change only with the new assignment of the variable a.
In reactive programming, a becomes dependent on b and c for the duration of the session. Each change in the value of these variables changes the value of a.
And if we then ask:
b = d + e
the value of and will also indirectly depend on the value of d and e.
This approach allows a much more intuitive description of a moving complex system or object. For example, to describe an explosive engine, data on speed, weight, acceleration, displacement, braking can be determined based on these variables and obtain a consumption variable that varies depending on each change in each of these parameters. It is clear that this approach is also suitable for determining the behavior of the robot and its interaction with the environment .
A reactive approach can create difficulties. Thus, if one determines:
d = a + z
Since it indirectly depends on d and d depends on a, the value of a becomes difficult to determine. This is the same problem as in procedural language if a call to the f2 function occurs in the body of the f1 function and an f1 call occurs in the f2 body.
This operation is absolutely valid if, depending on the result, an end condition is added, if it is not part of an infinite loop. It is a form of recursion.
When transferring indirect recursivity to the PR level, you can specify that a = b and b = a + z, if one of the two definitions has a condition, the first is the value of b, the second is the value of a.
But if the objects of the model are a transposition of the real world, this is not necessarily necessary. This is tantamount to including in the code the interdependence that exists in the real world. Which is really the goal. But this can only work in a competing system, otherwise these two definitions, working in an infinite loop, would monopolize all processor resources.
Another difference from procedural programming is that a variable can have only one purpose, describing all its dependencies, while the variables of classical languages change throughout the program. This can only make the code more compact.
When is it best to use reactive programming?
Each time the problem is more difficult to express than the solution.
Take the case of the booking system. This is described as a set of booking fields, on the one hand, a list of resources that allocate slots, on the other - a queue of customers who look at the flags to select a schedule that has not been reserved. Each check box is selected as empty, highlighted, or reserved, and each value depends on an external event initiated by the resource or client. Part of the "process" is simple, and comes down to registering resource and client records.
On the other hand, take the case where we have a very large list of words that need to be sorted as quickly as possible: the problem is simple, the words need to be in alphabetical order. In order to achieve this result the fastest, algorithms such as Quick Sort or Insert Sort are used, so procedural programming is better suited here.
So imperative mode is better suited for expressing processes and transformations and declarative interaction mode.
Reactive programming vs. imperative
Along with the main differences that lead to the IC operating in a sequence of states, that variables depend on subsequent assignments, it should be noted that the imperative program controls operations, it operates, and even if it chose a procedure based on external inputs, in some procedure the action comes from the program itself.
In PR, on the contrary, the program only reflects the actions and interactions of the actors, and in itself has no actions on them. The actions of one actor depend only on the actions of other actors, and not on the program .
Reactive programming vs. functional
All as PR, PF expresses the program in the form of mathematical relations, and not as a sequence of states. In declarative language, everything is described exclusively by expressions, this is a matter of PR. When everything is described in terms of procedures and functions, and the result of each function depends solely on its arguments (and in the body of which they do not refer to any more global variable), then this is functional programming.
The function program acts procedurally on objects, but does it differently to avoid edge effects.
And against functional reactive programming
This is a different paradigm. This is the addition of an event-oriented model to the functional language, which was implemented, for example, in FrTime, developed on the basis of Scheme. Unlike pure functional programming, some objects or variables are changeable, but their state does not depend on the assignments in the body of the program, which will return us to imperative programming, depends on events .
Reactive programming vs. events
PR is actually pretty close to the workings of events that fit into a procedural language like JavaScript. But it differs in that it allows you to write more concise and clear code.
If you can write var A = B + C, It's easier, how to associate an event with A, which itself depends on events, related to B and C. You can associate an event with A, which depends on the result of the sum of the values of B and C and the events, changing the value of B and C. But when one of these events is enabled, it does not activate the sum of their values. To do this, it is necessary that events call a function that calculates this sum, and the function triggers another event when a result is received, which is intercepted by A.
PR can be expressed in PE in the same way as it can be in PI, since in any case it is reduced to machine code, which has an imperative form, but its advantage is that the complexity of the code is passed to the compiler and runtime.
Reactive programming and competition
This kind of programming in practical applications (rather than theory) is based on competition, as it will be used to represent a system in which many players can act simultaneously, which is quite appropriate.
Reactive programming in languages
PR is not implemented directly in any popular language, even in the latter. She is not in "Go," nor in "Rust," nor in "Dart." Only Prologue uses something close to its logical programming.
But they are trying to add it as an extension to procedural languages.
In Java, event handlers are assigned to properties, and the same can be done in JavaScript. Events can be linked as PR definitions and produce indirect results.
But with the simplicity of RP code, these processes and the interweaving of JavaScript callbacks cannot be compared .
For JavaScript. React.js is mainly designed to build a graphical interface. He uses events and bears little resemblance to PR. The article "True Reactive Programming in JavaScript" on this site explains how to easily add PR to JavaScript.
Sodium is a library that calls itself a PR extension for Java and C++.
Reactive Extension is a C # module for event-based programming.
None of these languages offer definitions specific to PR syntax, they offer false similarity, which is rather event programming, since procedural code is required to propagate responsiveness throughout the program.
How to implement it
The fact that you get simplicity in the code for the programmer, he is paid with difficulty for implementing the compiler. No wonder procedural languages were imposed in comparison with alternative ones: procedural code is simply translated into several lines of machine code. It's different for RP.
Each variable must be assigned a list of variables whose value directly depends on that variable to reflect changes in values. This value change is no longer a simple assignment, somehow putting a value in a memory field is starting a process that looks for dependencies and recalculates formulas that include the changed variable.
You can optimize your code by considering dependencies only when you use them, so changing b or c only considers whether a is used.
This is achieved in two ways. Either a supervisor is added that reacts to each change in the object and passes the result to dependent objects, or code is added to the object code that sends a signal when the object changes - additional instructions to the method when changing object properties by methods. This signal is a message to objects dependent on it.
In both cases, the system has a filter that allows you to start propagation only when using dependent objects.
By compiling a reactive language into JavaScript code and not targeting performance, one can simplify using events in the backend, with code that generates PR definitions in functions and associates these functions with each event as described above (PR vs PE).
In conclusion, reactive programming is a way to make the work of programmers much easier. It must be implemented in each new language using the syntax code required for operations requiring performance.
Denis Suro January 23, 2014.