Na computação, dizemos que algo possui algum efeito colateral caso haja algum outro efeito observável que não seja o seu efeito primário (ler os argumentos e retornar).
Isso quer dizer que uma função possui efeitos colaterais caso altere o estado do programa sem ser pelo seu retorno.
O efeito colateral mais comum é uma atribuição à uma variável global.
- Modificar uma variável não local, variável local estática ou um argumento passado por referência
- Lançar erros ou exceções
- Entrada/saída de dados
- Chamar outras funções com efeitos colaterais
Na presença de efeitos colaterais, o comportamento de um programa pode depender de sua ordem de execução no programa, uma vez que outra expressão pode modificar o valor de uma variável que está em uso.
Entender e debugar uma função com efeitos colaterais requer um entendimento do contexto em que ela está sendo executada.
A seguinte função incrementa uma variável global iniciada em 0. Em cada chamada estamos printando o valor retornado.
contador = 0
def incremento():
global contador
contador += 1
return contador
print(incremento())
print(incremento())
O paradigma adotado interfere diretamente no uso dos efeitos colaterais, um ótimo exemplo é na comparação entre os paradigmas Imperativo e Declarativo.
- Imperativo: utiliza os efeitos colaterais ao seu favor, pois funciona através da atualização do estado de um sistema.
- Declarativo: diferentemente da anterior, a programação declarativa apenas relata o estado do sistema, sem efeitos colaterais.
O paradigma funcional busca minimizar/eliminar os efeitos colaterais. A falta desses efeitos facilita a verificação formal do programa.
A linguagem Haskell elimina os efeitos colaterais, como os de E/S e outras computações "stateful" (mantém informações sobre o estado). Isso é feito através da substituição por Mônadas.
- Mônada: uma maneira de estruturar os cálculos como uma sequência de etapas, onde cada etapa não produz apenas um valor, mas também informações extras sobre a computação, como falhas potenciais, não determinismo, efeitos colaterais.
Uma função pura, em programação funcional, é aquela que não tem nenhum efeito e nem faz uso de nenhum estado fora da função. Temos 3 critérios:
- A função sempre deve retornar o mesmo output quando receber a mesma entrada;
- A função não pode ter efeitos colaterais;
- A função deve ter transparência referencial, ou seja, depende apenas de seu input;
Uma função pura é determinística e não possui efeitos colaterais.
Haskell tenta eliminar os efeitos colaterais, então todas as funções são puras, a não ser que utilizemos E/S de dados.
-- sempre que utilizarmos as mesmas entradas, teremos as mesmas saídas
soma :: Int -> Int -> Int
soma a b = a + b
Em ciência da computação, imutabilidade é um conceito que se refere à propriedade de um objeto não poder ser modificado ou alterado após a sua criação. Uma vez que um objeto imutável é criado o seu estado não pode ser alterado. Caso haja a necessidade de mudança, um novo objeto é tipicamente criado com as mudanças desejadas, mantendo o original.
O conceito de imutabilidade é muito utilizado na programação funcional.
- Previsibilidade: esses objetos mantém um estado consistente, facilitando o entendimento sobre seu comportamento.
- Simultaneidade: a imutabilidade torna o acesso de vários threads/processos a um dado mais seguro e sem precisar se preocupar tanto com a sincronização.
- Depuração: simplifica a depuração de um programa, pois podemos confiar que os dados não mudarão inesperadamente. Também reduz o potencial de efeitos colaterais.
- Programação Funcional: permite funções puras, que geram a mesma saída para as mesmas entradas.
- Performance: reduz a sobrecarga de memória e melhora a eficiência de alocação de memória.
Dentre outros benefícios.
O seguinte código mostra exemplos do que podemos/não podemos fazer em um objeto imutável (nesse caso, nas tuplas).
Obs: podemos pensar nas tuplas como "listas imutáveis", apesar delas terem algumas outras diferenças.
# ex. com lista
minha_lista = [1, 2, 3]
minha_lista[0] = 4
# ex. com tuplas
minha_tupla = (1, 2, 3)
minha_tupla[0] = 4
-
Paradigmas de Programação: Uma Abordagem Comparativa - 5.2 Efeitos Colaterais
-
JavaScript Overview — Functional Programming (Immutability, Side Effects, Pure Functions, HOFs)