Functional Reactive Programming

for front-end developers

WTF is FRP?

Functional

  • First-class functions
  • Higher-order functions
  • Lexical closures
  • Referential transparency
  • Immutable data
  • Pattern matching
  • Lazy evaluation
  • Efficient recursion (TCO)
  • Homoiconicity

Reactive

In the Reactive pattern, module X defines which other modules affect X.

Gerard Berry, Real time programming, 1989

Functional

Reactive

var R = require('ramda');

// First-class functions
var addFunctional = function(arr) {
    // Lexical closures
    return R.concat(arr, ' Functional');
};

var addReactive = function(arr) {
    return R.concat(arr, ' Reactive');
};

// Higher-order functions
var addFunctionalReactive =
    R.compose(
        addFunctional,
        addReactive
    );

// Referential transparency
var memoizedFR =
    R.memoize(addFunctionalReactive);

var prf = memoizedFR('Programming')
    .split(' ');
var frp = prf.reverse();

// Immutable data
if(prf !== frp) {
    console.log(frp.join(' '));
}

// Lazy evaluation - lazy.js, lodash 3
// Efficient recursion (TCO) - ES6
//     (real one)
// Homoiconicity - not available in JS
var Rx = require('rx');
var Observable = Rx.Observable;
var Subject = Rx.Subject;

var number1 = new Subject();
var number2 = new Subject();

// sum is affected
// by number 1 and number 2
var sum = Observable
    .combineLatest(
        number1,
        number2,
        function(number1, number2) {
            return (number1 + number2);
        }
    );

number1.onNext(1);
number2.onNext(2);
number2.onNext(3);
number1.onNext(4);

// sum:
// 3
// 4
// 7

Imperative

Reactive

vs

Operators

So what?

var Cycle = require('cyclejs');
var h = Cycle.h;

var Model = Cycle.createModel(Intent =>
  ({name$: Intent.get('changeName$').startWith('')})
});

var View = Cycle.createView(Model =>
  ({
    vtree$: Model.get('name$').map(name =>
      h('div', [
        h('label', 'Name:'),
        h('input.field', {attributes: {type: 'text'}}),
        h('h1.header', 'Hello ' + name)
      ])
    )
  })
);

var User = Cycle.createDOMUser('.js-container');

var Intent = Cycle.createIntent(User =>
  ({changeName$: User.event$('.field', 'input').map(ev => ev.target.value)})
);

User.inject(View).inject(Model).inject(Intent).inject(User);

Text

https://github.com/erykpiast/online-css-autoprefixer

Cycle.js, Autoprefixer, Web Components, ES6, Gulp

Further reading

it's over

 

Thank you!

 Eryk Napierała

@UsabilityTools.com

Likes this kind of stuff?
Let's work together!

Functional Reactive Programming for front-end developers

By Eryk Napierała

Functional Reactive Programming for front-end developers

  • 3,827