La respuesta simple a su pregunta es que Math.random()
viola la regla # 2.
Muchas otras respuestas aquí han señalado que la presencia de Math.random()
significa que esta función no es pura. Pero creo que vale la pena decir por qué Math.random()
corrompe las funciones que lo usan.
Como todos los generadores de números pseudoaleatorios, Math.random()
comienza con un valor "semilla". Luego usa ese valor como punto de partida para una cadena de manipulaciones de bits de bajo nivel u otras operaciones que dan como resultado una salida impredecible (pero no realmente aleatoria ).
En JavaScript, el proceso involucrado depende de la implementación y, a diferencia de muchos otros lenguajes, JavaScript no proporciona ninguna forma de seleccionar la semilla :
La implementación selecciona la semilla inicial para el algoritmo de generación de números aleatorios; el usuario no puede elegirlo ni restablecerlo.
Es por eso que esta función no es pura: JavaScript esencialmente está usando un parámetro de función implícito sobre el que no tienes control. Está leyendo ese parámetro a partir de datos calculados y almacenados en otro lugar y, por lo tanto, viola la regla n. ° 2 de su definición.
Si desea convertir esto en una función pura, puede usar uno de los generadores de números aleatorios alternativos que se describen aquí . Llame a ese generador seedable_random
. Toma un parámetro (la semilla) y devuelve un número "aleatorio". Por supuesto, este número no es realmente aleatorio; está determinado únicamente por la semilla. Por eso es una función pura. La salida de seedable_random
es solo "aleatoria" en el sentido de que es difícil predecir la salida basándose en la entrada.
La versión pura de esta función necesitaría tomar tres parámetros:
function test(min, max, seed) {
return seedable_random(seed) * (max - min) + min;
}
Para cualquier triple de (min, max, seed)
parámetros, siempre devolverá el mismo resultado.
Tenga en cuenta que si desea que la salida de seedable_random
sea verdaderamente aleatoria, ¡deberá encontrar una manera de aleatorizar la semilla! Y cualquier estrategia que utilizara inevitablemente no sería pura, porque requeriría que recopilara información de una fuente fuera de su función. Como me recuerdan mtraceur y jpmc26 , esto incluye todos los enfoques físicos: generadores de números aleatorios de hardware , cámaras web con tapas de lentes , colectores de ruido atmosférico , incluso lámparas de lava . Todo esto implica el uso de datos calculados y almacenados fuera de la función.
Math.random()
que cambia el estado del RNG.