<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 3, 2017, at 11:44 PM, Jonathan Hull via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I like the idea of splitting it into 2 separate “Random” proposals.<div class=""><br class=""></div><div class="">The first would have Xiaodi’s built-in CSPRNG which only has the interface:</div><div class=""><br class=""></div><div class="">On FixedWidthInteger:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func random()throws -> Self</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func random(in range: ClosedRange<Self>)throws -> Self<br class=""><div class=""><br class=""></div><div class="">On Double:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func random()throws -> Double</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func random(in range: ClosedRange<Double>)throws -> Double</div><div class=""><br class=""></div><div class="">(Everything else we want, like shuffled(), could be built in later proposals by calling those functions)</div><div class=""><br class=""></div><div class="">The other option would be to remove the ‘throws’ from the above functions (perhaps fatalError-ing), and provide an additional function which can be used to check that there is enough entropy (so as to avoid the crash or fall back to a worse source when the CSPRNG is unavailable).</div></div></div></div></blockquote></div><div><blockquote type="cite" class=""><br class=""></blockquote></div><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">Then a second proposal would bring in the concept of RandomSources (whatever we call them), which can return however many random bytes you ask for… and a protocol for types which know how to initialize themselves from those bytes. That might be spelled like 'static func random(using: RandomSource)->Self'. As a convenience, the source would also be able to create FixedWidthIntegers and Doubles (both with and without a range), and would also have the coinFlip() and oneIn(UInt)->Bool functions. Most types should be able to build themselves off of that. There would be a default source which is built from the first protocol.</div><div class=""><br class=""></div><div class="">I also really think we should have a concept of Repeatably-Random as a subprotocol for the second proposal. I see far too many shipping apps which have bugs due to using arc4Random when they really needed a repeatable source (e.g. patterns and lines jump around when you resize things). If it was an easy option, people would use it when appropriate. This would just mean a sub-protocol which has an initializer which takes a seed, and the ability to save/restore state (similar to CGContexts).</div></div></div></div></blockquote></div><div class=""><br class=""></div><div class="">I like this kind of layering of functionality and proposals. I would additionally separate the fundamental CSPRNG interface from the fool-proof easy functions that naive users will find on Stack Overflow.</div><div><div><br class=""></div><div>The "easy" functions should:</div><div><br class=""></div></div><div>* Trap on any error without throwing. Sophisticated users may be able to do something about entropy failure, so the fundamental CSPRNG interface needs to provide errors, but the easy function should either degrade somewhat (if entropy is present but insufficient) or just die (if entropy is wholly absent or nearly so).</div><div><br class=""></div><div>* Remove the range-less function. Naive users often write things like `Int.random() % 100`, which unbeknownst to them is biased. Providing only the ranged interface nudges naive users toward correct usage. </div><div><br class=""></div><div>* Provide an "easy" way to get some random bytes instead of a random number. Perhaps a Data initializer that returns random-filled bytes of the requested length. This helps make up for the lack of a range-less function on FixedWidthInteger.</div><div><br class=""></div><div>The "easy" functions should get the best names: Int.random(in:), Data.random(length:), etc. The fundamental CSPRNG interface should have an interface that is less friendly and less discoverable.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">-- </div><div class="">Greg Parker <a href="mailto:gparker@apple.com" class="">gparker@apple.com</a> Runtime Wrangler</div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>