SE-0202: Random Unification

  • What is your evaluation of the proposal?

Overall, I expected (at least the beginnings of) a more full blown generic random number library along the lines of the one in the C++ standard library, which Dave Abrahams suggested should be looked at for inspiration in the original discussion thread. Assuming it's OK to quote that post here:

/.../ I think the discussion seems way too narrow, focusing on spelling rather than on functionality and composability. I consider the “generic random number library” design to be a mostly-solved problem, in the C++ standard library (Pseudo-random number generation - cppreference.com). Whatever goes into the Swift standard library does not need to have all those features right away, but should support being extended into something having the same general shape. IMO the right design strategy is to implement and use a Swift version of C++’s facilities and only then consider proposing [perhaps a subset of] that design for standardization in Swift.

I would like the proposal to show some more of that functionality, composability and extendability.

For example, I didn't see anything in the proposal about how support for distributions other than uniform (normal, gaussian, etc.) would fit into the API.

Also, even though it might be just an implementation detail, I noticed that the implementation uses the following method for converting a random bit pattern into a floating point value in the (half open) unit range [0, 1):

let unitRandom = Self.init(
    sign: .plus,
    exponentBitPattern: (1 as Self).exponentBitPattern,
    significandBitPattern: rand
) - 1

This will produce only half of the numbers that can actually be generated from the random bit pattern, because the lowest bit in the significand will always be zero. The following method (here only for Double) does not have this problem:

init(unitRange bitPattern: UInt64) {
    let shifts = UInt64(11) // Would be eg 7 for Float, obviously it would be calculated from static properties of the type.
    self = Double(bitPattern &>> shifts) * (Double.ulpOfOne / 2)
}

You can read more about these two ways of doing this conversion here (search the page for "Generating uniform doubles in the unit interval")

Note that range conversions like these could be factored out as a set of numeric range conversion methods/initializers that would be useful on their own. In this particular case it's range conversion from the full range of UInt64 to the unit range of a floating point type, but it can also be for converting between the full range of any two fixed width integer types (which can be useful for eg doing bit depth conversion).


  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes


  • Does this proposal fit well with the feel and direction of Swift?

See below.


  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I'd like Swift's Random API to (at least eventually) be more like a Swifty version of C++'s random number library, and I'm not sure if the current proposal would bring us closer or further away from something like that.


  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Followed the original thread, quick reading of the proposal and the current implementation.

6 Likes