A resposta simples para sua pergunta é que Math.random()
viola a regra nº 2.
Muitas outras respostas aqui indicaram que a presença de Math.random()
significa que essa função não é pura. Mas acho que vale a pena dizer por Math.random()
que as funções de contaminação que o usam.
Como todos os geradores de números pseudoaleatórios, Math.random()
começa com um valor "semente". Em seguida, ele usa esse valor como ponto de partida para uma cadeia de manipulações de bits de baixo nível ou outras operações que resultam em uma saída imprevisível (mas não realmente aleatória ).
Em JavaScript, o processo envolvido depende da implementação e, ao contrário de muitas outras linguagens, o JavaScript não fornece nenhuma maneira de selecionar a semente :
A implementação seleciona a semente inicial para o algoritmo de geração de números aleatórios; não pode ser escolhido ou redefinido pelo usuário.
É por isso que essa função não é pura: JavaScript está essencialmente usando um parâmetro de função implícito sobre o qual você não tem controle. Ele está lendo esse parâmetro de dados calculados e armazenados em outro lugar e, portanto, viola a regra nº 2 em sua definição.
Se você quiser fazer disso uma função pura, poderá usar um dos geradores de números aleatórios alternativos descritos aqui . Chame aquele gerador seedable_random
. Leva um parâmetro (a semente) e retorna um número "aleatório". Claro, esse número não é realmente aleatório; é determinado exclusivamente pela semente. É por isso que esta é uma função pura. A saída de seedable_random
é apenas "aleatória" no sentido de que é difícil prever a saída com base na entrada.
A versão pura desta função precisaria de três parâmetros:
function test(min, max, seed) {
return seedable_random(seed) * (max - min) + min;
}
Para qualquer dado triplo de (min, max, seed)
parâmetros, isso sempre retornará o mesmo resultado.
Observe que, se você quiser que a saída de seedable_random
seja realmente aleatória, precisará encontrar uma maneira de tornar a semente aleatória! E qualquer estratégia que você usasse seria inevitavelmente não pura, porque exigiria que você reunisse informações de uma fonte externa à sua função. Como o mtraceur e o jpmc26 me lembram, isso inclui todas as abordagens físicas: geradores de números aleatórios de hardware , webcams com tampas de lente , coletores de ruído atmosférico - até lâmpadas de lava . Tudo isso envolve o uso de dados calculados e armazenados fora da função.
Math.random()
que muda o estado do RNG.