> On Nov 30, 2017, at 11:11 PM, Martin Waitz <[email protected]> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution