Functional Reactive Javascript

Aliaksei Bahachuk 

Reactivity is modern, but What is it?

Reactive System

Reactive Programming

Programming paradigm oriented around data flows and the propagation of change (wiki)

Excel

be reactive

a := 1;
b := 2;

c := a + b; //c === 3

a := 3; //c === 5

Values that vary over time aka Observable Streams

Principles of FRP

  • Functional programming

  • Clear State

  • Behaviour/signal/cell/stream

  • Event/Property

  • Switching

Streams are everywhere

Streams are everywhere

Streams are everywhere

Java

JavaScript

.Net

Ruby

Swift

C++

Clojure

Scala

Let's create a bicycle

Let's create a bicycle!

Let's create a bicycle!

let ReactiveDeps = {
  funcs: new Map(),
  vars: new Map(),
  activeID: null
};

Let's create a bicycle!

function Merge(fn, args) {
  ...
  function obsFunc() {
    ReactiveDeps.activeID = _id;
    let res = fn.apply(this, args);
    ReactiveDeps.activeID = null;
    return res;
  };
  ...
}

Let's create a bicycle!

function Merge(fn, args) {
  ...
  stream = new Stream(obsFunc())

  ReactiveDeps.funcs.set(_id, function() {
    stream.set(obsFunc());
  });

  return stream;
}

Let's create a bicycle!

let Stream = class {
  ...
  get() {
    let activeID = ReactiveDeps.activeID
    
    if (activeID) {
      ReactiveDeps.vars.get(activeID).push(this);
    }

    return this._value;
  }
  ...
}

Let's create a bicycle!

let Stream = class {
  ...
  set(val) {
    this._value = val;

    for (let entry of ReactiveDeps.vars) {
      if (entry[1].indexOf(this) > -1) {
        ReactiveDeps.funcs.get(entry[0])();
      }
    }

    if (this._onChange) {
      this._onChange(this._value);
    }
  }
  ...
}

Let's create a bicycle!

let Stream = class {
  constructor(val) {
    this._value = val;
    this._onChange = null;
  }

  ...
  subscribe(event, fn) {
    if (event === 'change') {
      this._onChange = fn;
    }
  }
}

Let's create a bicycle!

let a = new Stream(1);
let b = new Stream(2);

let c = Merge(function(a, b) {
  return a.get() + b.get();
}, [a, b]);

c.subscribe('change', function(val) {
  document.querySelector('#summ').innerHTML = val;
});

setInterval(function() {
  a.set(a.get() + 1);
}, 1000);

Let's create a bicycle!

Bicycle is ready!

Let's improve our bicycle!

Stream Improvements: State and Status

  • isDisposed

  • isCompleted 

  • isStopped

  • hasError

  • hasWarnings

  • ...

Stream Improvements: Dependencies

Stream Improvements: Operators

  • Map

  • Filter

  • Scan

  • CombineLatest

  • StartWith

  • ...

Result of Improvements

Result of Improvements

Bicycle is ready!

Problems(

Complexity

Integration with imperative part of code

Cascade Updating

Cascade Updating

Cascade Updating/Exceptions

Memory

...FRP is so bad?

Problems FRP solves

  • Data Manipulation

  • Events handling

  • Callback Hell

  • Promise Hell

  • Comet/Async Manipulation

  • Race Conditions

  • Complex State

  • Tests 

Deep Dive

  • FRP

  • RxJS, Bacon, Kefir and others

  • MeteorJS

Questions?

FRP

By Aliaksei Bahachuk

FRP

An overview of FRP

  • 1,116