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: