[swift-evolution] [Proposal] Random Unification

Xiaodi Wu xiaodi.wu at gmail.com
Fri Sep 8 19:08:58 CDT 2017

```Internally, I know that Swift has a Linux shim for arc4random. However,
it's unlikely that any modern random number generator facility in Swift
would rely on arc4random in such a way.

This topic has been broached on Swift Evolution previously. It's
interesting to me that Steve Canon is so certain that CSPRNGs are the way
to go. I wasn't aware that hardware CSPRNGs have come such a long way and
are so ubiquitous as to be feasible as a basis for Swift random numbers. If
so, great.

Otherwise, if there is any way that a software, non-cryptographically
secure PRNG is going to outperform a CSPRNG, then I think it's worthwhile
to have a (carefully documented) choice between the two. I would imagine
that for many uses, such as an animation in which you need a plausible
source of noise to render a flame, whether that is cryptographically secure
or not is absolutely irrelevant but performance may be key.

I have implemented Xorshift128+ and Xoroshiro128+ in a Swift numerics
library here:
https://github.com/xwu/NumericAnnex/tree/master/Sources

They are, of course, *non*-cryptographically secure random number generator
algorithms, but these implementations rely on the hardware for a
cryptographically secure seed. A (useless) vignette for how my classes
would be used is:

```
let random = Random()!
// Initializing a `Random` from a cryptographically secure random seed may
fail,
// since it is possible that the system may not have enough entropy. Better
to be
// alternative source of entropy.

let x = random.uniform() as Int

// You can also pass the desired result type as an argument.
let y = random.uniform(Int.self)

if x > y {
print("Here's a random value between 0 and 42 (inclusive):")
print(random.uniform(a: 0, b: 42))
} else {
print("Here's a random value between -42 and 0 (inclusive):")
print(random.uniform(a: -42, b: 0))
}
```

If you look through the design of the `PRNG` protocol, you'll see how easy
it is to implement functions that return a sequence of random values, in
some desired distribution. The overall design is inspired by the C++ STL
random number generator APIs, as well as some very cogent commentary on how
the C++ STL random number generator APIs are unnecessarily complicated. No
matter how far we simplify, though, I agree with commentators elsewhere
that it's important to allow the user to explicitly seed a PRNG; this
allows for the use of one such PRNG per thread, for example, instead of
seeding a new PRNG every time a random number is required.

On Fri, Sep 8, 2017 at 11:52 AM, Alejandro Alonso via swift-evolution <
swift-evolution at swift.org> wrote:

> Hello swift evolution, I would like to propose a unified approach to
> `random()` in Swift. I have a simple implementation here
> https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5. This
> implementation is a simple wrapper over existing random functions so
> existing code bases will not be affected. Also, this approach introduces a
> new random feature for Linux users that give them access to upper bounds,
> as well as a lower bound for both Glibc and Darwin users. This change would
> be implemented within Foundation.
>
> I believe this simple change could have a very positive impact on new
> developers learning Swift and experienced developers being able to write
> single random declarations.
>
> I’d like to hear about your ideas on this proposal, or any implementation
> changes if need be.
>
> - Alejando
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170908/cb527dc6/attachment.html>
```