Skip to content

Commit 56fbee5

Browse files
authored
Merge pull request #324 from dhardy/updating
Add update guide
2 parents 69bfe59 + cb8e418 commit 56fbee5

File tree

2 files changed

+274
-0
lines changed

2 files changed

+274
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
A [separate changelog is kept for rand-core](rand-core/CHANGELOG.md).
8+
9+
You may also find the [Update Guide](UPDATING.md) useful.
10+
711

812
## [0.5.0] - Unreleased
913

UPDATING.md

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
# Update Guide
2+
3+
This guide gives a few more details than the [changelog], in particular giving
4+
guidance on how to use new features and migrate away from old ones.
5+
6+
[changelog]: CHANGELOG.md
7+
8+
## Rand 0.5
9+
10+
The 0.5 release has quite significant changes over the 0.4 release; as such,
11+
it may be worth reading through the following coverage of breaking changes.
12+
This release also contains many optimisations, which are not detailed below.
13+
14+
### Crates
15+
16+
We have a new crate: `rand-core`! This crate houses some important traits,
17+
`RngCore`, `BlockRngCore`, `SeedableRng` and `CryptoRng`, the error types, as
18+
well as two modules with helpers for implementations: `le` and `impls`. It is
19+
recommended that implementations of generators use the `rand-core` trait while
20+
other users use only the `rand` crate, which re-exports most parts of `rand-core`.
21+
22+
The `rand_derive` crate has been deprecated due to very low usage and
23+
deprecation of `Rand`.
24+
25+
### Features
26+
27+
Several new Cargo feature flags have been added:
28+
29+
- `alloc`, used without `std`, allows use of `Box` and `Vec`
30+
- `serde-1` adds serialisation support to some PRNGs
31+
- `log` adds logging in a few places (primarily to `OsRng` and `JitterRng`)
32+
33+
### `Rng` and friends (core traits)
34+
35+
`Rng` trait has been split into two traits, a "back end" `RngCore` (implemented
36+
by generators) and a "front end" `Rng` implementing all the convenient extension
37+
methods.
38+
39+
Implementations of generators must `impl RngCore` instead. Usage of `rand-core`
40+
for implementations is encouraged; the `rand_core::{le, impls}` modules may
41+
prove useful.
42+
43+
Users of `Rng` *who don't need to implement it* won't need to make so many
44+
changes; often users can forget about `RngCore` and only import `Rng`. Instead
45+
of `RngCore::next_u32()` / `next_u64()` users should prefer `Rng::gen()`, and
46+
instead of `RngCore::fill_bytes(dest)`, `Rng::fill(dest)` can be used.
47+
48+
#### `Rng` / `RngCore` methods
49+
50+
To allow error handling from fallible sources (e.g. `OsRng`), a new
51+
`RngCore::try_fill_bytes` method has been added; for example `EntropyRng` uses
52+
this mechanism to fall back to `JitterRng` if `OsRng` fails, and various
53+
handlers produce better error messages.
54+
As before, the other methods will panic on failure, but since these are usually
55+
used with algorithmic generators which are usually infallible, this is
56+
considered an appropriate compromise.
57+
58+
A few methods from the old `Rng` have been removed or deprecated:
59+
60+
- `next_f32` and `next_f64`; these are no longer implementable by generators;
61+
use `gen` instead
62+
- `gen_iter`; users may instead use standard iterators with closures:
63+
`::std::iter::repeat(()).map(|()| rng.gen())`
64+
- `gen_ascii_chars`; use `repeat` as above and `rng.sample(Alphanumeric)`
65+
- `gen_weighted_bool(n)`; use `gen_bool(1.0 / n)` instead
66+
67+
`Rng` has a few new methods:
68+
69+
- `sample(distr)` is a shortcut for `distr.sample(rng)` for any `Distribution`
70+
- `gen_bool(p)` generates a boolean with probability `p` of being true
71+
- `fill` and `try_fill`, corresponding to `fill_bytes` and `try_fill_bytes`
72+
respectively (i.e. the only difference is error handling); these can fill
73+
and integer slice / array directly, and provide better performance
74+
than `gen()`
75+
76+
#### Constructing PRNGs
77+
78+
##### New randomly-initialised PRNGs
79+
80+
A new trait has been added: `NewRng`. This is automatically implemented for any
81+
type supporting `SeedableRng`, and provides construction from fresh, strong
82+
entropy:
83+
84+
```rust
85+
use rand::{ChaChaRng, NewRng};
86+
87+
let mut rng = ChaChaRng::new();
88+
```
89+
90+
##### Seeding PRNGs
91+
92+
The `SeedableRng` trait has been modified to include the seed type via an
93+
associated type (`SeedableRng::Seed`) instead of a template parameter
94+
(`SeedableRng<Seed>`). Additionally, all PRNGs now seed from a byte-array
95+
(`[u8; N]` for some fixed N). This allows generic handling of PRNG seeding
96+
which was not previously possible.
97+
98+
PRNGs are no longer constructed from other PRNGs via `Rand` support / `gen()`,
99+
but through `SeedableRng::from_rng`, which allows error handling and is
100+
intentionally explicit.
101+
102+
`SeedableRng::reseed` has been removed since it has no utility over `from_seed`
103+
and its performance advantage is questionable.
104+
105+
Implementations of `SeedableRng` may need to change their `Seed` type to a
106+
byte-array; this restriction has been made to ensure portable handling of
107+
Endianness. Helper functions are available in `rand_core::le` to read `u32` and
108+
`u64` values from byte arrays.
109+
110+
#### Block-based PRNGs
111+
112+
rand-core has a new helper trait, `BlockRngCore`, and implementation,
113+
`BlockRng`. These are for use by generators which generate a block of random
114+
data at a time instead of word-sized values. Using this trait and implementation
115+
has two advantages: optimised `RngCore` methods are provided, and the PRNG can
116+
be used with `ReseedingRng` with very low overhead.
117+
118+
#### Cryptographic RNGs
119+
120+
A new trait has been added: `CryptoRng`. This is purely a marker trait to
121+
indicate which generators should be suitable for cryptography, e.g.
122+
`fn foo<R: Rng + CryptoRng>(rng: &mut R)`. *Suitability for cryptographic
123+
use cannot be guaranteed.*
124+
125+
### Error handling
126+
127+
A new `Error` type has been added, designed explicitly for no-std compatibility,
128+
simplicity, and enough flexibility for our uses (carrying a `cause` when
129+
possible):
130+
```rust
131+
pub struct Error {
132+
pub kind: ErrorKind,
133+
pub msg: &'static str,
134+
// some fields omitted
135+
}
136+
```
137+
The associated `ErrorKind` allows broad classification of errors into permanent,
138+
unexpected, transient and not-yet-ready kinds.
139+
140+
The following use the new error type:
141+
142+
- `RngCore::try_fill_bytes`
143+
- `Rng::try_fill`
144+
- `OsRng::new`
145+
- `jitter::new`
146+
147+
### External generators
148+
149+
We have a new generator, `EntropyRng`, which wraps `OsRng` and `JitterRng`
150+
(preferring to use the former, but falling back to the latter if necessary).
151+
This allows easy construction with fallback via `SeedableRng::from_rng`,
152+
e.g. `IsaacRng::from_rng(EntropyRng::new())?`. This is equivalent to using
153+
`NewRng` except for error handling.
154+
155+
It is recommended to use `EntropyRng` over `OsRng` to avoid errors on platforms
156+
with broken system generator, but it should be noted that the `JitterRng`
157+
fallback is very slow.
158+
159+
### PRNGs
160+
161+
*Pseudo-Random Number Generators* (i.e. deterministic algorithmic generators)
162+
have had a few changes since 0.4, and are now housed in the `prng` module
163+
(old names remain temporarily available for compatibility; eventually these
164+
generators will likely be housed outside the `rand` crate).
165+
166+
All PRNGs now do not implement `Copy` to prevent accidental copying of the
167+
generator's state (and thus repetitions of generated values). Explicit cloning
168+
via `Clone` is still available. All PRNGs now have a custom implementation of
169+
`Debug` which does not print any internal state; this helps avoid accidentally
170+
leaking cryptographic generator state in log files. External PRNG
171+
implementations are advised to follow this pattern (see also doc on `RngCore`).
172+
173+
`SmallRng` has been added as a wrapper, currently around `XorShiftRng` (but
174+
likely another algorithm soon). This is for uses where small state and fast
175+
initialisation are important but cryptographic strength is not required.
176+
(Actual performance of generation varies by benchmark; dependending on usage
177+
this may or may not be the fastest algorithm, but will always be fast.)
178+
179+
#### `ReseedingRng`
180+
181+
The `ReseedingRng` wrapper has been signficantly altered to reduce overhead.
182+
Unfortunately the new `ReseedingRng` is not compatible with all RNGs, but only
183+
those using `BlockRngCore`.
184+
185+
#### ISAAC PRNGs
186+
187+
The `IsaacRng` and `Isaac64Rng` PRNGs now have an additional construction
188+
method: `new_from_u64(seed)`. 64 bits of state is insufficient for cryptography
189+
but may be of use in simulations and games. This will likely be superceeded by
190+
a method to construct any PRNG from any hashable object in the future.
191+
192+
#### HC-128
193+
194+
This is a new cryptographic generator, selected as one of the "stream ciphers
195+
suitable for widespread adoption" by eSTREAM. This is now the default
196+
cryptographic generator, used by `StdRng` and `thread_rng()`.
197+
198+
### Helper functions/traits
199+
200+
The `Rand` trait has been deprecated. Instead, users are encouraged to use
201+
`Uniform` which is a real distribution and supports the same sampling as `Rand`.
202+
`Rng::gen()` now uses `Uniform` and should work exactly as before.
203+
204+
The `random()` function has been removed; users may simply use
205+
`thread_rng().gen()` instead or may choose to cache
206+
`let mut rng = thread_rng();` locally, or even use a different generator.
207+
208+
`weak_rng()` has been deprecated; use `SmallRng::new()` instead.
209+
210+
### Distributions
211+
212+
The `Sample` and `IndependentSample` traits have been replaced by a single
213+
trait, `Distribution`. This is largely equivalent to `IndependentSample`, but
214+
with `ind_sample` replaced by just `sample`. Support for mutable distributions
215+
has been dropped; although it appears there may be a few genuine uses, these
216+
are not used widely enough to justify the existance of two independent traits
217+
or of having to provide mutable access to a distribution object. Both `Sample`
218+
and `IndependentSample` are still available, but deprecated; they will be
219+
removed in a future release.
220+
221+
`Distribution::sample` (as well as several other functions) can now be called
222+
directly on type-erased (unsized) RNGs.
223+
224+
`RandSample` has been removed (see `Rand` deprecation and new `Uniform`
225+
distribution).
226+
227+
The `Open01` and `Closed01` wrappers have been removed. `Rng::gen()` (via
228+
`Uniform`) now yields samples from `(0, 1)` for floats; i.e. the same as the old
229+
`Open01`. This is considered sufficient for most uses. If you require more
230+
precision, use the `HighPrecision01` distribution.
231+
232+
#### Uniform distributions
233+
234+
Three new distributions are available:
235+
236+
- `Uniform` produces uniformly-distributed samples for many different types,
237+
and acts as a replacement for `Rand`
238+
- `HighPrecision01` generates floating-point numbers in the range `[0, 1)`
239+
(similar to `Uniform`) but with as much precision as the floating point
240+
format can represent
241+
- `Alphanumeric` samples `char`s from the ranges `a-z A-Z 0-9`
242+
243+
##### Ranges
244+
245+
The `Range` distribution has been heavily adapted, while remaining largely
246+
backwards compatible:
247+
248+
- `Range::new(low, high)` remains (half open `[low, high)`)
249+
- `Range::new_inclusive(low, high)` has been added, including `high` in the sample range
250+
- `Range::sample_single(low, high, rng)` is a faster variant for single usage sampling from `[low, high)`
251+
252+
`Range` can now be implemented for user-defined types; see the `RangeImpl` type.
253+
`SampleRange` has been adapted to suit the new `Range` model.
254+
255+
#### Non-uniform distributions
256+
257+
Two distributions have been added:
258+
259+
- Poisson, modelling the number of events expected from a constant-rate
260+
source within a fixed time interval (e.g. nuclear decay)
261+
- Binomial, modelling the outcome of a fixed number of yes-no trials
262+
263+
The sampling methods are based on those in "Numerical Recipes in C".
264+
265+
##### Exponential and Normal distributions
266+
267+
The main `Exp` and `Normal` distributions are unchanged, however the
268+
"standard" versions, `Exp1` and `StandardNormal` are no longer wrapper types,
269+
but full distributions. Instead of writing `let Exp1(x) = rng.gen();` you now
270+
write `let x = rng.sample(Exp1);`.

0 commit comments

Comments
 (0)