Top Banner
CYCLE.JS A Functional reactive UI framework Nikos Kalogridis @nikoskalogridis
40

Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

Jan 22, 2018

Download

Technology

GreeceJS
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

CYCLE.JSA Functional reactive UI framework

Nikos Kalogridis@nikoskalogridis

Page 2: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

WHY ANOTHER FRAMEWORK?Programming is hard!Complexity of Web apps is growing exponentiallyAsynchronous programming complicates thingseven more

Page 3: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

CYCLE.JS

ANDRÉ MEDEIROS (AKA. ANDRÉ STALTZ)

Page 4: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

CYCLE.JS FEATURESFunctionalReactiveUnidirectonal flow of dataVirtual DOMA Cycle.js program is a pure function - no sideeffects

Page 5: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

CYCLE.JS HISTORYNov-2014 - Initial commit on github based on RxJsNov-2015 - A fork of the project was made basedmost.jsJun-2016 - Merged back this time supportingxstream, Rxjs v4, Rxjs v5 and most.jsTC39 Observable proposalFeb-2017 - Dropped stream adapters and now usesObservable to convert between streams. Alsodropped support for Rxjs v4

Page 6: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

FUNCTIONAL PROGRAMMINGDeclarative instead of imperativePure functionsImmutability

Page 7: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

MAP

Returns a new array with the result of applying afunction on each element of the array

var myArray = [1, 2, 3, 4, 5];

myArray.map(function (value) { return value + 1; });

// -> [2, 3, 4, 5, 6]

Page 8: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

FILTER

Returns a new array with all elements that pass thetest implemented by the provided function

var myArray = [1, 2, 3, 4, 5];

myArray.filter(function (value) { return value < 4; });

// -> [1, 2, 3]

Page 9: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

REDUCE

Reduces the elements to a single value applying afunction to each of them

var myArray = [1, 2, 3, 4, 5];

myArray.reduce(function (acc, value) { return acc + value; }, 0);

// -> 15

Page 10: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

IMPERATIVE VS DECLARATIVEGiven an array of numbers return the numbers that

are less than 4 and add to each of those 10var myArray = [1, 2, 3, 4, 5]; var result = []; var i = 0;

for (i; i < myArray.length; i += 1) { if (myArray[i] < 4) { result.push(myArray[i] + 10); } }

var myArray = [1, 2, 3, 4, 5]; var result = myArray .filter((value) => value < 4) .map((value) => value + 10);

Page 11: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

HIGHER ORDER FUNCTIONa function that takes a function as a parameteror returns a functionor both

Page 12: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

HIGHER ORDER FUNCTIONEXAMPLES

function add(amount) { return function (value) { return value + amount; } }

function lessThan(amount) { return function (value) { return value < amount; } }

var result = myArray.filter(lessThan(4)).map(add(10));

Page 13: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

PURE FUNCTIONits return value is affected only by its passedparametersand has no side effects

Page 14: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

PURE VS IMPUREvar a = 10;

function impure(x) { return x + a;}

function pure(x, y) { return x + y;}

Page 15: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

SIDE EFFECTSvar a = 0;

function impure(x) { a = x + a; }

function impure(x) { console.log(x); return x + 1; }

Page 16: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

ASYNCHRONOUSPROGRAMMING IN JAVASCRIPT

CallbacksPromisesGenerators / yieldAsync / awaitObservables

Page 17: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

CALLBACKSvar counter = 0;

function callback() { counter += 1;}

document .getElementById('myButton') .addEventListener('click', callback);

var xhr = new XMLHttpRequest(); xhr.open('GET', '/server', true);

