Il vantaggio è che le funzioni pure rendono più facile ragionare sul codice. O, in altre parole, gli effetti collaterali aumentano la complessità del codice.
Prendi un esempio di computeProductPricemetodo.
Un metodo puro ti richiederebbe una quantità di prodotto, una valuta, ecc. Sai che ogni volta che il metodo viene chiamato con gli stessi argomenti, produrrà sempre lo stesso risultato.
- Puoi persino memorizzarlo nella cache e utilizzare la versione cache.
- Puoi renderlo pigro e rimandare la sua chiamata a quando ne hai effettivamente bisogno, sapendo che il valore non cambierà nel frattempo.
- Puoi chiamare il metodo più volte, sapendo che non avrà effetti collaterali.
- Puoi ragionare sul metodo stesso in un isolamento dal mondo, sapendo che tutto ciò di cui ha bisogno sono gli argomenti.
Un metodo non puro sarà più complesso da utilizzare ed eseguire il debug. Dal momento che dipende dallo stato delle variabili oltre agli argomenti e eventualmente dalla loro modifica, significa che potrebbe produrre risultati diversi quando viene chiamato più volte o non avere lo stesso comportamento quando non viene chiamato affatto o chiamato troppo presto o troppo tardi.
Esempio
Immagina che ci sia un metodo nel framework che analizza un numero:
decimal math.parse(string t)
Non ha trasparenza referenziale, perché dipende da:
La variabile di ambiente che specifica il sistema di numerazione, ovvero Base 10 o qualcos'altro.
La variabile all'interno della mathlibreria che specifica la precisione dei numeri da analizzare. Quindi, con il valore di 1, l'analisi della stringa "12.3456"darà 12.3.
La cultura, che definisce la formattazione prevista. Ad esempio, con fr-FR, l'analisi "12.345"fornirà 12345, perché il carattere di separazione dovrebbe essere ,, non.
Immagina quanto sarebbe facile o difficile lavorare con tale metodo. Con lo stesso input, puoi ottenere risultati radicalmente diversi a seconda del momento in cui chiami il metodo, perché qualcosa, da qualche parte, ha cambiato la variabile d'ambiente o ha cambiato la cultura o impostato una precisione diversa. Il carattere non deterministico del metodo porterebbe a più bug e a un incubo di debug più intenso. Chiamare math.parse("12345")e ottenere 5349come risposta poiché un codice parallelo analizzava i numeri ottali non è carino.
Come risolvere questo metodo ovviamente rotto? Introducendo la trasparenza referenziale. In altre parole, eliminando lo stato globale e spostando tutto sui parametri del metodo:
decimal math.parse(string t, base=10, precision=20, culture=cultures.en_us)
Ora che il metodo è puro, sai che non importa quando lo chiami, produrrà sempre lo stesso risultato per gli stessi argomenti.