La Programmazione Funzionale con le Funzioni Pure
Le Funzioni Pure sono uno dei pilastri fondamentali della programmazione funzionale. La definizione vera è qualcosa di astruso e non la scriverò perchè la capirebbero in pochi; invece in parole povere è addirittura un concetto semplice.
Una funzione si dice pura quando il suo output dipende esclusivamente dal suo input.
Sembra una cretinata, ma il 99% del codice scritto ogni giorno nel mondo non rispetta questa regola.
Vediamo un esempio di funzione impura e di funzione pura:
var etaMinima = 30;
//impura
function checkEta(var eta) {
return eta >= etaMinima;
}
//pura
function checkEta(var eta) {
var etaMinima = 30;
return eta >= etaMinima;
}
Riuscite a vedere il problema? la prima checkEta dipende da una variabile esterna, che può cambiare in qualunque momento e dunque può influenzare il modo in cui viene eseguito e valutato il codice.
Avete presente la parola chiave this ? Se la usate, o l'avete usata, il vostro codice è impuro. E' possibile trasformare parecchio in codice puro molte funzioni impure, ma per farlo dovrete dimenticare (per un po') il mondo object oriented.
Vediamo alcuni effetti collaterali (in matematica diremmo corollari) delle _pure function_s:
- una pure function non modifica l'input in ingresso.
- una pure function può essere riapplicata più volte sullo stesso input e si otterrà sempre lo stesso output. Questa proprietà viene solitamente detta idempotenza.
- Una Pure Function può chiamare altre Pure Function. (In object-oriented li chiameremmo metodi statici, ma non tutti, solo quelli che non dipendono da nessun'altro).
- Possiamo sfruttare l'ultima proprietà per cacheare il risultato delle pure function tramite una tecnica che si chiama memoization:
var memoize = function(f) {
var cache = {};
return function() {
var arg_str = JSON.stringify(arguments);
cache[arg_str] = cache[arg_str] || f.apply(f, arguments);
return cache[arg_str];
};
};
e se abbiamo una chiamata Http che è anch'essa idempotente potremmo cachearla con questa tecnica:
var pureHttpCall = memoize(function(url, params){
return function() {
return $.getJSON(url, params);
}
});
Dalla seconda volta in cui verrà chiamata pureHttpCall
, il risultato non sarà preso dalla rete ma dalla cache. Ingegnoso, no?
Se volete altri approfondimenti sul paradigma funzionale leggete questo libro free: Mostly Adequate Guide to Functional Programming. Alcuni spunti (ed esempi) li ho presi dal capitolo 3. Buona lettura!