En informática, se dice que una función o expresión tiene un efecto secundario si modifica algún estado o tiene una interacción observable con las funciones de llamada o el mundo exterior.
De Wikipedia - Efecto secundario
Una función, en el sentido matemático, es un mapeo de entrada a salida. El efecto deseado de llamar a una función es que asigne la entrada a la salida que devuelve. Si la función hace algo más, no importa qué, pero si tiene algún comportamiento que no esté asignando la entrada a la salida, se sabe que ese comportamiento es un efecto secundario.
En términos más generales, un efecto secundario es cualquier efecto que no sea el efecto previsto del diseñador de la construcción.
Un efecto es cualquier cosa que afecta a un actor. Si llamo a una función que envía a mi novia un mensaje de texto de ruptura, que afecta a un grupo de actores, a mí, a ella, a la red de la compañía de telefonía celular, etc. El único efecto previsto de llamar a una función libre de efectos secundarios es para la función para devolverme una asignación de mi entrada. Entonces para:
public void SendBreakupTextMessage() {
Messaging.send("I'm breaking up with you!")
}
Si se pretende que sea una función, entonces lo único que debería hacer es devolver void. Si no tenía efectos secundarios, en realidad no debería enviar el mensaje de texto.
En la mayoría de los lenguajes de programación, no existe una construcción para una función matemática. Ninguna construcción está destinada a ser utilizada como tal. Es por eso que la mayoría de los idiomas dicen que tiene métodos o procedimientos. Por diseño, se pretende que puedan hacer muchos más efectos. En el lenguaje de programación común, a nadie realmente le importa la intención de lo que era un método o un procedimiento, por lo que cuando alguien dice que esta función tiene efectos secundarios, en realidad quieren decir que esta construcción no se comporta como una función matemática. Y cuando alguien dice que esta función no tiene efectos secundarios, quieren decir que esta construcción se comporta efectivamente como una función matemática.
Una función pura siempre está libre de efectos secundarios, por definición. Una función pura, es una forma de decir, esta función, aunque está utilizando una construcción que permite más efectos, solo tiene como efecto una igual a la de una función matemática.
Reto a cualquiera a que me diga cuándo una función libre de efectos secundarios no sería pura. A menos que el efecto primario deseado del contexto de la oración usando el término puro y sin efectos secundarios no sea el efecto matemático previsto de una función, entonces esos son siempre iguales.
Como tal, a veces, aunque más raramente, y creo que esta es la distinción que carece y también desorienta a las personas (ya que esa no es la suposición más común) en la respuesta aceptada, pero a veces se supone que el efecto deseado de una función de programación es para asignar entrada a salida, donde la entrada no está limitada a los parámetros explícitos de la función, pero la salida está limitada al valor de retorno explícito. Si supone que ese es el efecto deseado, entonces una función que lee un archivo y devuelve un resultado diferente en función de lo que está en el archivo aún no tiene efectos secundarios, ya que permitió que las entradas provengan de otros lugares en su efecto deseado.
Entonces, ¿por qué es todo esto importante?
Se trata de controlar y mantenerlo. Si llama a una función y hace otra cosa y luego devuelve un valor, es difícil razonar sobre su comportamiento. Tendrá que buscar dentro de la función el código real para adivinar lo que está haciendo y afirmar su corrección. La situación ideal es que es muy claro y fácil saber cuál es la entrada que está utilizando la función y que no está haciendo nada más que devolverle una salida. Puede relajar esto un poco y decir que saber exactamente qué entrada está utilizando no es tan útil como estar seguro de que no está haciendo nada más de lo que podría no estar enterado y luego devolver un valor, por lo que tal vez esté satisfecho con solo aplicar que no hace nada más que mapear la entrada, sin importar de dónde la obtenga, a la salida.
En casi todos los casos, el objetivo de un programa es tener otros efectos además de mapear las cosas que entran y las que salen. La idea de controlar el efecto secundario es que puede organizar el código de una manera que sea más fácil de entender y razonar. Si combina todos los efectos secundarios, en un lugar que es muy explícito y central, es fácil saber dónde mirar y confiar en que esto es todo lo que está sucediendo, nada más. Si la entrada también es muy explícita, ayuda a probar el comportamiento para diferentes entradas, y es más fácil de usar, ya que no necesita cambiar la entrada en muchos lugares diferentes, algunos que pueden no ser obvios, solo para conseguir lo que quieres
Debido a que lo más útil para comprender, razonar y controlar el comportamiento de un programa es tener todas las entradas claramente agrupadas y explícitas, así como tener todos los efectos secundarios agrupados y explícitos, esto es generalmente de lo que las personas hablan cuando dicen efecto secundario, puro, etc.
Debido a que lo más útil es la agrupación de los efectos secundarios y su carácter explícito, a veces las personas solo quieren decir eso, y lo distinguen diciendo que no es puro, sino que está libre de "efectos secundarios". Pero el efecto secundario es relativo al supuesto "efecto primario pretendido", por lo que es un término contextual. Esto me parece que se usa con menos frecuencia, aunque sorprendentemente se habla mucho en este hilo.
Finalmente, idempotente significa que llamar a esta función muchas veces con las mismas entradas (no importa de dónde provengan) siempre dará como resultado los mismos efectos (efecto secundario o no).