Right now, in Javascript, our main source of randomness comes from a single function: Math.random(). I'm wondering if there would be interest in adding a more full-blown random library to Javascript, and if so, what kinds of random methods should exist in this library?
Some requirements:
- It should provide easy-to-use methods for common random needs (i.e. provide a
Random.randInt(start, end)instead of having people use common and incorrect patterns we see everywhere today, such asMath.floor(Math.random() * (end - start)) + start. It's also important to provide proper implementation of random logic that's difficult to implement correctly by hand, likeRandom.shuffle(array). - It should be seed-able. i.e. something like
const myRandGen = new Random(<seed>); myRandGen.randInt(start, end)
Just to get things started, here's a handful of methods that a new Random API could include:
Random.randInt(2, 5) // Either returns 2, 3, or 4
Random.randBigInt(2n, 5n)
Random.randBool() // Either true or false
Random.randFloat(start, end) // A float where start <= x < end
Random.choice(['a', 'b', 'c']) // Reteurns a random entry from the array
Random.choice('abc') // Returns a random character
const newArray = Random.shuffle(['a', 'b', 'c'])
Random.shuffleInPlace(myArray)
const gen = new Random(<optional seed>)
gen.randInt(...) // The instance constaints all of the static methods.
const newGen = gen.clone() // Clones the pseudo-random-number generator at its current state
console.assert(gen.randBool() === newGen.randBool())
We could also provide methods to provide random values using other distributions besides a linear one. It's probably wise not to stick every possible random-related thing into this, anyone who's wanting to do deep statistical logic, or to build some game that deeply depends on random generation should probably install a more full-featured random library. The build-in API should just try and cover the most common use-cases, so people don't have to keep twiddling with floats from Math.random() to do everyday tasks.
A note on Random.shuffle()
Random.shuffle() (and Random.choice()) has been discussed previously on this form here. Over there, @claudiameadows brought up an interesting point that I was unaware of.
Shuffling's way harder than you'd think to do right - the gold standard for it requires enough bits of RNG state to hold all possible mutations in order to hit all permutations and for all but small arrays (of <= 34 entries), they can't even use what they use for
Math.random().
...
And yes, I'm saying that Python's default is actually very bad.
I think this is an argument for why the Javascript language needs a random shuffle method. Any home-grown one is likely to be implemented worse than what we can do natively in Javascript. And yes, maybe Javascript can't provide a truly random shuffle method, but we can reflect this shortcoming in the method name, so it's clear to users that the shuffle method is not perfect. For example, Random.semiRandomShuffle(array). How to actually name it can be debated, but providing a proper shuffle method with a name that indicates its shortcomings is better than not having one at all.
prior art: