Não entendi claramente o conceito de efeito colateral.
- Qual é o efeito colateral da programação?
- É dependente da linguagem de programação?
- Existe efeitos colaterais externos e internos?
Por favor, dê um exemplo de causas que criam efeitos colaterais.
programming-languages
functional-programming
Amir Rezaei
fonte
fonte
Respostas:
Um efeito colateral refere-se simplesmente à modificação de algum tipo de estado - por exemplo:
Ao contrário do que algumas pessoas parecem estar dizendo:
Um efeito colateral não precisa ser oculto ou inesperado (pode ser, mas isso não tem nada a ver com a definição que se aplica à ciência da computação);
Um efeito colateral não tem nada a ver com idempotência. Uma função idempotente pode ter efeitos colaterais, e uma função não idempotente pode não ter efeitos colaterais (como obter a data e hora atuais do sistema).
É realmente muito simples. Efeito colateral = mudar algo em algum lugar.
PS Como comenta Benjol, várias pessoas podem estar confundindo a definição de um efeito colateral com a definição de uma função pura , que é uma função que é (a) idempotente e (b) não tem efeitos colaterais. Um não implica o outro na ciência geral da computação, mas as linguagens de programação funcional tendem a impor as duas restrições.
fonte
++a
.. Não parece tarefa.b = ++a;
tem dois efeitos colaterais. O óbvio e a atribuição de criptografia dea
. Esse é o tipo de coisa que é um efeito colateral que (para alguns) é desejável. Mas isso foi chamado de efeito colateral de toda a minha carreira para torná-la não sutil.Diz-se que qualquer operação que modifique o estado do computador ou que interaja com o mundo exterior tem um efeito colateral. Veja a Wikipedia sobre efeitos colaterais .
Por exemplo, esta função não tem efeitos colaterais. Seu resultado depende apenas dos argumentos de entrada e nada sobre o estado do programa ou seu ambiente muda quando é chamado:
Por outro lado, chamar essas funções fornecerá resultados diferentes, dependendo da ordem em que você as chama, porque elas alteram algo sobre o estado do computador:
Esta função tem o efeito colateral de gravar dados na saída. Você não chama a função porque deseja seu valor de retorno; você o chama porque deseja o efeito que ele tem no "mundo exterior":
fonte
Write
exemplo demonstra, ter efeitos colaterais não implica que a função mude sua saída em relação a suas entradas, ou mesmo que sua saída dependa da entrada.square(x)
pode fazer com que o módulo em que a função está definida seja carregado do disco. Isso deve ser considerado efeito colateral? Afinal, esta mens que o (primeiro) chamada leva inesperadamente longo, que o uso da RAM sobe, etc.square(x)
porque deseja que o estado do computador externo mude, considere isso como um efeito colateral.Eu acho que as respostas existentes são muito boas. Gostaria de elaborar alguns aspectos que a OMI não foi enfatizada o suficiente.
Em matemática, uma função é apenas um mapeamento de uma tupla de valores para um valor. Portanto, dada uma função
f
e um valorx
,f(x)
sempre será o mesmo resultadoy
. Você pode substituirf(x)
pory
todos os lugares de uma expressão e nada mudará.O que é chamado de função (ou procedimento) em muitas linguagens de programação é uma construção (parte do código) que pode ser executada porque:
Portanto, os efeitos podem estar relacionados ao estado, mas também a outros aspectos, como disparar um míssil ou pausar a execução por alguns segundos.
O termo efeito colateral pode parecer negativo, mas normalmente o efeito de chamar uma função é o próprio objetivo da própria função. Suponho que, como o termo função foi originalmente usado em Matemática, a computação de um valor seja considerada o efeito primário de uma função, enquanto outros efeitos são considerados efeitos colaterais . Algumas linguagens de programação usam o termo procedimento para evitar confusões com funções no sentido matemático.
Observe que
sleep()
em Python, são úteis apenas para seus efeitos (colaterais),. Eles geralmente são modelados como funções que retornam um valor especialNone
, ouunit
ou()
ou ..., o que simplesmente indica que o cálculo foi finalizado corretamente.fonte
Um efeito colateral é quando uma operação afeta uma variável / objeto que está fora do uso pretendido.
Isso pode acontecer quando você faz uma chamada para uma função complexa que tem o efeito colateral de alterar alguma variável global, mesmo que não tenha sido o motivo pelo qual você a chamou (talvez você tenha chamado para extrair algo de um banco de dados).
Eu admito que estou tendo problemas para apresentar um exemplo simples que não parece totalmente artificial, e exemplos de coisas nas quais trabalhei são muito longos para serem postados aqui (e, como é relacionado ao trabalho, provavelmente não devo )
Um exemplo que eu vi (há algum tempo) foi uma função que abriu uma conexão com o banco de dados se a conexão estivesse em um estado fechado. O problema era que ele deveria fechar a conexão no final da função, mas o desenvolvedor esqueceu de adicionar esse código. Portanto, aqui havia um efeito colateral não intencional : chamar um procedimento deveria fazer apenas uma consulta e o efeito colateral era que a conexão permanecesse aberta e se a função fosse chamada duas vezes seguidas, seria gerado um erro dizendo que a conexão era já aberto.
Ok, então como todo mundo está dando exemplos agora, acho que vou também;)
A função
do_task_x
tem um efeito primário de retornar o resultado de alguns cálculos e um efeito colateral de possivelmente modificar uma variável global.Obviamente, qual é o principal e qual é o efeito colateral pode estar aberto à interpretação e depender do uso real. Se eu chamar essa função com a finalidade de modificar o global e descartar o valor retornado, diria que modificar o global é o efeito principal.
fonte
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:
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).
fonte
Na programação, um efeito colateral é quando um procedimento altera uma variável de fora do seu escopo. Os efeitos colaterais não dependem do idioma. Existem algumas classes de idiomas que visam eliminar efeitos colaterais (idiomas funcionais puros), mas não tenho certeza se há algum que exija efeitos colaterais, mas posso estar errado.
Tanto quanto eu sei, não há efeitos colaterais internos e externos.
fonte
Aqui está um exemplo simples:
A definição de efeito colateral não é específica da programação; basta imaginar os efeitos colaterais dos remédios ou comer muita comida.
fonte
x++
modificar a variávelx
é geralmente considerado um efeito colateral. Esse valor da expressão é o valor de pré-incremento dex
; essa é a parte do efeito não colateral da expressão.Um efeito colateral são coisas que acontecem no código que não são obviamente aparentes.
Por exemplo, digamos que você tenha essa classe
Quando você cria a classe inicialmente, dá a ela uma semente.
Você não conhece os internos, apenas espera obter um valor aleatório e esperaria que o randomGenerator.Seed ainda tivesse 15 ... mas não é.
A chamada de função teve o efeito colateral de alterar o valor de propagação.
fonte