Real reactive programming in JavaScript

Without a framework, you can program by formulas, like using a spreadsheet, thanks to JavaScript dynamism.

Reactive programming is the third level in high-level programming: The first level was achieved with the advent of languages ​ ​ such as Fortran and Basic, and then in 1967 Simula took us to the second level with objects now implemented in all languages. Perhaps it's time to take it to the next level.

Because PR is closer to how to think about a person than imperative programming (a type of cooking recipe), and I'm not talking about functional programming!
Example. If I wanted to estimate the distance that can be covered with different car models, I would write:

distance = tank capacity/flow * 100

Then all I have to do is introduce tank capacity and consumption of different car models and I would always have their autonomy. No additional lines of code are needed, as in the spreadsheet, the first PR application.

PR is especially suitable for programming a robot, simulating or giving the game intelligence. The results, as well as the above distance, can be displayed through the interface or be commands for a real device or virtual object.

There are several frameworks that claim to add reactive programming to JavaScript, but from the tests I ran, it is not obvious that they can recalculate the formula assigned to the variable. They just spread events, so it's more of a so-called event programming. The scenario below allows the program to work as a spreadsheet, all formulas are recalculated when the parameter changes. That's why I added "truth" alongside "reactive programming" in the headline.

Having developed the same PHP script after the JavaScript version, I appreciated how it was so easy to implement this paradigm in JS thanks to the dynamism of the language.
In JavaScript, I implement it with an object that is held in 20 lines of code...

var Reactol = (function() {
Reactol.prototype.add = function(x) {
this.depend.push(x)
}
Reactol.prototype.change = function(x) {
if(x != undefined) this.value = x for(var i in this.depend) {
var d = this.depend[i]
d.action()
d.change() d.output()
}
}
function Reactol() {
this.depend=[]
this.value=0
}
return Reactol;
})();

As we can see, I use closure to add a constructor to the Reactol object.

The dependent table contains a list of objects that depend on the current object. The add method allows you to add a dependency.

If you want to change the value of an object, it is called a method, which in turn calls the action, change, and output methods of each object that depends on it .

Declaring an active variable

The reactive variable is represented by the Reactol object, so the object instance is declared first:

var v1 = new Reactol()

The formula to be assigned to this variable is then determined:

v1['action'] = function() { this.value = 10  }

If necessary, a method for displaying the contents of the variable will be added. It can also be a command for a mechanism .

v1['output'] = function() { document.getElementById("sum").value = this.value }

Now we create a dependency, define another variable v2, which depends on the variable v1.

var v2 = new Reactol()
v2['action'] = function() { this.value = v1.value + 1000 }
v1.add(v2) 

To add v2 to the list of dependent variables, call the add v1 method. In the future, each change to v1 will automatically update v2.

Nothing more is needed to make our variables reactive!

Example on HTML page

We have two variables v1 and v2 that are associated with text fields on the HTML page.

We want to define a new variable sum, whose value is equal to the sum of v1 and v2, which will also be displayed in the text field. Thus, each time the user changes the value of v1 or v2, sum will be updated automatically.

Here is the JavaScript and HTML code:

var Reactol = (function() {
Reactol.prototype.add = function(x) {
this.depend.push(x)
}
Reactol.prototype.change = function(x) { if(x != undefined) this.value = x
for(var i in this.depend) {
var d = this.depend[i]
d.action()
d.change()
d.output()
}
}
function Reactol() {
this.depend=[]
this.value=0
}
return Reactol
})();
var v1 = new Reactol()
var v2 = new Reactol()

var sum = new Reactol()
sum["action"] = function() { this.value = parseInt(v1.value) + parseInt(v2.value) }
sum["output"] = function() { document.getElementById("sum").value = this.value } v1.add(sum)
v2.add(sum)
<p>Value 1 : <input type="text" name="v1" onKeyUp="v1.change(this.value)"> </p>
<p>Value 2 : <input type="text" name="v2" onKeyUp="v2.change(this.value)"> </p>
<p>Sum : <input type="text" name="sum" id="sum"> </p>

This simplified example is only used to show the operation of the Reactol object. The same effect could be obtained without this item, of course, but if there were fifty widgets dependent on each other, it would be more difficult to cope with this, in which case reactive programming takes all the interest.

Display

Value 1:

Value 2:

Amount:

Download the full example. The script is licensed by MIT. Use it freely, but do not present it on a web page without attributing it to the author.

Reactive programming is implemented in the Script JavaScript compiler (done by myself) using the object described here. It is enough to state the formulas, the compiler is responsible for the automatic declaration of dependencies .

Denis Suro, September 18, 2014.