> On Nov 30, 2017, at 11:11 PM, Martin Waitz <t...@admingilde.org> wrote:
> 
> Hello,
> 
>> 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. ;-)
Not really.  Collection itself doesn’t have to change it’s structure at all.  
We can just define a convenience function in an extension.

> Well both approaches are equally clean from this point of view:

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.

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…


> 
> 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...


> 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?



_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to