[swift-evolution] [Proposal] Random Unification

Jonathan Hull jhull at gbis.com
Fri Dec 1 15:52:38 CST 2017

> On Dec 1, 2017, at 9:39 AM, Martin Waitz <tali at admingilde.org> wrote:
> Hi,
>> With a protocol defining random() and random(in:), you could write generic algorithms on things which know how to create themselves from a RNG.  With your approach the RNG has to provide a way to get a random value for each type you want to support.
> This is right, if we want a generic prototype for construction of random objects, well then we need such a protocol and a new method or initializer.
> However, I‘m not yet convinced that such a protocol is necessary.
> Most objects will be constructed using randomized values, according to the use case at hand. A generic randomizable protocol would not help here.

I’m not sure how you intend to get a random value from a Range without something like this. 

But even ignoring that for the moment, I have a version of this in my own code and find it quite useful.  What I do is setup a series of constraints on the values I want (e.g. the range I want them in) and then I generically generate a lazy collection of random values of that type.  Thus, I can ask for colors with certain properties, and then I receive a collection of random colors with those properties which I use to create patterns and graphic effects.

>> For example, without random(in:) or random(), how would you get a CGFloat between 0 and 1?  Ranges are only collections if they are countable…
> I was assuming that there would be a random.draw(from:) for ranges.

Sure, but Ranges of what?  Ranges of CGFloats are very different than Ranges of Ints, you need some cooperation from the type itself. This is my main point.

>>> extension RandomFoo {
>>>  func draw<T: Collection>(from urn: T) -> T.Element? {
>>>      guard !urn.isEmpty else { return nil }
>>>      let idx = draw(from: urn.indices)
>>>      return urn[idx]
>>>  }
>>> }
>> This will call itself repeatedly and hang...
> You are right, Collection.indices is also a Collection. We have to explicitly use the range here.
>>> We just have to define one base protocol for such extensions. Every random number generator then automatically knows how to draw elements from ranges and collections.
>> It isn’t automatic, thought.  How would I get a random color?
> This has already been discussed: you either want some random color from a fixed set, or you want to produce a new color using some random values. A completely random color it totally useless.

I wouldn’t say completely useless.  In the example above, I usually constrain my random colors to have a specific effect, but completely random has its own look (which I mainly use for debugging purposes).  As I mentioned earlier in the thread, the protocol can be augmented by UIColor to provide a way to only get random values with certain characteristics.

Yes, colors can be built from smaller primitives, but it is nice to have the type do that itself so you can continue to build on it generically.

In the examples you have given, everything has to be special cased (even getting a random Bool requires me to list out the options [true, false]). That isn’t useful for building large scale structures generically.

I am not arguing that we shouldn’t be able to get a random element from a collection or range… just that we should build this in a way which is easy to build on and modify.

More information about the swift-evolution mailing list