La réponse simple à votre question est que cela Math.random()
enfreint la règle n ° 2.
Beaucoup d'autres réponses ici ont souligné que la présence de Math.random()
signifie que cette fonction n'est pas pure. Mais je pense que cela vaut la peine de dire pourquoi Math.random()
ternit les fonctions qui l'utilisent.
Comme tous les générateurs de nombres pseudo-aléatoires, Math.random()
commence par une valeur «de départ». Il utilise ensuite cette valeur comme point de départ pour une chaîne de manipulations de bits de bas niveau ou d'autres opérations qui aboutissent à une sortie imprévisible (mais pas vraiment aléatoire ).
En JavaScript, le processus impliqué dépend de l'implémentation et, contrairement à de nombreux autres langages, JavaScript ne permet pas de sélectionner la graine :
L'implémentation sélectionne la graine initiale de l'algorithme de génération de nombres aléatoires; il ne peut pas être choisi ou réinitialisé par l'utilisateur.
C'est pourquoi cette fonction n'est pas pure: JavaScript utilise essentiellement un paramètre de fonction implicite sur lequel vous n'avez aucun contrôle. Il lit ce paramètre à partir de données calculées et stockées ailleurs, et enfreint donc la règle n ° 2 de votre définition.
Si vous souhaitez en faire une fonction pure, vous pouvez utiliser l'un des générateurs de nombres aléatoires alternatifs décrits ici . Appelez ce générateur seedable_random
. Il prend un paramètre (la graine) et renvoie un nombre "aléatoire". Bien sûr, ce nombre n'est pas du tout aléatoire; il est uniquement déterminé par la graine. C'est pourquoi c'est une fonction pure. La sortie de seedable_random
est uniquement "aléatoire" dans le sens où la prédiction de la sortie basée sur l'entrée est difficile.
La version pure de cette fonction aurait besoin de prendre trois paramètres:
function test(min, max, seed) {
return seedable_random(seed) * (max - min) + min;
}
Pour tout triple de (min, max, seed)
paramètres donné, cela retournera toujours le même résultat.
Notez que si vous voulez que la sortie de seedable_random
soit vraiment aléatoire, vous devez trouver un moyen de randomiser la graine! Et quelle que soit la stratégie que vous utilisiez serait inévitablement non pure, car elle vous obligerait à collecter des informations auprès d'une source extérieure à votre fonction. Comme mtraceur et jpmc26 me le rappellent, cela inclut toutes les approches physiques: générateurs de nombres aléatoires matériels , webcams avec bouchons d'objectif , collecteurs de bruit atmosphérique - même lampes à lave . Tous ces éléments impliquent l'utilisation de données calculées et stockées en dehors de la fonction.
Math.random()
ce qui change l'état du RNG.