# Notes from meeting with Amanieu and Josh
```rust
trait Distribution<T> {
fn sample<R: RandomSource>(&self, random_source: &mut R) -> T;
}
impl Distribution<T> for RangeFull {}
```
- slice shuffle/choose
- DefaultRandomSource secure?
- Performance of DefaultRandomSource? Should it be making syscalls?
- RandomSource is infallible. Fallible rand should be discussed separately.
-----
Response for tracking issue:
The library team (represented by myself and @joshtriplett) had a productive meeting with @dhardy (rand maintainer) and @traviscross (Rust project member and security expert), to talk through what this interface should be. @dhardy and I further discussed the idea of a `Distribution` trait and how to do random generation for arbitrary types.
In that meeting, we had folks wanting infallible random number generation, and folks wanting a lower-level fallible function that does not panic. For that lower-level function, it also seemed like there was a desire to handle the case where that function might block (effectively, that it's somewhat async).
The discussion about generating random values of specific types mirrored that on the thread, and came to the conclusion that we don't want the default `Random`/`random` interface to be one that generates random full-range values; we agreed that that would likely lead people to do things like `random() % 6` and get incorrect distributions.
Summarizing where we landed:
- `RandomSource` should be infallible, to handle the common cases well, and to avoid having people write code paths that don't get tested.
- We talked about that some random sources may want to generate a `u32` or `u64` at a time, for efficiency. We didn't get confirmation on whether it would be sufficient to have them use `fill_bytes` and generate 4 or 8 bytes at a time.
- We didn't reach a consensus on adopting a fallible, or non-blocking, random number generator interface (e.g. a low-level `getrandom`). If people need fallible random number generators, or need to be non-blocking, that interface would need further design. People could use interfaces from the crate ecosystem for this, in the interim.
- We didn't reach a consensus on the exact properties that `DefaultRandomSource` should have; that would take some further discussion.
- Should it be as secure as possible to the point of invoking a syscall (on some targets) every time it is called?
- Should it use a thread-local CSPRNG?
- Should we be providing multiple random sources with different properties?
Based on this discussion, we're going to propose the following:
- We'd like to separate proposals for a low-level fallible operation (e.g. `getrandom` or similar) into a separate issue. That proposal will need a libs-api ACP to get approved, and isn't covered by the existing ACP.
- For now, we'd like to continue with `fill_bytes` and have random sources that want to generate a `u32` or `u64` at a time do so via that interface. We should define `fill_bytes` such that calling fill_bytes multiple times is *not* equivalent to calling it once with a larger buffer, and is not guaranteed to give the same results even for a seeded random source.
- We'd like to rip out the `Random` trait and corresponding `random` function, and replace it with something based on a `trait Distribution<T>`. This would let people make calls like `random(1..=6)`, and allows for future expansion to non-uniform distributions, as well as floating-point.