Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prior art: API design #13

Open
curiousleo opened this issue Feb 28, 2020 · 1 comment
Open

Prior art: API design #13

curiousleo opened this issue Feb 28, 2020 · 1 comment

Comments

@curiousleo
Copy link
Collaborator

curiousleo commented Feb 28, 2020

Prior art in "standard" libraries

Go

Golang has two APIs, one for non-crypto PRNGs and one for cryptographically random bytes:

Rust

Rust has a family of packages for PRNGs. The basic interfaces are defined in rand_core.

C++

The C++ standard defines a set of highly templated classes which together form the PRNG API.

O'Neill makes the point that this API is flexible, but hard to use correctly, and proposes an alternative interface. IMO it's a nice API that provides safe defaults but is still very flexible for those who want flexibility.

numpy.random

Inspired by O'Neill.

Prior art in Haskell libraries

splitmix

Pure, splittable SplitMix implementation.

mwc-random

Provides a monadic generator interface for Marsaglia's MWC256 (a.k.a. MWC8222) multiply-with-carry generator, a way to access system randomness, and a way to draw from a number of random distributions. Does not provide a way to split/spawn generators or seeds.

random-source

Defines the MonadRandom typeclass, an interface for random number generation. One aim of our effort here should be to make random-source unnecessary (see #4 (comment)).

random-fu

Provides a way to draw from a number of random distributions. The randomness source is pluggable AFAICT.

tf-random

Implements a splittable PRNG implementing the old random's RandomGen, provides alternative interfaces, and a way to access system randomness. Based on ThreeFish.

More prior art

Common concepts

The API split between randomness sources and random distributions is apparent in every API I looked at:

Note that drawing from a distribution is what random-fu exists for in the Haskell world. I believe it is worth understanding if and what changes would be required to make random-fu work with the new random. Apart from that, it seems to cover the issue of drawing from a distribution well, so we can concentrate on building a solid API for randomness sources and seeding here.

Seeding

Seeding is handled a bit differently from API to API.

  • Rust's rand has the SeedableRng trait, whose associated Seed type must be convertible to byte slices.
    RNGs can be seeded directly, from an integer value (which is mixed to increase entropy), or from another RNG (which appropriate warnings in the docs).
  • C++ has random_device to get randomness from the system and seed_seq to generate good seeds from low-entropy inputs, which can be used to instantiate randum number "engines" like the Mersenne Twister.
  • numpy works similarly to C++, where the relevant class is called SeedSequence, but with a nicer API and fewer footguns.
  • Go has the Rand.Seed function.
@idontgetoutmuch
Copy link
Owner

An interesting discussion JuliaLang/julia#27614 not too dissimilar to the one we've been having.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants