Post on 29-Nov-2014
description
Javascript FunctionalProgramming
Programmazione procedurale
modificazione dello stato del programma (valori mutabili)
sequenzialità dei comandi
utilizza controlli condizionali e iterativi (if e for)
Programmazione procedurale
var newList= []; for (var cnt = 0; cnt <= 10; cnt++) {
if (cnt < 6) newList.push(cnt) }
Programmazione Funzionale
assenza di stati(valori immutabili, funzioni pure, niente variabili)
Funzioni come dato (passabili come argomenti o generate da altre funzioni HOF)
utilizzo di ricorsione, pattern matching e composizione di funzioni
Programmazione Funzionalefunction fib(n){ return n<2?n:fib(n-1)+fib(n-2);}
http://en.literateprograms.org/Fibonacci_numbers_(JavaScript)
Programmazione Funzionale
var select = function(el) { return el < 6
};
filter(select, range(1,10));
First Class Functions
Funzioni manipolabili come dati
First Class Functions
Passabili come parametri
$("div.players").each(function() {console.log($(this).attr('id'));
});
First Class Functions
Possono generare altre funzioni
var sum = function (a) { return function(b) {
return a+b; }; };
sum(1)(2); // -> 3
High Order Functions
Le HOF nella programmazione funzionale, sono funzioni che possono manipolare altre funzioni, accettarle come parametri, crearle, o trasformarle in altre funzioni
High Order Functionsvar generateAccumulator=function(start) { var acc = start;
return function(n) {acc=acc+n;console.log(acc);return acc;
}};
fnAcc=generateAccumulator(10);fnAcc(1);fnAcc(2);fnAcc(3);
otteniamo 11,13 e 16
Closure
Because Common Lisp is lexically scoped, when we define a function containingfree variables, the system must save copies of the bindings of those variables atthe time the function was defined. Such a combination of a function and a setof variable bindings is called a closure. Closures turn out to be useful in a widevariety of applications.(Paul Graham, On Lisp, cap 2.6)
Closurevar generateAccumulator=function(start) { var acc = start;
return function(n) {acc=acc+n;console.log(acc);return acc;
}};
Definizione della closure
Variabile locale visibile nello scopo delle funzioni figlie della HOF
Funzione ritornata dalla HOF
High Order FunctionEsempi
Esempi di HOF estrapolate dalla libreria
functional.js di Oliver Steele
http://osteele.com/sources/javascript/functional/
High Order FunctionMap
trasforma una lista in un’altra lista (fa un mapping)
var lst=[1,2,3,4,5,6,7,8,9,10];
var ret=map(function(el) { return el + 100; },lst);
High Order FunctionFilter
applica un filtro a una lista e ne ritorna una filtrata
var lst=[1,2,3,4,5,6,7,8,9,10];
var ret=filter(function(el) { return el < 6; },lst);
High Order FunctionReduce
accetta tre parametri (una funzione di trasformazione, un valore o oggetto iniziale e la lista), applica una riduzione della lista
var lst=[1,2,3,4,5,6,7,8,9,10];
var ret=reduce(function(x,y) { return x+y; },0,lst);
// -> 55
High Order FunctionReduce
accetta tre parametri (una funzione di trasformazione, un valore o oggetto iniziale e la lista), applica una riduzione della lista
var lst=[1,2,3,4,5,6,7,8,9,10];
var ret=reduce(function(x,y) { return x+y; },0,lst);
// -> 55
Function composition
S’intende la combinazione di funzioni semplici all’interno di una funzione più complessa.
Questo composizione, permette di creare una funzione che è il risultato di una concatenazione di funzioni.
Unica condizione è che queste funzioni accettino come parametro di input e di return un unico parametro.
Function composition
var sum1 = function(x) { return x + 1;};var sum2 = function(x) { return x + 2;};var sum3 = function(x) { return x + 3;};
var fnSum = sequence(sum1,sum2,sum3);
fnSum(10); //-> 16// equivale a sum3(sum2(sum1(10)))
Function compositioncon HOF
var genSum = function(n) { return function (x) { return x+ n };}var sum1 = genSum(1);var sum2 = genSum(2);var sum3 = genSum(3);
var fnSum = sequence(sum1,sum2,sum3);
fnSum(10); //-> 16
Currying
Per Currying si intende la trasformazione di una una funzione che accetta più parametri in una funzione che
restituisce una catena di funzioni, fino all’esaurirsi della lista di parametri.
Dopo di che viene eseguito il corpo vero è proprio della funzione.
Curryingvar sum=function(a,b,c,d) {
return a+b+c+d;
};
var sum3=sum.curry(1,2);
//sum3 è un parziale della funzione sum con i primi 2 parametri a,b già valorizzati con
1 e 2.
//sum3 diventa una funzione che accetta 2 parametri c e d.
sum3(3,4);
-> ritorna 10
var sum6=sum3.curry(3);
//sum6 è a sua volta una parzializzaione di sum3 che accetta un unico parametro d a cui
viene aggiunto il valore 6.
sum6(4);
-> ritorna 10
Partial
E' lo stesso identico meccanisco del currying, solo che non si rispetta un ordine sequenziale di definizione dei
parametri, ma un ordine casuale
Partialvar sum5=sum.partial(1,_,_,4);
sum5(2,3);
-> ritorna 10
oppure
var sum8=sum.partial(1,_,3,4);
sum8(2);
-> ritorna 10;
Approfondimenti
On Lisp di Paul Graham
Librerie per functional programming
underscore.jsasync.jsbacon.js (Functional reactive Programming)