Move contributing and updating guides and policy to the book

This commit is contained in:
Diggory Hardy 2018-11-08 18:12:01 +00:00
parent 8440f4f17b
commit 90e5c2c9a2
5 changed files with 34 additions and 568 deletions

View file

@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md).
You may also find the [Update Guide](UPDATING.md) useful.
You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.html) useful.
## [0.6.0] - Unreleased
@ -14,6 +14,8 @@ You may also find the [Update Guide](UPDATING.md) useful.
### Project organisation
- Rand has moved from [rust-lang-nursery](https://github.com/rust-lang-nursery/rand)
to [rust-random](https://github.com/rust-random/rand)! (#578)
- Created [The Rust Random Book](https://rust-random.github.io/book/)
([source](https://github.com/rust-random/book))
- Update copyright and licence notices (#591, #611)
- Migrate policy documentation from the wiki (#544)

View file

@ -1,93 +0,0 @@
# Contributing to Rand
Thank you for your interest in contributing to Rand!
The following is a list of notes and tips for when you want to contribute to
Rand with a pull request.
If you want to make major changes, it is usually best to open an issue to
discuss the idea first.
Rand doesn't (yet) use rustfmt. It is best to follow the style of the
surrounding code, and try to keep an 80 character line limit.
## Documentation
We especially welcome documentation PRs.
As of Rust 1.25 there are differences in how stable and nightly render
documentation links. Make sure it works on stable, then nightly should be good
too. One Travis CI build checks for dead links using `cargo-deadlinks`. If you
want to run the check locally:
```sh
cargo install cargo-deadlinks
# It is recommended to remove left-over files from previous compilations
rm -rf /target/doc
cargo doc --no-deps
cargo deadlinks --dir target/doc
```
When making changes to code examples in the documentation, make sure they build
with:
```sh
cargo test --doc
```
A helpful command to rebuild documentation automatically on save (only works on
Linux):
```
while inotifywait -r -e close_write src/ rand_core/; do cargo doc; done
```
## Testing
Rand already contains a number of unit tests, but could use more. Also the
existing ones could use clean-up. Any work on the tests is appreciated.
Not every change or new bit of functionality requires tests, but if you can
think of a test that adds value, please add it.
Depending on the code you change, test with one of:
```sh
cargo test
cargo test --package rand_core
# Test log, serde and 128-bit support
cargo test --features serde1,log,nightly
```
We want to be able to not only run the unit tests with `std` available, but also
without. Because `thread_rng()` and `FromEntropy` are not available without the
`std` feature, you may have to disable a new test with `#[cfg(feature="std")]`.
In other cases using `::test::rng` with a constant seed is a good option:
```rust
let mut rng = ::test::rng(528); // just pick some number
```
Only the unit tests should work in `no_std` mode, we don't want to complicate
the doc-tests. Run the tests with:
```sh
# Test no_std support
cargo test --lib --no-default-features
cargo test --package rand_core --no-default-features
# Test no_std+alloc support; requires nightly
cargo test --lib --no-default-features --features alloc
```
## Benchmarking
A lot of code in Rand is performance-sensitive, most of it is expected to be
used in hot loops in some libraries/applications. If you change code in the
`rngs`, `prngs` or `distributions` modules, especially when you see an 'obvious
cleanup', make sure the benchmarks do not regress. It is nice to report the
benchmark results in the PR (or to report nothing's changed).
```sh
# Benchmarks (requires nightly)
cargo bench
# Potentially nightly features allow different code paths
cargo bench --features=nightly
```

View file

@ -13,13 +13,14 @@ Rand provides utilities to generate random numbers, to convert them to useful
types and distributions, and some randomness-related algorithms.
The core random number generation traits of Rand live in the [rand_core](
https://crates.io/crates/rand_core) crate; this crate is most useful when
implementing RNGs.
https://crates.io/crates/rand_core) crate but are also exposed here; RNG
implementations should prefer to use `rand_core` while most other users should
depend on `rand`.
Documentation:
- [API reference for latest release](https://docs.rs/rand/0.5)
- [API reference for master branch](https://rust-random.github.io/rand/rand/index.html)
- [Additional documentation (subdir)](doc/README.md)
- [The Rust Rand Book](https://rust-random.github.io/book/)
- [API reference for the latest release](https://docs.rs/rand/)
- [API reference for the master branch](https://rust-random.github.io/rand/)
## Usage
@ -28,78 +29,34 @@ Add this to your `Cargo.toml`:
```toml
[dependencies]
rand = "0.5"
rand = "0.6"
```
and this to your crate root:
```rust
extern crate rand;
use rand::prelude::*;
fn main() {
// basic usage with random():
let x: u8 = random();
println!("{}", x);
let y = random::<f64>();
println!("{}", y);
if random() { // generates a boolean
println!("Heads!");
}
// normal usage needs both an RNG and a function to generate the appropriate
// type, range, distribution, etc.
let mut rng = thread_rng();
if rng.gen() { // random bool
let x: f64 = rng.gen(); // random number in range [0, 1)
println!("x is: {}", x);
let ch = rng.gen::<char>(); // Sometimes you need type annotation
println!("char is: {}", ch);
println!("Number from 0 to 9: {}", rng.gen_range(0, 10));
}
}
```
## Functionality
The Rand crate provides:
- A convenient to use default RNG, `thread_rng`: an automatically seeded,
crypto-grade generator stored in thread-local memory.
- Pseudo-random number generators: `StdRng`, `SmallRng`, `prng` module.
- Functionality for seeding PRNGs: the `FromEntropy` trait, and as sources of
external randomness `EntropyRng`, `OsRng` and `JitterRng`.
- Most content from [`rand_core`](https://crates.io/crates/rand_core)
(re-exported): base random number generator traits and error-reporting types.
- 'Distributions' producing many different types of random values:
- A `Standard` distribution for integers, floats, and derived types including
tuples, arrays and `Option`
- Unbiased sampling from specified `Uniform` ranges.
- Sampling from exponential/normal/gamma distributions.
- Sampling from binomial/poisson distributions.
- `gen_bool` aka Bernoulli distribution.
- `seq`-uence related functionality:
- Sampling a subset of elements.
- Randomly shuffling a list.
To get started using Rand, see [The Book](https://rust-random.github.io/book/).
## Versions
Version 0.5 is the latest version and contains many breaking changes.
See [the Upgrade Guide](UPDATING.md) for guidance on updating from previous
versions.
The Rand lib is not yet stable, however we are careful to limit breaking changes
and warn via deprecation wherever possible. Patch versions never introduce
breaking changes. The following minor versions are supported:
Version 0.4 was released in December 2017. It contains almost no breaking
changes since the 0.3 series.
- Version 0.6 was released in November 2018, redesigning the `seq` module,
moving most PRNGs to external crates, and many small changes.
- Version 0.5 was released in May 2018, as a major reorganisation
(introducing `RngCore` and `rand_core`, and deprecating `Rand` and the
previous distribution traits).
- Version 0.4 was released in December 2017, but contained almost no breaking
changes from the 0.3 series.
For more details, see the [changelog](CHANGELOG.md).
A detailed [changelog](CHANGELOG.md) is available.
When upgrading to the next minor series (especially 0.4 → 0.5), we recommend
reading the [Upgrade Guide](https://rust-random.github.io/book/update.html).
### Rust version requirements
The 0.5 release of Rand requires **Rustc version 1.22 or greater**.
The since version 0.5, Rand requires **Rustc version 1.22 or greater**.
Rand 0.4 and 0.3 (since approx. June 2017) require Rustc version 1.15 or
greater. Subsets of the Rand code may work with older Rust versions, but this
is not supported.
@ -108,6 +65,11 @@ Travis CI always has a build with a pinned version of Rustc matching the oldest
supported Rust release. The current policy is that this can be updated in any
Rand release if required, but the change must be noted in the changelog.
To avoid bumping the required version unnecessarily, we use a `build.rs` script
to auto-detect the compiler version and enable certain features or change code
paths automatically. Since this makes it easy to unintentionally make use of
features requiring a more recent Rust version, we recommend testing with a
pinned version of Rustc if you require compatibility with a specific version.
## Crate Features
@ -137,9 +99,10 @@ functionality depending on `std`:
- Since no external entropy is available, it is not possible to create
generators with fresh seeds using the `FromEntropy` trait (user must provide
a seed).
- Exponential, normal and gamma type distributions are unavailable since `exp`
- Several non-linear distributions distributions are unavailable since `exp`
and `log` functions are not provided in `core`.
- The `seq`-uence module is unavailable, as it requires `Vec`.
- Large parts of the `seq`-uence module are unavailable, unless the `alloc`
feature is used (several APIs and many implementations require `Vec`).
# License

View file

@ -1,260 +0,0 @@
# Update Guide
This guide gives a few more details than the [changelog], in particular giving
guidance on how to use new features and migrate away from old ones.
[changelog]: CHANGELOG.md
## Rand 0.5
The 0.5 release has quite significant changes over the 0.4 release; as such,
it may be worth reading through the following coverage of breaking changes.
This release also contains many optimisations, which are not detailed below.
### Crates
We have a new crate: `rand_core`! This crate houses some important traits,
`RngCore`, `BlockRngCore`, `SeedableRng` and `CryptoRng`, the error types, as
well as two modules with helpers for implementations: `le` and `impls`. It is
recommended that implementations of generators use the `rand_core` crate while
other users use only the `rand` crate, which re-exports most parts of `rand_core`.
The `rand_derive` crate has been deprecated due to very low usage and
deprecation of `Rand`.
### Features
Several new Cargo feature flags have been added:
- `alloc`, used without `std`, allows use of `Box` and `Vec`
- `serde1` adds serialization support to some PRNGs
- `log` adds logging in a few places (primarily to `OsRng` and `JitterRng`)
### `Rng` and friends (core traits)
`Rng` trait has been split into two traits, a "back end" `RngCore` (implemented
by generators) and a "front end" `Rng` implementing all the convenient extension
methods.
Implementations of generators must `impl RngCore` instead. Usage of `rand_core`
for implementations is encouraged; the `rand_core::{le, impls}` modules may
prove useful.
Users of `Rng` *who don't need to implement it* won't need to make so many
changes; often users can forget about `RngCore` and only import `Rng`. Instead
of `RngCore::next_u32()` / `next_u64()` users should prefer `Rng::gen()`, and
instead of `RngCore::fill_bytes(dest)`, `Rng::fill(dest)` can be used.
#### `Rng` / `RngCore` methods
To allow error handling from fallible sources (e.g. `OsRng`), a new
`RngCore::try_fill_bytes` method has been added; for example `EntropyRng` uses
this mechanism to fall back to `JitterRng` if `OsRng` fails, and various
handlers produce better error messages.
As before, the other methods will panic on failure, but since these are usually
used with algorithmic generators which are usually infallible, this is
considered an appropriate compromise.
A few methods from the old `Rng` have been removed or deprecated:
- `next_f32` and `next_f64`; these are no longer implementable by generators;
use `gen` instead
- `gen_iter`; users may instead use standard iterators with closures:
`::std::iter::repeat(()).map(|()| rng.gen())`
- `gen_ascii_chars`; use `repeat` as above and `rng.sample(Alphanumeric)`
- `gen_weighted_bool(n)`; use `gen_bool(1.0 / n)` instead
`Rng` has a few new methods:
- `sample(distr)` is a shortcut for `distr.sample(rng)` for any `Distribution`
- `gen_bool(p)` generates a boolean with probability `p` of being true
- `fill` and `try_fill`, corresponding to `fill_bytes` and `try_fill_bytes`
respectively (i.e. the only difference is error handling); these can fill
and integer slice / array directly, and provide better performance
than `gen()`
#### Constructing PRNGs
##### New randomly-initialised PRNGs
A new trait has been added: `FromEntropy`. This is automatically implemented for
any type supporting `SeedableRng`, and provides construction from fresh, strong
entropy:
```rust
use rand::{ChaChaRng, FromEntropy};
let mut rng = ChaChaRng::from_entropy();
```
##### Seeding PRNGs
The `SeedableRng` trait has been modified to include the seed type via an
associated type (`SeedableRng::Seed`) instead of a template parameter
(`SeedableRng<Seed>`). Additionally, all PRNGs now seed from a byte-array
(`[u8; N]` for some fixed N). This allows generic handling of PRNG seeding
which was not previously possible.
PRNGs are no longer constructed from other PRNGs via `Rand` support / `gen()`,
but through `SeedableRng::from_rng`, which allows error handling and is
intentionally explicit.
`SeedableRng::reseed` has been removed since it has no utility over `from_seed`
and its performance advantage is questionable.
Implementations of `SeedableRng` may need to change their `Seed` type to a
byte-array; this restriction has been made to ensure portable handling of
Endianness. Helper functions are available in `rand_core::le` to read `u32` and
`u64` values from byte arrays.
#### Block-based PRNGs
rand_core has a new helper trait, `BlockRngCore`, and implementation,
`BlockRng`. These are for use by generators which generate a block of random
data at a time instead of word-sized values. Using this trait and implementation
has two advantages: optimised `RngCore` methods are provided, and the PRNG can
be used with `ReseedingRng` with very low overhead.
#### Cryptographic RNGs
A new trait has been added: `CryptoRng`. This is purely a marker trait to
indicate which generators should be suitable for cryptography, e.g.
`fn foo<R: Rng + CryptoRng>(rng: &mut R)`. *Suitability for cryptographic
use cannot be guaranteed.*
### Error handling
A new `Error` type has been added, designed explicitly for no-std compatibility,
simplicity, and enough flexibility for our uses (carrying a `cause` when
possible):
```rust
pub struct Error {
pub kind: ErrorKind,
pub msg: &'static str,
// some fields omitted
}
```
The associated `ErrorKind` allows broad classification of errors into permanent,
unexpected, transient and not-yet-ready kinds.
The following use the new error type:
- `RngCore::try_fill_bytes`
- `Rng::try_fill`
- `OsRng::new`
- `JitterRng::new`
### External generators
We have a new generator, `EntropyRng`, which wraps `OsRng` and `JitterRng`
(preferring to use the former, but falling back to the latter if necessary).
This allows easy construction with fallback via `SeedableRng::from_rng`,
e.g. `IsaacRng::from_rng(EntropyRng::new())?`. This is equivalent to using
`FromEntropy` except for error handling.
It is recommended to use `EntropyRng` over `OsRng` to avoid errors on platforms
with broken system generator, but it should be noted that the `JitterRng`
fallback is very slow.
### PRNGs
*Pseudo-Random Number Generators* (i.e. deterministic algorithmic generators)
have had a few changes since 0.4, and are now housed in the `prng` module
(old names remain temporarily available for compatibility; eventually these
generators will likely be housed outside the `rand` crate).
All PRNGs now do not implement `Copy` to prevent accidental copying of the
generator's state (and thus repetitions of generated values). Explicit cloning
via `Clone` is still available. All PRNGs now have a custom implementation of
`Debug` which does not print any internal state; this helps avoid accidentally
leaking cryptographic generator state in log files. External PRNG
implementations are advised to follow this pattern (see also doc on `RngCore`).
`SmallRng` has been added as a wrapper, currently around `XorShiftRng` (but
likely another algorithm soon). This is for uses where small state and fast
initialisation are important but cryptographic strength is not required.
(Actual performance of generation varies by benchmark; dependending on usage
this may or may not be the fastest algorithm, but will always be fast.)
#### `ReseedingRng`
The `ReseedingRng` wrapper has been signficantly altered to reduce overhead.
Unfortunately the new `ReseedingRng` is not compatible with all RNGs, but only
those using `BlockRngCore`.
#### ISAAC PRNGs
The `IsaacRng` and `Isaac64Rng` PRNGs now have an additional construction
method: `new_from_u64(seed)`. 64 bits of state is insufficient for cryptography
but may be of use in simulations and games. This will likely be superceeded by
a method to construct any PRNG from any hashable object in the future.
#### HC-128
This is a new cryptographic generator, selected as one of the "stream ciphers
suitable for widespread adoption" by eSTREAM. This is now the default
cryptographic generator, used by `StdRng` and `thread_rng()`.
### Helper functions/traits
The `Rand` trait has been deprecated. Instead, users are encouraged to use
`Standard` which is a real distribution and supports the same sampling as
`Rand`. `Rng::gen()` now uses `Standard` and should work exactly as before.
See the documentation of the `distributions` module on how to implement
`Distribution<T>` for `Standard` for user types `T`
`weak_rng()` has been deprecated; use `SmallRng::from_entropy()` instead.
### Distributions
The `Sample` and `IndependentSample` traits have been replaced by a single
trait, `Distribution`. This is largely equivalent to `IndependentSample`, but
with `ind_sample` replaced by just `sample`. Support for mutable distributions
has been dropped; although it appears there may be a few genuine uses, these
are not used widely enough to justify the existance of two independent traits
or of having to provide mutable access to a distribution object. Both `Sample`
and `IndependentSample` are still available, but deprecated; they will be
removed in a future release.
`Distribution::sample` (as well as several other functions) can now be called
directly on type-erased (unsized) RNGs.
`RandSample` has been removed (see `Rand` deprecation and new `Standard`
distribution).
The `Closed01` wrapper has been removed, but `OpenClosed01` has been added.
#### Uniform distributions
Two new distributions are available:
- `Standard` produces uniformly-distributed samples for many different types,
and acts as a replacement for `Rand`
- `Alphanumeric` samples `char`s from the ranges `a-z A-Z 0-9`
##### Ranges
The `Range` distribution has been heavily adapted, and renamed to `Uniform`:
- `Uniform::new(low, high)` remains (half open `[low, high)`)
- `Uniform::new_inclusive(low, high)` has been added, including `high` in the sample range
- `Uniform::sample_single(low, high, rng)` is a faster variant for single usage sampling from `[low, high)`
`Uniform` can now be implemented for user-defined types; see the `uniform` module.
#### Non-uniform distributions
Two distributions have been added:
- Poisson, modelling the number of events expected from a constant-rate
source within a fixed time interval (e.g. nuclear decay)
- Binomial, modelling the outcome of a fixed number of yes-no trials
The sampling methods are based on those in "Numerical Recipes in C".
##### Exponential and Normal distributions
The main `Exp` and `Normal` distributions are unchanged, however the
"standard" versions, `Exp1` and `StandardNormal` are no longer wrapper types,
but full distributions. Instead of writing `let Exp1(x) = rng.gen();` you now
write `let x = rng.sample(Exp1);`.

View file

@ -1,146 +0,0 @@
# Rand Documentation
Also see the [main project readme](../README.md).
## Learning Rand
TODO. In the mean-time, we have some learning resources within the API
documentation.
The following example programs may be of interest:
- [examples/monte-carlo.rs](https://github.com/rust-random/rand/blob/master/examples/monte-carlo.rs)
- [examples/monty-hall.rs](https://github.com/rust-random/rand/blob/master/examples/monty-hall.rs)
## References
API documentation can be found:
- [`rand` API on docs.rs](https://docs.rs/rand/)
- [`rand_core` API on docs.rs](https://docs.rs/rand_core/)
- [self-published API on github.io](https://rust-random.github.io/rand/rand/index.html) (latest code in master branch)
- by running `cargo doc --no-deps --all --all-features`
## Project policies
### Open Participation
This project is open to contributions from anyone, with the main criteria of
review being correctness, utility, project scope, and good documentation. Where
correctness is less obvious (PRNGs and some type-conversion algorithms),
additional criteria apply (see below).
Additionally we welcome feedback in the form of bug reports, feature requests
(preferably with motivation and consideration for the scope of the project),
code reviews, and input on current topics of discussion.
Since we must sometimes reject new features in order to limit the project's
scope, you may wish to ask first before writing a new feature.
### Stability and Portability
We try to follow [semver rules](https://docs.npmjs.com/misc/semver) regarding
API-breaking changes and `MAJOR.MINOR.PATCH` versions:
- New *patch* versions should not include API-breaking changes or major new
features
- Before 1.0, *minor* versions may include API breaking changes. After 1.0
they should not.
- We may make pre-releases like `0.5.0-pre.0`. In this case:
- although these are public versions, they are not used by default unless
opting into using a pre-release on the specific `MAJOR.MINOR.PATCH`
version
- pre-releases are considered semantically less than their final release
(e.g. Cargo may automatically upgrade from `0.5.0-pre.0` to `0.5.0`)
- all pre-release versions are unstable and may make any change
- we make no commitment to support users of pre-releases
Additionally, we must also consider *value-breaking changes* and *portability*.
A function is *value-stable* if, given the same inputs:
- it is portable (produces the same results on all platforms)
- changing the output value for some input in a new library version is
considered a breaking change
Note that some Rand functionality is supposed to be value stable, and some
functionality is supposed to be non-deterministic (i.e. depend on something
external). Some functionality may be deterministic but not value-stable.
A trait should define which of its functions are expected to be value-stable.
An implementation of a trait must meet those stability requirements, unless the
object for which the trait is implemented is explicitly not value-stable.
As an example, `SeedableRng::from_seed` is required to be value-stable, but
`SeedableRng::from_rng` is not. RNGs implementing the trait are value-stable
when they guarantee `SeedableRng::from_seed` is value-stable, while
`SeedableRng::from_rng` may receive optimisations.
Before 1.0, we allow any new *minor* version to break value-stability, though
we do expect such changes to be mentioned in the changelog. Post 1.0 we have
not yet determined exact stability rules.
Additionally, we expect patch versions not to change the output of any
deterministic functions, even if not value-stable (this is not a hard
requirement, but exceptions should be noted in the changelog).
Defining which parts of Rand are value-stable is still in progress. Many parts
of `rand_core` have some documentation on value-stability.
### Project Scope
The `rand_core` library has the following scope:
- the core traits which RNGs may implement
- tools for implementing these traits
The `rand` library has the following scope:
- re-export all parts of `rand_core` applicable to end users
- an interface to request entropy from an external source
- hooks to provide entropy from several platform-specific sources
- traits covering common RNG functionality
- some PRNGs, notably `StdRng` and `SmallRng`
- `thread_rng` auto-seeding source of randomness
- conversion of random bits to common types and uses
- shuffling and sampling from sequences
- sampling from various random number distributions
Note: the scope of the project and above libraries may change. We are currently
discussing moving PRNGs (#431) and distributions (#290) to other libraries or
projects.
### Code style
We do not currently have many policies on style other than:
- neat and consistent
- minimise changes which are purely stylistic, or move to a separate commit
Rand does **make use of `unsafe`**, both for performance and out of necessity.
We consider this acceptable so long as correctness is easy to verify.
In order to make this as simple as possible,
we prefer that all parameters affecting safety of `unsafe` blocks are checked or
prepared close to the `unsafe` code,
and wherever possible within the same function (thus making the function safe).
### New PRNG Algorithms
The Rand library includes several pseudo-random number generators, and we have
received several requests to adopt new algorithms into the library. We must
consider such requests in regards to several things:
- whether the PRNG is cryptographically secure, and if so, how trustworthy
such claims are
- statistical quality of output
- performance and features of the generator
- scope of the project
- reception and third-party review of the algorithm
In general, we expect the following, though we may make exceptions:
- the author of the algorithm to publish an article of some type (e.g.
a scientific article or web page) introducing the new algorithm and
discussing its utility, strengths and weaknesses
- review of statistical quality and any special features by third parties
- good performance in automated test suites like PractRand and TestU01
(unless for some reason this is not expected, e.g. a mock generator)