While this could work, I don’t believe this aligns with Swift. 
SecRandomCopyBytes and arc4random_buf do it this way because of the languages 
they were built in, and for SecRandomCopyBytes, it needs to also return an 
error (in the form of its return value). For custom generators this doesn’t 
make sense to me because it seems as if each generator will have the same code 
to return an integer of a different size from what it’ll be producing. I really 
like Xiaodi’s solution to explicitly state what type of integer a custom 
generator will return, and as a default implementation, we provide a way to 
transform that.

- Alejandro

On Nov 15, 2017, 11:26 AM -0600, Nate Cook <natec...@apple.com>, wrote:
On Nov 13, 2017, at 7:38 PM, Xiaodi Wu 
<xiaodi...@gmail.com<mailto:xiaodi...@gmail.com>> wrote:

On Mon, Nov 13, 2017 at 7:12 PM, Alejandro Alonso 
<aalonso...@outlook.com<mailto:aalonso...@outlook.com>> wrote:
After thinking about this for a while, I don’t agree with with an associated 
type on RandomNumberGenerator. I think a generic FixedWidthInteger & 
UnsignedInteger should be sufficient. If there were an associated type, and the 
default for Random was UInt32, then there might be some arguments about 
allowing Double to utilize the full 64 bit precision. We could make Random32 
and Random64, but I think people will ask why there isn’t a Random8 or Random16 
for those bit widths. The same could also be said that any experienced 
developer would know that his PRNG would be switched if he asked for 32 bit or 
64 bit.

I don't understand. Of course, Double would require 64 bits of randomness. It 
would obtain this by calling `next()` as many times as necessary to obtain the 
requisite number of bits.

At base, any PRNG algorithm yields some fixed number of bits on each iteration. 
You can certainly have a function that returns an arbitrary number of random 
bits (in fact, I would recommend that such an algorithm be a protocol extension 
method on RandomNumberGenerator), but it must be built on top of a function 
that returns a fixed number of bits, where that number is determined on a 
per-algorithm basis. Moreover--and this is important--generating a random 
unsigned integer of arbitrary bit width in a sound way is actually subtly 
_different_ from generating a floating-point value of a certain bit width, and 
I'm not sure that one can be built on top of the other. Compare, for example:

https://github.com/xwu/NumericAnnex/blob/c962760bf974a84ec57d8c5e94c91f06584e2453/Sources/PRNG.swift#L157
https://github.com/xwu/NumericAnnex/blob/c962760bf974a84ec57d8c5e94c91f06584e2453/Sources/PRNG.swift#L316

(These are essentially Swift versions of C++ algorithms.)

Basically, what I'm saying is that RandomNumberGenerator needs a `next()` 
method that returns a fixed number of bits, and extension methods that build on 
that to return T : FixedWidthInteger & UnsignedInteger of arbitrary bit width 
or U : BinaryFloatingPoint of an arbitrary number of bits of precision. Each 
individual RNG does not need to reimplement the latter methods, just a method 
to return a `next()` value of a fixed number of bits. You are welcome to use my 
implementation.

An alternative to this is to have the random generator write a specified number 
of bytes to a pointer’s memory, as David Waite and others have suggested. This 
is same way arc4random_buf and SecRandomCopyBytes are implemented. Each random 
number generator could then choose the most efficient way to provide the 
requested number of bytes. The protocol could look something like this:

protocol RandomNumberGenerator {
    /// Writes the specified number of bytes to the given pointer’s memory.
    func read(into p: UnsafeMutableRawPointer, bytes: Int)
}

This is less user-friendly than having a next() method, but I think that’s a 
good thing—we very much want people who need a random value to use higher-level 
APIs and just pass the RNG as a parameter when necessary.

Nate


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to