Na ciência da computação, diz-se que uma função ou expressão tem um efeito colateral se modificar algum estado ou se houver uma interação observável com as funções de chamada ou com o mundo exterior.
Da Wikipedia - Efeito Colateral
Uma função, no sentido matemático, é um mapeamento da entrada para a saída. O efeito pretendido de chamar uma função é mapear a entrada para a saída que retorna. Se a função fizer qualquer outra coisa, não importa o quê, mas se tiver algum comportamento que não esteja mapeando a entrada para a saída, esse comportamento é conhecido por ser um efeito colateral.
Em termos mais gerais, um efeito colateral é qualquer efeito que não seja o efeito pretendido pelo projetista da construção.
Um efeito é qualquer coisa que afeta um ator. Se eu ligar para uma função que envie à minha namorada uma mensagem de texto final, que afete vários atores, eu, ela, a rede da empresa de telefonia celular etc. O único efeito pretendido de chamar uma função livre de efeito colateral é a função para retornar um mapeamento da minha entrada. Então para:
public void SendBreakupTextMessage() {
Messaging.send("I'm breaking up with you!")
}
Se isso pretende ser uma função, a única coisa que deve fazer é retornar nulo. Se fosse livre de efeitos colaterais, não deveria realmente enviar a mensagem de texto.
Na maioria das linguagens de programação, não há construção para uma função matemática. Nenhuma construção se destina a ser usada como tal. É por isso que a maioria dos idiomas diz que você tem métodos ou procedimentos. Por design, esses itens devem ter muito mais efeitos. Na linguagem comum de programação, ninguém realmente se importa com a intenção de qual método ou procedimento era; portanto , quando alguém diz que essa função tem efeito colateral, eles efetivamente significam que esse construto não se comporta como uma função matemática. E quando alguém diz que essa função é livre de efeitos colaterais, eles querem dizer que esse construto se comporta efetivamente como uma função matemática.
Uma função pura é sempre livre de efeitos colaterais, por definição. Uma função pura, é uma maneira de dizer, essa função, mesmo que esteja usando uma construção que permita mais efeitos, tem como efeito igual à de uma função matemática.
Eu desafio alguém a me dizer quando uma função livre de efeitos colaterais não seria pura. A menos que o efeito primário pretendido do contexto da sentença usando o termo puro e livre de efeitos colaterais não seja o efeito matemático de uma função, eles sempre serão iguais.
Como tal, às vezes, embora mais raramente, e acredito que essa é a distinção que falta e também desorienta as pessoas (como essa não é a suposição mais comum) na resposta aceita, mas às vezes presume-se que o efeito pretendido de uma função de programação seja mapear entrada para saída, em que a entrada não é restrita aos parâmetros explícitos da função, mas a saída é restrita ao valor de retorno explícito. Se você assumir que esse é o efeito pretendido, uma função que esteja lendo um arquivo e retornando um resultado diferente com base no que está no arquivo ainda estará livre de efeitos colaterais, pois você permitiu que entradas fossem provenientes de outros lugares no efeito pretendido.
Então, por que tudo isso é importante?
É tudo sobre controle e manutenção. Se você chama uma função e ela faz outra coisa e depois retorna um valor, é difícil argumentar sobre seu comportamento. Você precisará procurar dentro da função o código real para adivinhar o que está fazendo e afirmar sua correção. A situação ideal é que é muito claro e fácil saber qual é a entrada que a função está usando e que ela não está fazendo nada além de retornar uma saída para ela. Você pode relaxar um pouco e dizer que saber exatamente qual entrada está sendo usada não é tão útil quanto ter certeza de que não está fazendo mais nada do que você talvez não esteja ciente de retornar um valor, então talvez esteja satisfeito apenas em aplicar que ele não faz mais nada, em seguida, mapeia a entrada, não importa de onde vem, para a saída.
Em quase todos os casos, o objetivo de um programa é ter efeitos que não sejam mapear as coisas que vão surgindo. A idéia de controlar o efeito colateral é que você pode organizar o código de uma maneira que seja mais fácil de entender e raciocinar. Se você reunir todo o efeito colateral, em um local muito explícito e central, é fácil saber para onde procurar e confiar que isso é tudo o que está acontecendo, nada mais. Se você tem uma entrada muito explícita, isso ajuda a testar o comportamento de entradas diferentes e é mais fácil de usar, pois você não precisa alterar a entrada em muitos lugares diferentes, alguns que podem não ser óbvios, apenas para conseguir o que você quer.
Como o mais útil para entender, raciocinar e controlar o comportamento de um programa é ter todas as entradas claramente agrupadas e explícitas, além de todos os efeitos colaterais serem agrupados e explícitos, é sobre isso que as pessoas falam quando dizem efeito colateral, puro, etc.
Como o mais útil é o agrupamento dos efeitos colaterais e sua explicitação, às vezes as pessoas apenas querem dizer isso, e o distinguem dizendo que não é puro, mas ainda é "livre de efeitos colaterais". Mas efeito colateral é relativo ao suposto "efeito primário pretendido", portanto é um termo contextual. Acho que isso é usado com menos frequência, embora, surpreendentemente, seja discutido muito neste tópico.
Por fim, idempotente significa chamar essa função muitas vezes com as mesmas entradas (não importa de onde elas venham) sempre resultará nos mesmos efeitos (efeito colateral ou não).