Nell'informatica, si dice che una funzione o espressione abbia un effetto collaterale se modifica uno stato o ha un'interazione osservabile con le funzioni di chiamata o il mondo esterno.
Da Wikipedia - Effetto collaterale
Una funzione, in senso matematico, è una mappatura da input a output. L'effetto previsto del richiamo di una funzione è di mappare l'input sull'output che restituisce. Se la funzione fa qualcos'altro, non importa cosa, ma se ha un comportamento che non sta mappando l'input sull'output, quel comportamento è noto per essere un effetto collaterale.
In termini più generali, un effetto collaterale è qualsiasi effetto che non è l'effetto previsto dal progettista del costrutto.
Un effetto è tutto ciò che colpisce un attore. Se chiamo una funzione che invia alla mia fidanzata un messaggio di errore, che riguarda un gruppo di attori, io, lei, la rete della compagnia di telefonia cellulare, ecc. L'unico effetto previsto di chiamare una funzione gratuita con effetti collaterali è per la funzione per restituirmi una mappatura dal mio input. Quindi per:
public void SendBreakupTextMessage() {
Messaging.send("I'm breaking up with you!")
}
Se si intende che questa sia una funzione, l'unica cosa che dovrebbe fare è restituire il vuoto. Se fosse privo di effetti collaterali, non dovrebbe effettivamente inviare il messaggio di testo.
Nella maggior parte dei linguaggi di programmazione, non esiste un costrutto per una funzione matematica. Nessun costrutto deve essere usato come tale. Ecco perché la maggior parte delle lingue afferma che hai metodi o procedure. In base alla progettazione, si intende che questi siano in grado di produrre molti più effetti. Nel linguaggio comune della programmazione, a nessuno interessa davvero l'intento di quale sia stato un metodo o una procedura, quindi quando qualcuno dice che questa funzione ha effetti collaterali, significa effettivamente che questo costrutto non si comporta come una funzione matematica. E quando qualcuno dice che questa funzione è priva di effetti collaterali, significa che questo costrutto si comporta efficacemente come una funzione matematica.
Una funzione pura è sempre priva di effetti collaterali, per definizione. Una funzione pura, è un modo di dire, questa funzione, anche se sta usando un costrutto che consente più effetti, ha come effetto uguale a quello di una funzione matematica.
Sfido chiunque a dirmi quando una funzione senza effetti collaterali non sarebbe pura. A meno che l'effetto primario voluto del contesto della frase usando il termine puro e senza effetti collaterali non sia quello dell'effetto matematico previsto di una funzione, allora questi sono sempre uguali.
Come tale, a volte, anche se più raramente, e credo che questa sia la distinzione che manca e guida erroneamente le persone (in quanto ciò non è il presupposto più comune) nella risposta accettata, ma a volte si presume che l'effetto previsto di una funzione di programmazione sia mappare l'input sull'output, dove l'input non è vincolato ai parametri espliciti della funzione, ma l'output è vincolato al valore di ritorno esplicito. Se supponi che sia l'effetto desiderato, una funzione che legge un file e restituisce un risultato diverso in base a ciò che è nel file è ancora priva di effetti collaterali, poiché hai permesso agli input di provenire da altri punti dell'effetto desiderato.
Quindi, perché è tutto così importante?
Si tratta di controllo e mantenimento. Se chiamate una funzione e fa qualcos'altro, quindi restituisce un valore, è difficile ragionare sul suo comportamento. Dovrai andare all'interno della funzione per individuare il codice effettivo per indovinare cosa sta facendo e affermarne la correttezza. La situazione ideale è che è molto chiaro e facile sapere qual è l'input utilizzato dalla funzione e che non sta facendo altro che restituire un output per esso. Puoi rilassare un po 'questo, e dire che sapere esattamente quale input sta usando non è utile quanto essere certo che non sta facendo altro che potresti non essere a conoscenza e quindi restituire un valore, quindi forse sei soddisfatto solo di far rispettare che non fa nient'altro che mappare l'input, indipendentemente da dove lo ottiene, all'output.
In quasi tutti i casi, il punto di un programma è avere effetti diversi dalla mappatura delle cose che entrano nelle cose che escono. L'idea di controllare l'effetto collaterale è che puoi organizzare il codice in un modo che sia più facile da capire e ragionare. Se metti insieme tutti gli effetti collaterali, in un posto che è molto esplicito e centrale, è facile sapere dove guardare e fidarsi che questo è tutto ciò che sta accadendo, non di più. Se l'input è anche molto esplicito, aiuta a testare il comportamento per input diversi ed è più facile da usare, poiché non è necessario modificare l'input in molti luoghi diversi, alcuni dei quali potrebbero non essere ovvi, solo per ottenere quello che vuoi.
Poiché il più utile per capire, ragionare e controllare il comportamento di un programma è avere tutti gli input chiaramente raggruppati ed espliciti, così come avere tutti gli effetti collaterali essere raggruppati ed espliciti, questo è generalmente ciò di cui le persone parlano quando dicono effetto collaterale, puro, ecc.
Poiché il più utile è il raggruppamento degli effetti collaterali e la loro esplicitazione, a volte le persone intendono solo questo, e lo distinguono dicendo che non è puro, ma è ancora "effetto collaterale" libero. Ma l'effetto collaterale è relativo al presunto "effetto primario previsto", quindi è un termine contestuale. Trovo che questo sia usato meno spesso, anche se sorprendentemente si parla molto di questo thread.
Infine, idempotente significa che chiamare questa funzione più volte con gli stessi input (non importa da dove vengano) provocherà sempre gli stessi effetti (effetto collaterale o meno).