xhr.onload = function () { // Request finished. Do processing here. };

Page 18: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

PROMISESvar requestPromise = fetch({url: 'http://www.google.com'});

requestPromise .then(function (response) { // do something with the response }) .catch(function (error) { // handle the error });

Page 19: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

GENERATORS / YIELDfunction* foo () { var index = 0; while (index < 2) { yield index++; } } var bar = foo();

console.log(bar.next()); // { value: 0, done: false } console.log(bar.next()); // { value: 1, done: false } console.log(bar.next()); // { value: undefined, done: true }

Page 20: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

ASYNC / AWAITasync function save(Something) { try { await Something.save(); } catch (ex) { //error handling } console.log('success');}

Page 21: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

OBSERVABLE// data$ is an Observable object var subscription = data$.subscribe( { next: function (value) { // handle next value }, error: function (error) { // handle error }, complete: function () { // finished so do cleanup... } } );

Page 22: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

REACTIVE PROGRAMMINGis programming with data streams (synchronous orasynchronous)on top of that you are given an amazing toolbox offunctions to combine, create, filter any of thosestreams

Page 23: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

REACTIVE LIBRARIES INJAVASCRIPT

Bacon.jsRxjskefir.jsmost.jsxstream

Page 24: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

RXJS EXAMPLEimport Rx from 'rxjs/Rx';

let counter = 0;

const increaseButton = document.querySelector('#increase'); const increaseClick$ = Rx.Observable.fromEvent(increaseButton, 'click');

increaseClick$.subscribe({ next: function () { // click received counter += 1; console.log(counter); } });

Page 25: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

RXJS EXAMPLE REVISEDimport Rx from 'rxjs/Rx'; const increaseButton = document.querySelector('#increase'); const increaseClick$ = Rx.Observable.fromEvent(increaseButton, 'click'); const counter$ = increaseClick$ .mapTo(1) // always maps to a constant value .scan((acc, value) => acc + value, 0); // hint: reduce

counter$.subscribe({ next: function (counter) { // new count event received console.log(counter); } });

Page 26: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

OTHER TYPES OF STREAMSRx.Observable.from([1, 2, 3, 4, 5]) .filter((x) => x < 4) .map((x) => x + 10) .subscribe({ next: (value) => console.log(value), complete: () => console.log('done') });

// ->// 11// 12// 13// done

Page 27: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

PROMISE AS A STREAMconst myPromise = new Promise((resolve) => resolve('hello')); Rx.Observable.from(myPromise) .subscribe({ next: (value) => console.log(value), complete: () => console.log('done') });

// ->// hello // done

Page 28: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

COMBINING STREAMSconst data1$ = Rx.Observable.from([1, 2, 3]);const data2$ = Rx.Observable.from([6, 7, 8]);Rx.merge(data1$, data2$) .subscribe({ next: (value) => console.log(value) });// ->// 1 // 6 // 2 // 7 // 3 // 8

Page 29: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

MERGE OPERATOR

Page 30: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

CYCLE.JS MODEL

Human

Senses Actuators

InputOutput

Computer

Page 31: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

A CYCLE.JS PROGRAM IS APURE FUNCTION

function cycleProgram(sources) { return sinks;}

Page 32: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

function main(sources) { const model$ = sources .DOM.select('.increase').events('click') .mapTo(1).fold((acc, value) => acc + value, 0);

const vtree$ = model$.map((value) => div([ button('.increase', 'Increase'), span(value) ]) );

return {DOM: vtree$}; }

Cycle.run(main, { DOM: makeDOMDriver('#app') });

Page 33: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

NO SIDE EFFECTS

SourcesSinks

main()

DOM side effects

HTTP side effects

Other side effects

pure dataflow

Page 34: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

IN CYCLE.JS

Page 35: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

DEMO

Page 36: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

PROSTruly reactive programming styleDeclarative UI designFast - thanks to Snabdom and xstreamFractal state management

Page 37: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

CONSBrain rewiring for using functional reactive styleRelatively small community compared to React orAngularSteep learning curve especially on stream librariesLacks a complete UI component library (as of today)

Page 38: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

USEFUL LINKShttps://cycle.js.org/http://widdersh.in/tricycle/https://github.com/cyclejs-communityhttps://gitter.im/cyclejs/cyclejshttps://github.com/staltz/cycle-onionifyhttps://github.com/cyclejs-community/cyclic-routerhttp://staltz.com

Page 39: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

QUESTIONS

Page 40: Cycle.js - Functional reactive UI framework (Nikos Kalogridis)

THANK YOU