> On Nov 16, 2017, at 8:12 PM, Alejandro Alonso via swift-evolution 
> <[email protected]> wrote:
> 
> 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


The random source does not know about integers or floats or colors. It just 
provides randomness. Higher level code is what determines for instance how to 
generate (for example) a random number between 1 and 27 with equal probability 
- which could theoretically require more than a 64 bits of randomness (with 
probability of that depending on luck and the algorithm used)

A double is not a uniform distribution, so likewise simply casting a 64 bit 
integer value to a double would not yield appropriate results (you’d have a 
significant chance of NaN values, for instance)

Thats why I would recommend having the random source just be a sequence of 
bytes. The higher level API choosing random elements from a Strideable or 
shuffling an array *should* be the interfaces that developers use, rather than 
directly reading from the random source

I proposed “read” below because it is compatible with the signature on 
InputStream, which both would allow you to easily bridge /dev/random or 
/dev/urandom in as well as have predefined data as a source of randomness for 
predictable testing.

Predictable randomness and multiple sources of randomness are important in a 
few scenarios, including gaming where the same “random” choices need to be made 
locally for each player to keep the games in sync.

-DW


> 
> On Nov 15, 2017, 11:26 AM -0600, Nate Cook <[email protected]>, wrote:
>>> On Nov 13, 2017, at 7:38 PM, Xiaodi Wu <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> On Mon, Nov 13, 2017 at 7:12 PM, Alejandro Alonso <[email protected] 
>>> <mailto:[email protected]>> 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#L157>
>>> https://github.com/xwu/NumericAnnex/blob/c962760bf974a84ec57d8c5e94c91f06584e2453/Sources/PRNG.swift#L316
>>>  
>>> <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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to