[swift-evolution] [Proposal] Random Unification

Dave DeLong swift at davedelong.com
Tue Jan 2 10:19:46 CST 2018

Just skimmed through the updated proposal and am weighing in with my naïve opinions:

I’m still highly skeptical of a static “T.random” API. I’ve yet to see a convincing example where it’d be useful to pick a value from the range of all possible values. The only truly useful one I’ve seen is “pick a random bool”, which could easily be done via “[true, false].random()"

I much prefer the GameplayKit API[0], which breaks the idea of randomness up in to 2 separate concepts:
A “Source” → Where the random numbers come from
A “Distribution” → Initialized with a source, it makes sure the produced numbers exhibit a specific distribution over multiple samplings. Ie, a uniform distribution vs a Gaussian distribution, or something like “I want to pick a card from a deck but bias choices towards Spades or Aces”. I’m also reminded of the anecdote of how iTunes had to modify their “playlist shuffle” algorithm to be less random[1], because the true randomness would do weird things that made it seem not random. Spotify had the same problem and solution[2].
Breaking things up like this would also make it easier to test randomness (by using a replay-able source) but that still follow the parameters of your app (that it has a bell-curve distribution of probabilities, for example)

I’d still really really really like to see how this could be done as two separate things:
A minimal implementation in the Standard Library (like, defining the base Source and Distribution protocols, with a single default implementation of each)
A proposal for a more complete “non-standard library” where the larger array of functionality would be contained. For example, IMO I don’t think the shuffling stuff needs to be in the standard library. This is also where all the cryptographically secure stuff (that your typical app developer does not need) would live.

The “random” element of a collection/range should be “func random() → Element?”, not “var random: Element?”. Property values shouldn't change between accesses. Ditto the static “Randomizable.random” property.

What do you think about actively discouraging people from using the modulo operator to create a range? It could be done by having the RNGs return a “RandomValue<T>” type, then defining a mod operator that takes a RandomValue<T> and a T (?), and then giving it a deprecation warning + fixit. Not sure if that’d be worth the type overhead, but I’m very much in favor of encouraging people towards better practices.

I’m +1 on crashing if we can’t produce a random number. 

What do you think about the philosophical difference of Type.random(using:) vs Type.init(randomSource:)?


[0]: https://developer.apple.com/documentation/gameplaykit/gkrandom <https://developer.apple.com/documentation/gameplaykit/gkrandom>
[1]: https://www.youtube.com/watch?v=lg188Ebas9E&feature=youtu.be&t=719 <https://www.youtube.com/watch?v=lg188Ebas9E&feature=youtu.be&t=719>
[2]: https://labs.spotify.com/2014/02/28/how-to-shuffle-songs/ <https://labs.spotify.com/2014/02/28/how-to-shuffle-songs/>

> On Jan 2, 2018, at 1:35 AM, Alejandro Alonso via swift-evolution <swift-evolution at swift.org> wrote:
> Hello swift evolution once again, I’ve been hard at work considering every email and revising the proposal. I’ve made lots of changes and additions to the proposal to discuss some problems we’ve had (T.random), and walks through detailed design. You can see the proposal here: https://github.com/apple/swift-evolution/pull/760 <https://github.com/apple/swift-evolution/pull/760> .
> A big issue that lots of people pointed out was `T.random %` and to remove it completely from the API. To give a gist of why I continue to support T.random:
> 1. Modulo bias misuse is only a problem to types that conform to `BinaryInteger`. Why remove this functionality if only a portion of the types have the ability of misuse. `Double.random % 10` is a good example of where modulo isn’t implemented here as it produces the error, “'%' is unavailable: Use truncatingRemainder instead”.
> 2. `Int.random(in: Int.min … Int.max)` doesn’t work. For developers that actually rely on this functionality, the work around that was discussed earlier simply doesn’t work. `Int.min … Int.max`’s count property exceeds that of `Int`’s numerical range. A working work around would be something along the lines of `Int(truncatingIfNeeded: Random.default.next(UInt.self))` which creates a pain point for those developers. As the goal of this proposal to remove pain points regarding random, this change does the opposite.
> I’m interested to hear if anymore discussion around this, or any other issues come up.
> - Alejandro
> On Sep 8, 2017, 11:52 AM -0500, Alejandro Alonso via swift-evolution <swift-evolution at swift.org>, wrote:
>> Hello swift evolution, I would like to propose a unified approach to `random()` in Swift. I have a simple implementation here https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5 <https://gist.github.com/Azoy/5d294148c8b97d20b96ee64f434bb4f5>. 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.
>> 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.
>> I’d like to hear about your ideas on this proposal, or any implementation changes if need be.
>> - Alejando
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180102/e8249fa6/attachment.html>

More information about the swift-evolution mailing list