Trabalhar com funções puras pode ser muito menos estressante, pois você pode testá-las facilmente e raciocinar sobre elas com mais confiança.

Funções puras são funções que não produzem efeitos colaterais e, quando chamadas com os mesmos parâmetros de entrada, sempre retornarão a mesma saída.

Você pode usar funções puras para garantir que seu código seja limpo, sustentável e testável. Essas funções são ideais para essas tarefas porque são previsíveis e não modificam estados externos.

Eles também são mais fáceis de depurar, tornando-os úteis no desenvolvimento de sistemas de software complexos. Aqui você explorará funções puras em JavaScript, suas características e suas vantagens.

Características de uma Função Pura

Para uma função para ser “puro”, tem que satisfazer alguns requisitos.

Valor de retorno constante

Uma função pura deve sempre retornar o mesmo valor dada a mesma entrada, independentemente do número de vezes que é chamada.

Por exemplo, considere a função abaixo:

funçãomultiplicar(a, b) {
retornar a * b;
}

O multiplicar A função no exemplo acima sempre retornará o produto de seus dois argumentos. Dado o mesmo conjunto de argumentos, ele tem um valor de retorno constante.

Chamar esta função várias vezes com os mesmos argumentos produzirá a mesma saída todas as vezes. Por exemplo:

multiplicar(2, 3); // retorna 6
multiplicar(2, 3); // retorna 6
multiplicar(2, 3); // retorna 6

Alternativamente, considere o exemplo abaixo:

funçãomultipliqueRandomNumber(num) {
retornar num * Matemática.chão(Matemática.aleatório() * 10);
}

multiplicarRandomNumber(5); // Resultados imprevisíveis
multiplicarRandomNumber(5); // Resultados imprevisíveis
multiplicarRandomNumber(5); // Resultados imprevisíveis

O multipliqueRandomNumber A função acima retornará resultados diferentes cada vez que você chamá-la, tornando-a impura. Os resultados dessa função são imprevisíveis, portanto, testar os componentes que dependem dela é difícil.

Sem efeitos colaterais

Uma função pura não deve produzir nenhum efeito colateral. Um efeito colateral refere-se a qualquer modificação de estado ou comportamento fora do escopo da função, como modificação de variáveis ​​globais, saída do console, solicitações de rede ou manipulação de DOM.

Quando uma função pura tem um efeito colateral, ela não é mais pura porque afeta o estado externo e viola o princípio de não ter efeitos colaterais observáveis. Portanto, funções puras evitam efeitos colaterais para garantir que não alterem o estado do programa.

Por exemplo, considere o exemplo abaixo:

deixar contagem = 0;

funçãoincremento() {
contar++;
console.log (contagem);
}

incremento(); // Registros 1
incremento(); // Registros 2
incremento(); // Registros 3

O incremento função neste exemplo tem o efeito colateral de modificar o contar variável fora de seu escopo. Ele também registra no console.

Essa função não é pura porque tem um efeito colateral, que pode tornar mais difícil prever sua saída e testar isoladamente. Para torná-lo puro, você pode modificá-lo para absorver o contar variável como um argumento e retornar o valor incrementado sem modificar nenhum estado externo.

Igual a:

funçãoincremento(contar) {
retornar contar + 1;
}

incremento(1); // retorna 2
incremento(1); // retorna 2
incremento(1); // retorna 2

A versão do incremento A função no exemplo acima não tem efeitos colaterais, pois não modifica nenhuma variável externa nem registra nenhum valor. Além disso, não importa quantas vezes você o chame, ele retornará o mesmo valor para a mesma entrada. Portanto, é uma função pura.

Outras características

Além de ter um valor de retorno constante e não produzir efeitos colaterais, você deve seguir as seguintes regras quando estiver criando uma função JavaScript que você quer ser puro:

  • Sua função não deve modificar nenhum de seus argumentos. Em vez disso, se alguma operação exigir mutação, faça uma cópia do argumento e modifique a cópia.
  • Sua função deve sempre ter um valor de retorno. Se sua função não tiver um valor de retorno ou nenhum efeito colateral, ela não poderá fazer nada!
  • Sua função não deve depender de nenhum estado externo.

Vantagens das funções puras

As funções puras têm certos benefícios sobre as funções impuras, algumas das quais incluem as seguintes.

Testabilidade

As funções puras são fáceis de testar, pois seu comportamento de entrada/saída é bem definido. Além disso, funções puras não dependem de estado externo ou efeitos colaterais. Portanto, você pode testá-los isoladamente sem se preocupar com quaisquer dependências ou interações com outras partes do programa.

Por outro lado, testar funções impuras que dependem do estado externo ou produzem efeitos colaterais pode ser mais desafiador porque seu comportamento pode depender do estado do programa ou de outros fatores externos. Isso pode dificultar a criação de casos de teste abrangentes e garantir que a função se comporte corretamente em todos os cenários.

Memorização

Como as funções puras sempre produzem a mesma saída para a mesma entrada e não produzem efeitos colaterais, você pode memorizá-las facilmente.

Baseando-se nessas propriedades e usando memoização, você pode armazenar em cache o resultado de uma chamada de função pura para uma entrada específica. Sua função pode retornar o resultado armazenado em cache na próxima vez que for chamada com a mesma entrada.

Memorizando funções puras pode melhorar o desempenho de um programa, especialmente para cálculos caros que lidam repetidamente com a mesma entrada, sem se preocupar com a interferência no estado do programa.

Em contraste, funções impuras podem produzir resultados diferentes para a mesma entrada, dependendo do estado do programa ou de fatores externos. Isso os torna difíceis de memorizar porque o resultado armazenado em cache pode não ser mais válido se as dependências da função ou o estado externo mudarem entre as chamadas.

Simultaneidade

Como as funções puras não modificam nenhum estado externo nem produzem efeitos colaterais, elas são thread-safe. Você pode executá-los simultaneamente sem se preocupar com condições de corrida ou problemas de sincronização.

Por outro lado, as funções impuras podem ser difíceis de executar simultaneamente porque podem interferir umas nas outras ou produzir um comportamento inesperado quando executadas em paralelo. Por exemplo, se dois threads acessam e modificam a mesma variável global, eles podem sobrescrever as alterações um do outro ou produzir resultados inconsistentes.

Funções Puras vs. Funções impuras

Você pode escrever programas usando uma combinação de funções puras e impuras, pois cada tipo tem seus usos.

As funções puras são fáceis de otimizar, testar e paralelizar, tornando-as adequadas para casos de uso como programação funcional, cache, teste, programação paralela e tarefas de processamento de dados.

No entanto, funções impuras apresentam desafios em testes e simultaneidade, mas são úteis ao trabalhar com estruturas de dados mutáveis ​​ou interagir com sistemas e recursos externos.