Why isn't there `FixedWidthInteger.random` (or at least `.random(in: ...)`)

Forgive me if this is a dumb question, but why do I always have to manually specify a full range to the random(…) static methods? Why isn't the range optional (i.e. a random static dynamic property), or at least why isn't there an overload that takes UnboundedRange_ (...)?

Maybe it's just me, but almost every time I use these APIs I always just want the full range, and having to append (in: .min ... .max) to the end is annoyingly noisy. I create my own 'convenience' overloads in my own projects, which isn't hard, but if the standard library is going to have these (very useful) APIs then why doesn't it have a complete set?

Handwaving a little bit, to avoid the attractive nuisance of Int.random % 6 // unfair dice roll

Filling in some details, if you're always using the full range, it's likely that you're generating random bit patterns (possibly for further processing of some sort), rather than random integers, in which case an API that explicitly does that might be a better fit.

6 Likes

"Nuisance" in the sense that it's not idiomatic stylistically, or that random doesn't guarantee equal randomness amongst the bits?

Assuming the latter, I know random doesn't guarantee "cryptographic"-level randomness, but still, even with a lesser PRNG I thought the biased bits problem was solved, with modern algorithms?

That said, a quick glance at Wikipedia for e.g. Xoroshiro suggests this is not the case. Bummer. I thought we'd moved past that.

I'm not sure I agree with the trade-off there, but I respect the motivation.

I haven't kept precise track of my uses, but from memory at least, it's most-often that I want random numbers for use as identifiers or similar. It's counter-productive to not use the full range of the appropriate integer type, for them.

Sometimes it's for use in tests (think fuzzers, sort of thing).

In that the full range isn’t a multiple of six, so 1 will be selected more often than 5.

6 Likes

It's not random, it's %. If Int were a three bit unsigned type, say, then Int.random would give you value between 0 and 7. Eight doesn't divide evenly by six; there are two possible values for with x % 6 == 0 or x % 6 == 1, but only one for the other possibilities, so given a perfectly uniform distribution of x values, x % 6 would still give 0 or 1 twice as often as the other possibilities. For larger powers of two, the difference isn't as drastic, but it's still there. Distributing the raw bits from a random source over a non-power-of-two sized interval requires care.

9 Likes