<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Here is my wishlist:</div><div class=""><br class=""></div><div class="">• A protocol which allows random instances of any type which conforms (they would init from some number of random bytes passed to them… or better yet, they would be passed a source which can give them however many bytes of randomness they need)</div><div class="">• A choice between fast and secure randomness (and possibly other implementations)</div><div class="">• The optional ability to seed so that randomness can be reproduced when needed</div><div class=""><br class=""></div><div class="">It would also be nice to be able to constrain the created instances in some way. For scalars like Float and Int, this would mean being able to define a range which the random value falls in. For dimensional constructs (e.g. colors, points, sizes) you want to be able to constrain each axis individually. This is actually the hardest part to get right, especially if you are trying to keep things secure. Even for graphics applications where security isn’t the issue, biases in the randomness added by naive approaches like using % can be apparent to the eye.</div><div class=""><br class=""></div><div class="">I think what I would like to see is a protocol defining a source of randomness, which does that hard part for you (written in mail):</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">protocol RandomnessSource {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>init(seed: UInt64)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func randomBytes(count: Int) -> [UInt64]</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>//Default Imp of below provided from above</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func randomInt(in: ClosedRange<Int>? = nil) -> Int //nil means don’t constrain ( = nil is shorthand for convenience func randomInt() )</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func randomUInt(in: ClosedRange<UInt>? = nil) -> UInt </div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func randomDouble(in: ClosedRange<Double>? = nil) -> Double </div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func randomBool() -> Bool</div><div class="">}</div></blockquote><div class=""><br class=""></div><div class="">…and then a protocol where a type can use that source to create random instances of themselves:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">protocol Randomizable {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func random(_ source: RandomnessSource)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static var fastRandom:Self {get} //Uses default “fast” source (default imp provided)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static var secureRandom:Self {get} //Uses default “secure” source (default imp provided)</div><div class="">}</div><div class=""><br class=""></div><div class=""><div class="">protocol RangeRandomizable: Randomizable {</div></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>static func random(_ source: RandomnessSource, in: ClosedRange<Self>?)</div></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>static func fastRandom(in: ClosedRange<Self>?) -> Self //Uses default “fast” source (default imp provided)</div></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>static func secureRandom(in: ClosedRange<Self>?) -> Self //Uses default “secure” source (default imp provided)</div></div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>//Also provides default imp for random(_ source: RandomnessSource) {random(source, in: nil)}, etc...</div><div class=""><div class="">}</div></div><div class=""><br class=""></div></blockquote>Then things like points/sizes can use scalar types as building blocks:<br class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><br class=""></div><div class="">extension CGFloat: RangeRandomizable {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func random(_ source: RandomnessSource, in:ClosedRange<CGFloat>){</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>let doubleRange = //Convert range to double</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>return CGFloat(source.randomDouble(in: doubleRange))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">extension CGSize: Randomizable {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>static func random(source: RandomnessSource){</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>return CGSize(width: CGFloat.random(source), height: CGFloat.random(source))</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>//Can add convenience functions to bound width/height to range/constant</div><div class="">}</div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">What I do behind the scenes in my own protocol is take a dictionary of named constraints (instead of a range) because I need a common interface for all dimensions:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #0433ff" class="">public</span> <span style="color: #0433ff" class="">enum</span> RandomSourceConstraint<T> {</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">case</span> none</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">case</span> constant(<span style="color: #3495af" class="">T</span>)</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">case</span> min(<span style="color: #3495af" class="">T</span>)</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">case</span> max(<span style="color: #3495af" class="">T</span>)</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">case</span> range (<span style="color: #3495af" class="">T</span>,<span style="color: #3495af" class="">T</span>)</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> <span style="color: #0433ff" class="">case</span> custom ( (<span style="color: #3495af" class="">RandomSourceValue</span>)-><span style="color: #3495af" class="">T</span> )</div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""> //More code here...</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div></blockquote><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 8, 2017, at 3:40 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="">Here is some Swift 3 code that allows simple repeatable repeatable random sequences by conforming to a protocol:<div class=""><a href="https://gist.github.com/jonhull/3655672529f8cf5b2eb248583d2cafb9" class="">https://gist.github.com/jonhull/3655672529f8cf5b2eb248583d2cafb9</a></div><div class=""> </div><div class="">I now use a slightly more complicated version of this which allows more complex types (like colors) to be added and constrained in more interesting ways than just from…to (e.g. Colors with a fixed lightness/brightness, but a range in hue). The base is pretty much the same.</div><div class=""><br class=""></div><div class="">I have found that user-facing code often needs the idea of repeatable/re-creatable randomness. I originally created it to create a sketchy version of lines that had random offsets added to points along the line. If the randomness wasn’t reproducible, then the sketchiness of the line would shift around randomly every time there was a change.</div><div class=""><br class=""></div><div class="">The code I have provided above is not useful for any sort of cryptography/security though. There are different reasons for randomness. Maybe that is something we should consider?</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Sep 8, 2017, at 9:52 AM, Alejandro Alonso 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="">
<title class=""></title>
<div class="">
<div name="messageBodySection" style="font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, sans-serif;" class="">
Hello swift evolution, I would like to propose a unified approach to `random()` in Swift. I have a simple implementation here <a href="https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5" class="">https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5</a>.
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.
<div class=""><br class="">
</div>
<div class="">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.</div>
<div class=""><br class="">
</div>
<div class="">I’d like to hear about your ideas on this proposal, or any implementation changes if need be.</div>
<div class=""><br class="">
</div>
<div class="">- Alejando</div>
</div>
<div name="messageReplySection" style="font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, sans-serif;" class="">
<br class="">
<div class=""></div>
</div>
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>