Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Funzioni pure e non pure

Comprendere le differenza tre le funzioni pure e quelle non pure, concetti di base fondamentali per la programmazione funzionale in JavaScript.
Comprendere le differenza tre le funzioni pure e quelle non pure, concetti di base fondamentali per la programmazione funzionale in JavaScript.
Link copiato negli appunti

Abbiamo visto nella parte introduttiva di questa guida come le funzioni matematiche giochino un ruolo fondamentale nella programmazione funzionale. Abbiamo anche sottolineato la differenza tra le funzioni matematiche e le funzioni JavaScript o, più in generale, dei linguaggi di programmazione imperativa. In breve, mentre le funzioni matematiche restituiscono sempre lo stesso risultato a parità di input, le funzioni non matematiche potrebbero restituire risultati diversi a parità di dati in input. Proviamo a spiegarci meglio con un esempio.

Consideriamo il seguente codice JavaScript:

var value = 0;
function add(n) {
    value = value + n;
    return value;
}

Invochiamo la funzione add() una prima volta con il valore 1 come parametro, ed otterremo il valore 1:

add(1); //result: 1

Se la invochiamo una seconda volta con lo stesso valore di input, otterremo il valore 2 come output:

add(1); //result: 2

Questo ci rende difficile ragionare formalmente sulla funzione add(), dal momento che il suo output non dipende unicamente dall'input, ma anche dal valore corrente della variabile value. Questa variabile rappresenta l'ambiente in cui la funzione viene eseguita, e tale ambiente viene modificato dalla funzione stessa. In pratica, il risultato dell'applicazione della funzione sul valore in input non è soltanto il valore numerico esplicitamente restituito, ma anche l'effetto che tale applicazione ha sulla variabile value, cioè su un ambiente non esplicito che però determina il risultato fornito come output.

La modifica di questo ambiente viene generalmente indicata come un effetto collaterale (side effect), cioè un effetto non esplicito che potrebbe influire non soltanto sulla funzione corrente, ma anche su altre funzioni che condividono lo stesso ambiente. L'insieme dei dati modificabili condiviso tra più funzioni o tra più oggetti è comunemente chiamato stato ed è il principale responsabile della difficoltà nel gestire la complessità delle applicazioni software. La gestione di dati condivisi rende complessa un'applicazione non tanto per la condivisione in sè, ma per il fatto che questi dati possono variare in seguito all'interazione di diversi oggetti e/o funzioni e rende impredicibile il risultato atteso. Ad esempio, è difficile poter definire dei test automatici che ci garantiscano la correttezza di una funzione che ha degli effetti collaterali. La presenza di effetti collaterali rende tra l'altro complessa l'attività di refactoring, dal momento che non possiamo concentrarci soltanto sulle finalità della funzione, ma dobbiamo tener conto anche degli effetti sull'ambiente esterno.

Funzioni pure e non pure

Nell'ambito della programmazione funzionale si fa una chiara distinzione tra funzioni pure e funzioni non pure. Le prime sono quelle funzioni che hanno un comportamento matematico, cioè sono quelle funzioni che dato un determinato input restituiscono sempre lo stesso output e non hanno effetti collaterali. Le seconde sono le funzioni che invece producono effetti collaterali, come la funzione add() vista prima.

Quindi, per adottare un approccio funzionale nella scrittura del nostro codice JavaScript dobbiamo fare in modo che le nostre funzioni siano deterministiche come le funzioni matematiche e fare attenzione ad evitare effetti collaterali durante la sua esecuzione.

Come conseguenza della definizione di funzione matematica possiamo affermare che:

Una funzione senza parametri non è pura o non ha senso

Consideriamo infatti una funzione come la seguente:

function getDate() {
    return new Date();
}

Dal momento che una funzione è una relazione tra dati di due insiemi, una funzione che non prevede nessun parametro non sta mettendo in relazione nulla. Inoltre, se la funzione restituisce dei valori diversi ad ogni chiamata, è segno che sta facendo riferimento ad un contesto esterno. È questo il caso del nostro esempio: la funzione non prende nessun valore in input e restituisce valori diversi ad ogni invocazione. I valori restituiti dipendono effettivamente dal sistema su cui è eseguita la funzione, quindi essa non è assolutamente una funzione pura.

Una funzione senza un output non è pura

Anche in questo caso, una funzione che prende dei valori in input e non restituisce un output non sta mettendo in relazione gli elementi di due insiemi, e molto probabilmente sta soltanto generando effetti collaterali, come può essere ad esempio la seguente funzione:

var value = 0;
function add(n) {
    value = value + n;
}

In questo caso la funzione non restituisce esplicitamente un valore, ma sta modificando il valore di una variabile globale e pertanto non è pura.

Ti consigliamo anche