Closed
Description
For a while now, I've been planning to replace Rand
with some distribution (Default
in this branch) for most purposes. The two are roughly equivalent; e.g. the one-tuple (T,)
implementation boils down to:
// old Rand
impl<T: Rand> Rand for (T,) {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> (T,) {
(rng.gen(),)
}
}
// new Disrtibution (`Default` name may change)
impl<T> Distribution<(T,)> for Default where Default: Distribution<T> {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> (T,) {
(rng.gen(),)
}
}
Why, you ask?
- Type-specific value generation now all comes under the
Distribution
trait, giving more uniform usage (rng.sample(Default)
orrng.sample(Range::new(2, 11))
) and making generic code easier Rand::rand
does not support dynamic dispatch due to implicitSized
constraint; fixing this would break allRand
implementations, so we have no reason not to introduce a replacement
But, then, what about people using code like let v: (u32, u64) = Rand::rand(rng)
?
This is what this issue is about; we could:
- Remove
Rand
completely, forcing users to update (not that hard in many cases;rng.gen()
will still work) - Introduce a wrapper trait; this eliminates breakage for users (and in some cases even implementations of
Rand
), but leaves duplicate functionality - Introduce the above wrapper, with deprecation warnings, and remove before 1.0
Is the last option the best?
There is also rand_derive
; we can probably introduce an alternative based on Distribution
, but I don't know if we should? Apparently rand_derive
has no dependent crates.