The `Random` package provides basic support for **predictable**
pseudo-random number generation, as needed by video games and
stochastic model checking.

This is not a package for writing things that rely on unpredictable
randomness for security. And things in this package will likely be
moved around and renamed as a result, before the stable release happens.

# Predictable randomness

The [type:random] type provides the entry-point for predictable
random number generation. All random number generators spawned
from this type follow the [trait:predictable-rng] trait, but the
only concrete implementation is currently on the [type:xor-shift]
type.

Random number generators are **immutable** by default. That is,
calling methods on them does not _change_ the state of the generator,
but rather returns a [type:random-next] value with a new generator to use.
This leads to a pattern of usage that looks like the following:

    let Random1 = #random with-seed: 123456;
    let Result1 = Random1 between: 1 and: 10;
    let N1 = Result1 value;

    let Result2 = Result1 random between: 1 and: 10;
    let N2 = Result2 value;

Note how it's necessary to use the [command:_ value] command to extract
the actual integer generated by the random number generator. And in order
to get a new result out of it, we have to use the [command:_ random] command
on the value we get back. If we had just used `Random1` to get generate
the second integer we'd get the same number as before—over and over
again—because we would run the generator with the same state.

## Mutable generators

As a convenience, mutable generators are provided in the [type:mutable-random].
This can be constructed by using the [command:_ mutable] on any immutable
random number generator. And the way it works is by wrapping the given
generator in a type that keeps state with a mutable [type:cell], so every
time a command is used, the internal state is updated accordingly, affecting
future generations of the value.

With mutable generators, the previous example can be written as:

    let Random = #random with-seed: 123456 | mutable;
    let N1 = Random between: 1 and: 10;
    let N2 = Random between: 1 and: 10;

"Much easier!", you exclaim. And indeed! However, care needs to be taken
here—if this mutable generator is shared with other pieces of code, then
it can be _changed_ in ways that you did not expect, leading to a random
number generator that is **unpredictable**. You generally want to avoid
this in simulations and games.

## Scoped, shared generators

Finally, this package also allows one to share mutable generators within
a dynamic scope—that is, instead of passing the generators around as
arguments to commands, you can share it once and access it everywhere
within the code block it's shared with.

Because this risks the same unpredictable problems as before, but in
an even greater scale, this package gates this power through two
capabilities:

- [capability:update-shared-instance] allows one to override the
  current scoped random generator (including changing its implementation!).

- [capability:read-shared-instance] allows one to access the current
  scoped random generator, and mutate it as a result of requesting new
  random numbers.

Shared generators are safer than passing mutable generators around
if you need to pass the generators to pieces of code that you don't
control, but these capabilities are best left granted **only** to your
application, unless you have a really good reason to grant it to
another package.

Using the shared generators looks like this:

    let Starting-random = #random with-seed: 123456;

    scoped-random with-source: Starting-random do: {
      let Random = shared-random instance;
      let N1 = Random between: 1 and: 10;
      let N2 = Random between: 1 and: 10;
    };
