Skip to content

Fate of the Rand trait #83

Closed
Closed
@dhardy

Description

@dhardy

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?

  1. Type-specific value generation now all comes under the Distribution trait, giving more uniform usage (rng.sample(Default) or rng.sample(Range::new(2, 11))) and making generic code easier
  2. Rand::rand does not support dynamic dispatch due to implicit Sized constraint; fixing this would break all Rand 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:

  1. Remove Rand completely, forcing users to update (not that hard in many cases; rng.gen() will still work)
  2. Introduce a wrapper trait; this eliminates breakage for users (and in some cases even implementations of Rand), but leaves duplicate functionality
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions