[swift-evolution] [Proposal] Random Unification

Martin Waitz tali at admingilde.org
Fri Dec 1 01:11:59 CST 2017


> The collection is a subject which has elements, and we are asking for one of them at random.

it has elements, sure.
And because of its structure, it has a first and a last element and whatever.
But that random element is not an inherent property of the collection.

I find it much more natural to use the random number generator to draw random elements from collections than the other way round.
That approach also completely side-steps the problem with having to define default arguments. The user can just use any random number generator she has. Obviously, it makes sense to provide a default one named `random` to make it easily accessible.

>>> var list = [1,2,3,4]
>>> let a:Int? = list.randomElement //List is still [1,2,3,4] and ‘a’ contains one of the elements
>> Instead I would prefer to have something like:
>> let a = random.draw(from: list)
> But now the RNG has to understand the concept of collections. I would argue it is much cleaner to write an extension on Collection.
> func randomElement(using source: RandomSource = .default) -> Element? {
> 	guard !isEmpty else {return nil}
> 	let idx = Int.random(in: 0…(count - 1), using: source)
> 	return self[idx]
> }

But then the Collection has to understand the concept of random numbers. ;-)
Well both approaches are equally clean from this point of view:

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]

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.

— Martin

More information about the swift-evolution mailing list