Introduction to functional reactive programming
with RxJS
23.03.2017 - Graffiti HUB
Chi sono
Giulio Collesei
Front end dev @AQuest
Motivazioni
Introduction to functional reactive programming
with RxJS
Functional programming
Cosa significa?
Functional programming
Functional programming
Scrivere applicazioni utilizzando funzioni
f Main()
f A()
f B()
f A1()
f A2()
f A3()
f A4()
Functional programming
È tutto?
Functional programming
nope!
Functional programming
Functional programming
-
Functions are first class entities
-
Functions are pure
-
Functions use immutable data
-
Functions guarantee referential transparency
Functional programming
-
Functions are first class entities
Functional programming
-
Functions are first class entities
// Function declaration
function sayHello(name) {
return `Hello, ${name}`
}
// Function expression
const sayHello = name => `Hello, ${name}`
Functional programming
const putInPot = i1 => console.log(`${i1} in pot!`);
const cook = (i1, i2, f) => {
console.log(`Cooking ${i1} and ${i2}`);
f(i1);
f(i2);
};
cook('chicken', 'potatoes', putInPot);
// -> Cooking chicken and potatoes
// -> chicken in pot!
// -> potatoes in pot!
-
Functions are first class entities
Functional programming
const getSecret = (secret) =>
() => console.log(secret);
const mySecret = getSecret('my secret');
mySecret();
// -> my secret
-
Functions are first class entities
Functional programming
-
Functions are pure
Functional programming
-
Functions are pure
- Il risultato della funzione dipende solo dagli input della stessa
- La funzione non altera né ciò che sta fuori né i parametri ad esse passati.
Functional programming
-
Functions are pure
const PI = 3.14;
// Non-pure function
const calculateArea = (radius) =>
radius * radius * PI;
// Pure function
const calculateArea = (radius, PI) =>
radius * radius * PI;
Functional programming
-
Functions use immutable data
Functional programming
-
Functions use immutable data
Nella programmazione funzionale non c'è più il concetto di variabile. I dati non cambiano nel tempo.
Functional programming
-
Functions use immutable data
// Non-immutable data
let myString = 'Hello';
myString = myString.concat(' world!');
// Immutable data
const myString = 'Hello';
const myString2 = myString.concat(' world!');
Functional programming
-
Functions guarantee referential transparency
Functional programming
-
Functions guarantee referential transparency
f(x) = x * x
Functional programming
-
Functions guarantee referential transparency
f(x) = x * x
f(4) = 16
Functional programming
-
Functions guarantee referential transparency
f(x) = x * x
f(4) = 16
f(4) = 16
f(4) = 16
Functional programming
-
Functions guarantee referential transparency
f(x) = x * x
g(x) = f(x) + x
Functional programming
-
Functions guarantee referential transparency
f(x) = x * x
g(x) = f(x) + x
g(4) = f(4) + 4
Functional programming
-
Functions guarantee referential transparency
f(x) = x * x
g(x) = f(x) + x
g(4) = f(4) + 4
g(4) = 16 + 4
Functional programming
-
Functions guarantee referential transparency
La referential transparency ci da la possibilità di cambiare un espressione con il suo risultato senza compromettere il funzionamento dell'applicazione.
Pure function
+ Immutable data
= Referential transparancy
Functional programming
Benefits
Functional programming
- Più facili da capire
- Più facili da riutilizzare
- Più facili da testare
- Più facili da ottimizzare e mantenere
Benefits
Nella programmazione funzionale le funzioni sono:
Functional programming
Imperative
vs
Declarative
Functional programming
const a = [1,2,3,4,5];
// Imperative (how)
let b = 0;
for (let i = 0; i < a.length; i++) {
b = b + a[i];
}
// Declarative (what)
const sum = (b, a) => b + a;
const b = a.reduce(sum, 0);
Functional programming
Patterns
Functional programming
higher-order function
Functional programming
Higher-order function
Funzioni che accettano come parametro altre funzioni e/o restituisco nuove funzioni
Array.prototype
.filter() .map() .reduce() .reduceRight() .find() .every() .concat()
Functional programming
function composition
Functional programming
Composizione di funzioni
È l'applicazione di una funzione al risultato di un'altra
A
B
B
C
C
D
D
Res.
func1()
func2()
func3()
Functional programming
Composizione di funzioni
È l'applicazione di una funzione al risultato di un'altra
f ∘ g (f dopo g)
Functional programming
Composizione di funzioni
È l'applicazione di una funzione al risultato di un'altra
f ∘ g (f dopo g)
(f ∘ g)(x)
Functional programming
Composizione di funzioni
È l'applicazione di una funzione al risultato di un'altra
f ∘ g (f dopo g)
(f ∘ g)(x)
f(g(x)) = y
Functional programming
Composizione di funzioni
È l'applicazione di una funzione al risultato di un'altra
// two functions that we'll compose
const applyTax = x => x * 1.08;
const applyShipping = x => x + 10;
const totalCost = compose(applyShipping, applyTax);
Functional programming
Partial application
Functional programming
Applicazione parziale di funzione
L'applicazione di una funzione a una parte dei suoi argomenti
f(a, b) = c
Functional programming
Applicazione parziale di funzione
L'applicazione di una funzione a una parte dei suoi argomenti
f(a, b) = c
(f1(a))(b)
Functional programming
Applicazione parziale di funzione
L'applicazione di una funzione a una parte dei suoi argomenti
f(a, b) = c
(f1(a))(b) = f(a, b) = c
Functional programming
// Partial application
const f = (a, b, c) => a * b * c;
const g = partialApplication(f, [2, 3]);
// ...
const h = g(4); // 24
enough with functional!
Reactive programming
Cosa significa?
Reactive programming
Reactive programming
È un paradigma di programmazione che mira alla gestione di flussi di dati asincroni (stream) basati su eventi.
Reactive programming
Stream?
Reactive programming
Gli stream sono simili agli array, solo asincroni.
Array
[1, 2, 3]
Stram
[1, ..... 2, ...... 3]
Reactive programming
Una serie di eventi ordinati nel tempo
Reactive programming
Una serie di eventi ordinati nel tempo
Tempo
e
e
e
Reactive programming
A cosa serve RP?
Reactive programming
a = b + c
Reactive programming
Listener
(memory leaks)
Callback
(callback hell)
Promises
(cannot be cancelled)
Reactive programming
Observable
Reactive programming
Come funziona?
Reactive programming
Come manipolare i dati?
Reactive programming
Tempo
// tieni i pari
1
2
3
4
Reactive programming
Tempo
filter() // tieni i pari
1
2
3
4
2
4
// fai il quadrato
Reactive programming
Tempo
filter() // tieni i pari
1
2
3
4
2
4
map() // fai il quadrato
4
16
// riduci con somma
Reactive programming
Tempo
filter() // tieni i pari
1
2
3
4
2
4
map() // fai il quadrato
4
16
reduce() // riduci con somma
4
20
Reactive programming
Merge
Reactive programming
KeyPress
KeyPress
+
Mouse move
merge()
Mouse move
Reactive programming
Reactive programming
Concat
Reactive programming
Reactive programming
Switch
(Higher-order event stream)
Reactive programming
Reactive programming
RxJS
RxJS
RxJS
An API for asynchronous programming
with observable streams
RxJS
http://reactivex.io/languages.html
- Java: RxJava
- JavaScript: RxJS
- C#: Rx.NET
- Scala: RxScala
- C++: RxCpp
- Ruby: Rx.rb
- Python: RxPY
- ......
RxJS
Terminologia
RxJS
Observable
RxJS
Observable
È il wrapper dello stream.
Un Observable ha 3 eventi:
- Next
- Error
- Complete
RxJS
var source = Rx.Observable.range(0, 3);
Observable
RxJS
Observables are lazy-evaluated
RxJS
Observer (Subscriber)
RxJS
Observer
L'oggetto passato al metodo .subscribe() che contiente le 3 callback
RxJS
var source = Rx.Observable.range(0, 3);
source.subscribe({
next: x => console.log(`Next: ${x}`),
error: err => console.error(`Error: ${err}`),
complete: () => console.log(`Done!`)
});
Observable
Observer
RxJS
Operators
RxJS
Operators
Sono le funzioni che ci permettono di manipolare gli observables.
Operators = RxJs
RxJS
Creare un observable
RxJS
// da qualsiasi valore Rx.Observable.of(0, 3, 'fevr', ['a', 'b']);
RxJS
// da qualsiasi valore Rx.Observable.of(0, 3, 'fevr', ['a', 'b']);
// da un array o da una promise Rx.Observable.from([1, 2, 3]);
RxJS
// da qualsiasi valore Rx.Observable.of(0, 3, 'fevr', ['a', 'b']);
// da un array o da una promise Rx.Observable.from([1, 2, 3]);
// da un evento Rx.Observable.fromEvent(myBtn, 'click');
RxJS
// da qualsiasi valore Rx.Observable.of(0, 3, 'fevr', ['a', 'b']);
// da un array o da una promise Rx.Observable.from([1, 2, 3]);
// da un evento Rx.Observable.fromEvent(myBtn, 'click');
// da un intervallo (tipo setTimeout) Rx.Observable.interval(1000);
RxJS
// da un array o da una promise Rx.Observable.from([1, 2, 3]);
// da un evento Rx.Observable.fromEvent(myBtn, 'click');
// da un intervallo (tipo setTimeout) Rx.Observable.interval(1000);
// da un timer (delay, interval) Rx.Observable.timer(100, 1000);
// da qualsiasi valore Rx.Observable.of(0, 3, 'fevr', ['a', 'b']);
RxJS
// da un range Rx.Observable.range(30, 10);
RxJS
// da un range Rx.Observable.range(30, 10);
// da una funzione con bindCallback const fetch = (url, callback) => { //...
callback('data')
}
const rxFetch = Rx.Observable.bindCallback(fetch);
RxJS
// da un range Rx.Observable.range(30, 10);
// da una funzione con bindCallback const fetch = (url, callback) => { //...
callback('data')
}
const rxFetch = Rx.Observable.bindCallback(fetch);
// never Rx.Observable.never();
RxJS
Merge observable
RxJS
const mouseMove$ = Rx.Observable.fromEvent(document, 'mousemove');
const click$ = Rx.Observable.fromEvent(document, 'click');
const uiEvents$ = Rx.Observable.merge(mouseMove$, click$)
.subscribe(e => console.log(e.type));
// click
// mousemove
// mousemove
// mousemove
// click
// mousemove
// mousemove
// mousemove
// mousemove
RxJS
Concat observable
RxJS
const interval100$ = Rx.Observable.interval(100)
.take(5);
const interval2000$ = Rx.Observable.interval(2000);
const intervalConcat$ = Rx.Observable.concat(interval100$, interval2000$)
.subscribe(console.log);
// 0
// 1
// 2
// 3
// 4
// 0
// 1
// 2
// 3
// ...
RxJS
combineLatest
RxJS
const interval100$ = Rx.Observable.interval(100);
const interval2000$ = Rx.Observable.interval(2000);
const intervalConcat$ = Rx.Observable.combineLatest(interval100$, interval2000$)
.subscribe(console.log);
// [19, 0]
// [20, 0]
// [21, 0]
// ...
// [39, 1]
// ...
// [39, 1]
// ...
// [59, 2]
RxJS
Demo!
RxJS
http://codepen.io/giuliocollesei/pen/vxjyjp/
Drag and drop
RxJS
Redux
http://codepen.io/giuliocollesei/pen/ryvjKG
RxJS
Risorse utili
RxJS
Documentazione ufficiale:
http://reactivex.io/rxjs/
Introduzione FRP by André Staltz
https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
Video corsi su egghead.io
https://egghead.io/technologies/rx
RxMarbles (stream interattivi)
http://rxmarbles.com/
RxJS
Fine
Introduction to Functional Reactive Programming with RxJS
By giulico
Introduction to Functional Reactive Programming with RxJS
- 2,080