Michele Nasti

Thoughts on what I learn

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!