Funções sem Efeitos Colaterais

livroprogramacaofuncional

Ainda lendo o livro “Programação Funcional para Desenvolvedores Java” do Ph.D Dean Wampler, esbarrei com um conceito interessante desse paradigma de programação e que poderia ser pensado no orientação a objetos.

O que são funções sem efeitos colaterais?

Segundo o livro, funções que possuem efeitos colaterais são aquelas que não importa quantas vezes nós a chamemos, ela sempre retornará o mesmo valor. Isso acontece porque essa funções não alteram o estado em que elas estão, como por exemplo na orientação a objeto, gravar valores em um campo do objeto em que estão ou, na programação procedural, gravar valores em variáveis globais. Sendo assim, funções sem efeitos colaterais são obviamente o oposto disso. Buscando um pouco mais sobre esse tema, encontrei o blog do Maurízio Szabo, e ele da o seguinte significado a funções sem efeitos colaterais:

Uma função não tem efeitos colaterais quando não importa quantas vezes ela é chamada, ela sempre traz os mesmos resultados – Maurício Szabo

Então, um função sem efeito colateral é aquela que retorna sempre o mesmo resultado se sempre usarmos os mesmos parâmetros de entrada e também é aquela que não depende do contexto. Reparem que essas duas partes da definição se relacionam. Se uma função não depende do contexto, isto é, não altera o contexto nem depende de algum dado dele, o resultado dela só dependerá dos parâmetros de entrada e, por isso, se informarmos sempre os mesmos parâmetros ela sempre retornará o mesmo resultado.

Diante de tais definições cheguei a conclusão de que é improvável que sob o paradigma orientado a objetos seja possível criar uma função que não cause efeitos colaterais ao ser invocada, pois é dificil uma função não alterar variáveis do objeto apesar de ser fácil encontrar funções que sempre retornam os mesmo valor não importando o número de vezes que são chamadas. Isso porque as funções são extremamente coesas ao escopo ou contexto empregado pela classe em que ele está e, por isso, acabam alterando informações daquele contexto, como os atributos da classe.

(…) não é possível escrever um código completamente isento de efeitos colaterais (na verdade, até é possível, mas provavelmente ninguém vai querer usar um programa no qual você roda-o e ele imprime na tela um resultado baseado em valores hard-coded no código…). Então, a ideia é evitar ao máximo efeitos colaterais em seu código (ao contrário do que você aprendeu a programar na faculdade, se sua faculdade for igual à minha…) – Maurício Szabo

Então, mesmo que seja impossível eliminar todos os efeitos colaterais, porque devo tentar ao máximo evitá-los em meu código? Pelas vantagens que isso traz.

Vantagens – Porque deveria pensar nisso?

Dentre as vantagens podemos citar, facilitar testes unitários, diminuir complexidade do código e facilitar reuso, entendimento e manutenção do código. Seguem abaixo as citações dos autores que afirmam o mesmo:

Por fim, sem efeitos colaterais, é mais fácil de testar o código. E embora seja impossível fazer um sistema completo sem nenhum efeito colateral, nos testes isso é imprescindível (teardown, ou o “after” do rspec, são funções que obrigatoriamente devem limpar qualquer “sujeira” que seu teste tenha feito: criar arquivos, criar registros no banco de dados, etc). – Maurício Szabo

Outra fonte de complexidade, de que leva a falhas, são funções que mudam o estado, e.g., gravar valores no campo de um objeto ou de variáveis globais. – Dean Wampler

Funções sem efeitos colaterais são ótimas para implementar reuso, já que não dependem do contexto no qual são executadas. Comparadas com funções com efeitos colaterais, também são mais fáceis de projetar, entender, otimizar e testar. Assim, têm menor probabilidade de ter erros. – Dean Wampler

Como tornar minha função sem efeitos colaterais?

Há algumas dicas dadas pelo Maurício em seu post para tornar as funções com menos efeitos colaterais possível. A primeira é implementar a ideia das funções realizarem poucas ações e terem um único objetivo unida com a ideia de evitar funções que possuam o mesmo objetivo.

Enfim, a ideia principal é fazer os métodos fazerem poucas coisas. Se você precisa criar um método que vai identificar se aquele registro é válido, certifique-se de que ele APENAS faz isso. – Maurício Szabo

E a segunda dica é evitar retornos baseados em número randômicos e data para que seja possível o retorno ser sempre o mesmo e evitar IO para que o estado se mantenha sempre o mesmo.

Outra dica interessante é que para uma função não ter efeitos colaterais, ela não pode envolver-se com E/S (IO) (ou seja, não pode imprimir na tela, salvar num arquivo, ler um caractere, etc), nem gerar ou consumir número randômicos, acessar a data e hora atual, etc… isso porque qualquer E/S modifica o estado do sistema, gerar número randomicos é, por definição, algo que gera um resultado diferente sempre que é chamado, e acessar a data e hora é basicamente ter um resultado diferente a cada milisegundo (por isso que fazemos “stub” desse tipo de operação em testes). – Maurício Szabo

Referências

[1] – WAMPLER, Dean. Functional Programming for Java Developers: Tools for Better Concurrency, Abstraction, and Agility. ” O’Reilly Media, Inc.”, 2011.

[2] – Em: <https://mauricioszabo.wordpress.com/2012/03/16/efeitos-colaterais-e-codigos/&gt;. Acesso em: 24 janeiro 2015

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s