I agree that the RNG should be public. GameplayKit uses customizable 
distributions including normal and uniform.

https://developer.apple.com/library/content/documentation/General/Conceptual/GameplayKit_Guide/RandomSources.html

-- E

> On Nov 30, 2017, at 4:03 PM, TellowKrinkle via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Whether or not it’s possible to hide, I think that the default RNG should be 
> exposed publicly, so that functions like `CustomType.random(using:)` will 
> take a RandomSource property instead of just using the system RNG, allowing 
> someone to specify a different RNG (maybe a seedable PRNG for example) to 
> suit their needs.
> 
>> 2017/11/30 16:30、Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>>のメール:
>> 
>> On Thu, Nov 30, 2017 at 3:58 PM, Dave DeLong via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Nov 30, 2017, at 2:48 PM, Jonathan Hull via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> I would personally go with:
>>> 
>>>     Int.random //Returns a random Int
>> 
>> “Type.random” is so rarely used as to not be worth the addition, IMO. If you 
>> really need a random element from the *entire* domain, then I think you 
>> should have to manually create the ClosedRange<T> yourself.
>> 
>>>     Int.random(in: ClosedRange<Int>) //Works for Comparable types. Gives a 
>>> result from the closed range. Closed Range is never empty.
>> 
>> This is redundant. In order to pick a random element, you’re saying I should 
>> have to do “Int.random(0 ..< 10)”? The redundancy here is that I have to 
>> specify Int twice: once for the “.random” call, and again for the type of 
>> the range. We can do better than that.
>> 
>>>     [0,2,3].randomElement //Returns a random element from the collection
>> 
>> I strongly believe this should be a method, not a property. Properties, like 
>> .first and .last, are expected to return the same value each time you access 
>> them. “.random” inherently breaks that.
>>  
>> FWIW--and this isn't a vote, I know--I largely agree with Dave DeLong's 
>> conclusions above, and for substantially the same reasons.
>>> 
>>> Then a version of each with a ‘using:’ parameter which takes a 
>>> generator/source:
>>> 
>>>     Int.random(using: RandomSource) //Returns a random Int using the given 
>>> source of randomness
>>>     Int.random(in: ClosedRange<Int>, using: RandomSource)
>>>     [0,2,3].randomElement(using: RandomSource)
>>> 
>>> In my own RandomSource & RandomSourceCreatable protocols, I frequently use 
>>> random colors and sizes as well.  The issue there is that you really want a 
>>> closed range for each dimension. I wish Swift had a better notion of 
>>> dimensionality baked into the language. 
>>> 
>>> What I ended up doing was having a “constraints” parameter which took an 
>>> array of constraints which corresponded to various dimensions.  It works 
>>> for me, but it might be a bit complex for something in the standard library.
>>> 
>>> Honestly, given the current capabilities of Swift what this really calls 
>>> for is custom initializers/functions for dimensional types:
>>> 
>>>     UIColor.random //This comes from the protocol
>>>     UIColor.random(hue: ClosedRange<CGFloat> = 0…1, saturation: 
>>> ClosedRange<CGFloat> = 0…1, brightness: ClosedRange<CGFloat> = 0…1, alpha: 
>>> ClosedRange<CGFloat> = 1…1)
>>>     //…and of course the same as above, but with ‘using:'
>>> 
>>> Then you can easily get random colors which look like they belong together:
>>>     
>>>     let myColor = UIColor.random(saturation: 0.2…0.2, brightness: 0.6…0.6) 
>>> 
>>> There would probably also be a convenience version taking CGFloats and 
>>> passing them to the real function as ranges:
>>> 
>>>     let myColor = UIColor.random(saturation: 0.2, brightness: 0.6)
>>> 
>>> 
>>> This means that our default RandomSource needs to be publicly available, so 
>>> that the custom functions can use it as the default…
>> 
>> 
>> It does not. Having actually implemented some version of these APIs, it's 
>> readily apparent now to me that all custom types can simply call 
>> Int.random(in:) (or UnsafeRawBufferPointer<T>.random(byteCount:), or 
>> whatever else we want to have in the standard library) to get random values 
>> from the default RNG for any built-in type and size. The actual default 
>> random need never be exposed publicly, and since its functions are strictly 
>> redundant to these other APIs (which, of course, are the "currency" APIs 
>> that our purpose here is to design and make public), the default random is 
>> required only for internal implementation of the "currency" APIs and (a) is 
>> better off *not* exposed; (b) doesn't need to be of the same type as other 
>> RNGs, conform to the same protocols, or for that matter, does not even need 
>> to be a type or be written in Swift.
>> 
>> 
>> 👍 
>> 
>>> 
>>> Thanks,
>>> Jon
>>> 
>>> 
>>>> On Nov 27, 2017, at 10:14 AM, TellowKrinkle via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> You say that all the `.random`s have different semantics, but to me (at 
>>>> least), they are all very similar.  All the methods can be summarized as 
>>>> selecting a single random element from a collection
>>>> `[0, 2, 3].random` selects a single element from the given collection
>>>> `Int.random(in: 0…8)` selects a single element from the given range
>>>> `Int.random` has no range, but selects a single element from the 
>>>> collection of all ints (equivalent to if the above method had a default 
>>>> value for its range)
>>>> So to me these are all doing the same operation, just with different types 
>>>> of inputs
>>>> 
>>>>> 2017/11/24 20:07、Alejandro Alonso <aalonso...@outlook.com 
>>>>> <mailto:aalonso...@outlook.com>>のメール:
>>>>> 
>>>>> 
>>>>> - Alejandro
>>>>> 
>>>>> ---------- Forwarded message ----------
>>>>> From: Xiaodi Wu <xiaodi...@gmail.com <mailto:xiaodi...@gmail.com>>
>>>>> Date: Nov 24, 2017, 3:05 PM -0600
>>>>> To: Alejandro Alonso <aalonso...@outlook.com 
>>>>> <mailto:aalonso...@outlook.com>>
>>>>> Cc: Brent Royal-Gordon <br...@architechies.com 
>>>>> <mailto:br...@architechies.com>>, Steve Canon via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
>>>>> Subject: Re: [swift-evolution] [Proposal] Random Unification
>>>>> 
>>>>>> On Fri, Nov 24, 2017 at 2:55 PM, Alejandro Alonso 
>>>>>> <aalonso...@outlook.com <mailto:aalonso...@outlook.com>> wrote:
>>>>>> Regarding naming too many things “random”, I’ve talked to many 
>>>>>> developers on my end and they all don’t find it confusing. This proposal 
>>>>>> is aimed to make it obvious what the operation is doing when regarding 
>>>>>> random. I still agree that the proposed solution does just that and in 
>>>>>> practice feels good to write.
>>>>>> 
>>>>>> I must disagree quite strongly here. The various facilities you name 
>>>>>> "random" have different semantics, and differences in semantics should 
>>>>>> be reflected in differences in names. It doesn't matter that some people 
>>>>>> don't find it confusing; it is objectively the case that you have named 
>>>>>> multiple distinct facilities with the same name, which leads to 
>>>>>> confusion. I, for one, get confused, and you can see on this list that 
>>>>>> people are using arguments about one property named "random" to discuss 
>>>>>> another property named "random". This is quite an intolerable situation.
>>>>>> 
>>>>>> I disagree that sample is the correct naming to use here. Getting a 
>>>>>> sample is a verb in this context which would make it break API 
>>>>>> guidelines just as well as `pick()`. To sample is to “take a sample or 
>>>>>> samples of (something) for analysis.” I can agree to use `sampling()` 
>>>>>> which follows API guidelines. This would result in the following grammar 
>>>>>> for `[“hi”, “hello”, “hey”].sampling(2)`, “From array, get a sampling of 
>>>>>> 2"
>>>>>> 
>>>>>> "Sampling" is fine.
>>>>>> 
>>>>>> 
>>>>>> On Nov 23, 2017, 12:54 AM -0600, Xiaodi Wu , wrote:
>>>>>>> On Wed, Nov 22, 2017 at 23:01 Alejandro Alonso <aalonso...@outlook.com 
>>>>>>> <mailto:aalonso...@outlook.com>> wrote:
>>>>>>> Like I’ve said, python has different syntax grammar. We have to read 
>>>>>>> each call site and form a sentence from it. `random.choice([1, 2, 3])` 
>>>>>>> to me this reads, “Get a random choice from array”. This makes sense. 
>>>>>>> Slapping the word choice as an instance property like `[1, 2, 
>>>>>>> 3].choice` reads, “From array, get choice”. What is choice? This 
>>>>>>> doesn’t make sense at all to me. To me, the only good solution is `[1, 
>>>>>>> 2, 3].random` which reads, “From array, get random”. I actually think 
>>>>>>> most users will be able to understand this at first glance rather than 
>>>>>>> choice (or any or some).
>>>>>>> 
>>>>>>> Again, my concern here is that you are proposing to name multiple 
>>>>>>> things "random". If this property should be called "random"--which I'm 
>>>>>>> fine with--then the static method "random(in:)" should be named 
>>>>>>> something else, and the static property "random" should be dropped 
>>>>>>> altogether (as I advocate for reasons we just discussed) or renamed as 
>>>>>>> well. It is simply too confusing that there are so many different 
>>>>>>> "random" methods or properties. Meanwhile, isn't your default RNG also 
>>>>>>> going to be called something like "DefaultRandom"?
>>>>>>> 
>>>>>>> In regards to the sample() function on collections, I have added this 
>>>>>>> as I do believe this is something users need. The name I gave it was 
>>>>>>> pick() as this reads, “From array, pick 2”.
>>>>>>> 
>>>>>>> The name "sample" has been used to good effect in other languages, has 
>>>>>>> a well understood meaning in statistics, and is consistent with Swift 
>>>>>>> language guidelines. The operation here is a sampling, and per Swift 
>>>>>>> guidelines the name must be a noun: therefore, 'sample' is fitting. 
>>>>>>> "Pick" does not intrinsically suggest randomness, whereas sample does, 
>>>>>>> and your proposed reading uses it as a verb, whereas Swift guidelines 
>>>>>>> tell us it must be a noun. I would advocate strongly for using 
>>>>>>> well-established terminology and sticking with "sample."
>>>>>>> 
>>>>>>> 
>>>>>>> On Nov 17, 2017, 8:32 PM -0600, Xiaodi Wu via swift-evolution 
>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>, wrote:
>>>>>>>> On Fri, Nov 17, 2017 at 7:11 PM, Brent Royal-Gordon 
>>>>>>>> <br...@architechies.com <mailto:br...@architechies.com>> wrote:
>>>>>>>>> On Nov 17, 2017, at 3:09 PM, Xiaodi Wu via swift-evolution 
>>>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>>>>> 
>>>>>>>>> But actually, Int.random followed by % is the much bigger issue and a 
>>>>>>>>> very good cautionary tale for why T.random is not a good idea. Swift 
>>>>>>>>> should help users do the correct thing, and getting a random value 
>>>>>>>>> across the full domain and computing an integer modulus is never the 
>>>>>>>>> correct thing to do because of modulo bias, yet it's a very common 
>>>>>>>>> error to make. We are much better off eliminating this API and 
>>>>>>>>> encouraging use of the correct API, thereby reducing the likelihood 
>>>>>>>>> of users making this category of error.
>>>>>>>> 
>>>>>>>> Amen.
>>>>>>>> 
>>>>>>>>> If (and I agree with this) the range-based notation is less intuitive 
>>>>>>>>> (0..<10.random is certainly less discoverable than Int.random), then 
>>>>>>>>> we ought to offer an API in the form of `Int.random(in:)` but not 
>>>>>>>>> `Int.random`. This does not preclude a `Collection.random` API as 
>>>>>>>>> Alejandro proposes, of course, and that has independent value as 
>>>>>>>>> Gwendal says.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> If we're not happy with the range syntax, maybe we should put 
>>>>>>>> `random(in:)`-style methods on the RNG protocol as extension methods 
>>>>>>>> instead. Then there's a nice, uniform style:
>>>>>>>> 
>>>>>>>> let diceRoll = rng.random(in: 1...6)
>>>>>>>> let card = rng.random(in: deck)
>>>>>>>> let isHeads = rng.random(in: [true, false])
>>>>>>>> let probability = rng.random(in: 0.0...1.0)
>>>>>>>> 
>>>>>>>> // Special FloatingPoint overload
>>>>>>>> 
>>>>>>>> The only issue is that this makes the default RNG's name really 
>>>>>>>> important. Something like:
>>>>>>>> 
>>>>>>>> DefaultRandom.shared.random(in: 1...6)
>>>>>>>> 
>>>>>>>> Will be a bit of a pain for users.
>>>>>>>> 
>>>>>>>> I did in fact implement this style of RNG in NumericAnnex, but I'm not 
>>>>>>>> satisfied with the design myself. Not only is it a bit of an ergonomic 
>>>>>>>> thorn, there's also another drawback that actually has weighty 
>>>>>>>> implications:
>>>>>>>> 
>>>>>>>> Users aren't conditioned to reuse RNG instances. Perhaps, it is 
>>>>>>>> because it can "feel" wrong that multiple random instances should come 
>>>>>>>> from the *same* RNG. Instead, it "feels" more right to initialize a 
>>>>>>>> new RNG for every random number. After all, if one RNG is random, two 
>>>>>>>> must be randomer! This error is seen with some frequency in other 
>>>>>>>> languages that adopt this design, and they sometimes resort to 
>>>>>>>> educating users through documentation that isn't consistently heeded.
>>>>>>>> 
>>>>>>>> Of course, you and I both know that this is not ideal for performance. 
>>>>>>>> Moreover, for a number of PRNG algorithms, the first few hundred or 
>>>>>>>> thousand iterations can be more predictable than later iterations. 
>>>>>>>> (Some algorithms discard the first n iterations, but whether that's 
>>>>>>>> adequate depends on the quality of the seed, IIUC.) Both of these 
>>>>>>>> issues don't apply specifically to a default RNG type that cannot be 
>>>>>>>> initialized and always uses entropy from the global pool, but that's 
>>>>>>>> not enough to vindicate the design, IMO. By emphasizing *which* RNG 
>>>>>>>> instance is being used for random number generation, the design 
>>>>>>>> encourages non-reuse of non-default RNGs, which is precisely where 
>>>>>>>> this common error matters for performance (and maybe security).
>>>>>>>> 
>>>>>>>> Maybe we call the default RNG instance `random`, and then give the 
>>>>>>>> `random(in:)` methods another name, like `choose(in:)`?
>>>>>>>> 
>>>>>>>> let diceRoll = random.choose(in: 1...6)
>>>>>>>> let card = random.choose(in: deck)
>>>>>>>> let isHeads = random.choose(in: [true, false])
>>>>>>>> let probability = random.choose(in: 0.0...1.0)
>>>>>>>> let diceRoll = rng.choose(in: 1...6)
>>>>>>>> let card = rng.choose(in: deck)
>>>>>>>> let isHeads = rng.choose(in: [true, false])
>>>>>>>> let probability = rng.choose(in: 0.0...1.0)
>>>>>>>> 
>>>>>>>> This would allow us to keep the default RNG's type private and expose 
>>>>>>>> it only as an existential—which means more code will treat RNGs as 
>>>>>>>> black boxes, and people will extend the RNG protocol instead of the 
>>>>>>>> default RNG struct—while also putting our default random number 
>>>>>>>> generator under the name `random`, which is probably where people will 
>>>>>>>> look for such a thing.
>>>>>>>> 
>>>>>>>> I've said this already in my feedback, but it can get lost in the long 
>>>>>>>> chain of replies, so I'll repeat myself here because it's relevant to 
>>>>>>>> the discussion. I think one of the major difficulties of discussing 
>>>>>>>> the proposed design is that Alejandro has chosen to use a property 
>>>>>>>> called "random" to name multiple distinct functions which have 
>>>>>>>> distinct names in other languages. In fact, almost every method or 
>>>>>>>> function is being named "random." We are tripping over ourselves and 
>>>>>>>> muddling our thinking (or at least, I find myself doing so) because 
>>>>>>>> different things have the exact same name, and if I'm having this 
>>>>>>>> trouble after deep study of the design, I think it's a good sign that 
>>>>>>>> this is going to be greatly confusing to users generally.
>>>>>>>> 
>>>>>>>> First, there's Alejandro's _static random_, which he proposes to 
>>>>>>>> return an instance of type T given a type T. In Python, this is named 
>>>>>>>> `randint(a, b)` for integers, and `random` (between 0 and 1) or 
>>>>>>>> `uniform(a, b)` for floating-type types. The distinct names reflect 
>>>>>>>> the fact that `randint` and `uniform` are mathematically quite 
>>>>>>>> different (one samples a *discrete* uniform distribution and the other 
>>>>>>>> a *continuous* uniform distribution), and I'm not aware of non-numeric 
>>>>>>>> types offering a similar API in Python. These distinct names 
>>>>>>>> accurately reflect critiques from others on this list that the 
>>>>>>>> proposed protocol `Randomizable` lumps together types that don't share 
>>>>>>>> any common semantics for their _static random_ method, and that the 
>>>>>>>> protocol is of questionable utility because types in general do not 
>>>>>>>> share sufficient semantics such that one can do interesting work in 
>>>>>>>> generic code with such a protocol.
>>>>>>>> 
>>>>>>>> Then there's Alejandro's _instance random_, which he proposes to 
>>>>>>>> return an element of type T given a instance of a collection of type 
>>>>>>>> T. In Python, this is named "choice(seq)" (for one element, or else 
>>>>>>>> throws an error) and "sample(seq, k)" (for up to k elements). As I 
>>>>>>>> noted, Alejandro was right to draw an analogy between _instance 
>>>>>>>> random_ and other instance properties of a Collection such as `first` 
>>>>>>>> and `last`. In fact, the behavior of Python's "choice" (if modified to 
>>>>>>>> return an Optional) and "sample", as a pair, would fit in very well 
>>>>>>>> next to Swift's existing pairs of `first` and `prefix(k)` and `last` 
>>>>>>>> and `suffix(k)`. We could trivially Swiftify the names here; for 
>>>>>>>> example:
>>>>>>>> 
>>>>>>>> ```
>>>>>>>> [1, 2, 3].first
>>>>>>>> [1, 2, 3].any // or `choice`, or `some`, or...
>>>>>>>> [1, 2, 3].last
>>>>>>>> 
>>>>>>>> [1, 2, 3].prefix(2)
>>>>>>>> [1, 2, 3].sample(2)
>>>>>>>> [1, 2, 3].suffix(2)
>>>>>>>> ```
>>>>>>>> 
>>>>>>>> I'm going to advocate again for _not_ naming all of these distinct 
>>>>>>>> things "random". Even in conducting this discussion, it's so hard to 
>>>>>>>> keep track of what particular function a person is giving feedback 
>>>>>>>> about.
>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>>>>>> _______________________________________________
>>>>>>>> swift-evolution mailing list
>>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> 
>>>>>> On Nov 17, 2017, 8:32 PM -0600, Xiaodi Wu via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>, wrote:
>>>>>> 
>>>>>>> On Fri, Nov 17, 2017 at 7:11 PM, Brent Royal-Gordon 
>>>>>>> <br...@architechies.com <mailto:br...@architechies.com>> wrote:
>>>>>>>> On Nov 17, 2017, at 3:09 PM, Xiaodi Wu via swift-evolution 
>>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>>>> 
>>>>>>>> But actually, Int.random followed by % is the much bigger issue and a 
>>>>>>>> very good cautionary tale for why T.random is not a good idea. Swift 
>>>>>>>> should help users do the correct thing, and getting a random value 
>>>>>>>> across the full domain and computing an integer modulus is never the 
>>>>>>>> correct thing to do because of modulo bias, yet it's a very common 
>>>>>>>> error to make. We are much better off eliminating this API and 
>>>>>>>> encouraging use of the correct API, thereby reducing the likelihood of 
>>>>>>>> users making this category of error.
>>>>>>> 
>>>>>>> Amen.
>>>>>>> 
>>>>>>>> If (and I agree with this) the range-based notation is less intuitive 
>>>>>>>> (0..<10.random is certainly less discoverable than Int.random), then 
>>>>>>>> we ought to offer an API in the form of `Int.random(in:)` but not 
>>>>>>>> `Int.random`. This does not preclude a `Collection.random` API as 
>>>>>>>> Alejandro proposes, of course, and that has independent value as 
>>>>>>>> Gwendal says.
>>>>>>> 
>>>>>>> 
>>>>>>> If we're not happy with the range syntax, maybe we should put 
>>>>>>> `random(in:)`-style methods on the RNG protocol as extension methods 
>>>>>>> instead. Then there's a nice, uniform style:
>>>>>>> 
>>>>>>> let diceRoll = rng.random(in: 1...6)
>>>>>>> let card = rng.random(in: deck)
>>>>>>> let isHeads = rng.random(in: [true, false])
>>>>>>> let probability = rng.random(in: 0.0...1.0)
>>>>>>> 
>>>>>>> // Special FloatingPoint overload
>>>>>>> 
>>>>>>> The only issue is that this makes the default RNG's name really 
>>>>>>> important. Something like:
>>>>>>> 
>>>>>>> DefaultRandom.shared.random(in: 1...6)
>>>>>>> 
>>>>>>> Will be a bit of a pain for users.
>>>>>>> 
>>>>>>> I did in fact implement this style of RNG in NumericAnnex, but I'm not 
>>>>>>> satisfied with the design myself. Not only is it a bit of an ergonomic 
>>>>>>> thorn, there's also another drawback that actually has weighty 
>>>>>>> implications:
>>>>>>> 
>>>>>>> Users aren't conditioned to reuse RNG instances. Perhaps, it is because 
>>>>>>> it can "feel" wrong that multiple random instances should come from the 
>>>>>>> *same* RNG. Instead, it "feels" more right to initialize a new RNG for 
>>>>>>> every random number. After all, if one RNG is random, two must be 
>>>>>>> randomer! This error is seen with some frequency in other languages 
>>>>>>> that adopt this design, and they sometimes resort to educating users 
>>>>>>> through documentation that isn't consistently heeded.
>>>>>>> 
>>>>>>> Of course, you and I both know that this is not ideal for performance. 
>>>>>>> Moreover, for a number of PRNG algorithms, the first few hundred or 
>>>>>>> thousand iterations can be more predictable than later iterations. 
>>>>>>> (Some algorithms discard the first n iterations, but whether that's 
>>>>>>> adequate depends on the quality of the seed, IIUC.) Both of these 
>>>>>>> issues don't apply specifically to a default RNG type that cannot be 
>>>>>>> initialized and always uses entropy from the global pool, but that's 
>>>>>>> not enough to vindicate the design, IMO. By emphasizing *which* RNG 
>>>>>>> instance is being used for random number generation, the design 
>>>>>>> encourages non-reuse of non-default RNGs, which is precisely where this 
>>>>>>> common error matters for performance (and maybe security).
>>>>>>> 
>>>>>>> Maybe we call the default RNG instance `random`, and then give the 
>>>>>>> `random(in:)` methods another name, like `choose(in:)`?
>>>>>>> 
>>>>>>> let diceRoll = random.choose(in: 1...6)
>>>>>>> let card = random.choose(in: deck)
>>>>>>> let isHeads = random.choose(in: [true, false])
>>>>>>> let probability = random.choose(in: 0.0...1.0)
>>>>>>> let diceRoll = rng.choose(in: 1...6)
>>>>>>> let card = rng.choose(in: deck)
>>>>>>> let isHeads = rng.choose(in: [true, false])
>>>>>>> let probability = rng.choose(in: 0.0...1.0)
>>>>>>> 
>>>>>>> This would allow us to keep the default RNG's type private and expose 
>>>>>>> it only as an existential—which means more code will treat RNGs as 
>>>>>>> black boxes, and people will extend the RNG protocol instead of the 
>>>>>>> default RNG struct—while also putting our default random number 
>>>>>>> generator under the name `random`, which is probably where people will 
>>>>>>> look for such a thing.
>>>>>>> 
>>>>>>> I've said this already in my feedback, but it can get lost in the long 
>>>>>>> chain of replies, so I'll repeat myself here because it's relevant to 
>>>>>>> the discussion. I think one of the major difficulties of discussing the 
>>>>>>> proposed design is that Alejandro has chosen to use a property called 
>>>>>>> "random" to name multiple distinct functions which have distinct names 
>>>>>>> in other languages. In fact, almost every method or function is being 
>>>>>>> named "random." We are tripping over ourselves and muddling our 
>>>>>>> thinking (or at least, I find myself doing so) because different things 
>>>>>>> have the exact same name, and if I'm having this trouble after deep 
>>>>>>> study of the design, I think it's a good sign that this is going to be 
>>>>>>> greatly confusing to users generally.
>>>>>>> 
>>>>>>> First, there's Alejandro's _static random_, which he proposes to return 
>>>>>>> an instance of type T given a type T. In Python, this is named 
>>>>>>> `randint(a, b)` for integers, and `random` (between 0 and 1) or 
>>>>>>> `uniform(a, b)` for floating-type types. The distinct names reflect the 
>>>>>>> fact that `randint` and `uniform` are mathematically quite different 
>>>>>>> (one samples a *discrete* uniform distribution and the other a 
>>>>>>> *continuous* uniform distribution), and I'm not aware of non-numeric 
>>>>>>> types offering a similar API in Python. These distinct names accurately 
>>>>>>> reflect critiques from others on this list that the proposed protocol 
>>>>>>> `Randomizable` lumps together types that don't share any common 
>>>>>>> semantics for their _static random_ method, and that the protocol is of 
>>>>>>> questionable utility because types in general do not share sufficient 
>>>>>>> semantics such that one can do interesting work in generic code with 
>>>>>>> such a protocol.
>>>>>>> 
>>>>>>> Then there's Alejandro's _instance random_, which he proposes to return 
>>>>>>> an element of type T given a instance of a collection of type T. In 
>>>>>>> Python, this is named "choice(seq)" (for one element, or else throws an 
>>>>>>> error) and "sample(seq, k)" (for up to k elements). As I noted, 
>>>>>>> Alejandro was right to draw an analogy between _instance random_ and 
>>>>>>> other instance properties of a Collection such as `first` and `last`. 
>>>>>>> In fact, the behavior of Python's "choice" (if modified to return an 
>>>>>>> Optional) and "sample", as a pair, would fit in very well next to 
>>>>>>> Swift's existing pairs of `first` and `prefix(k)` and `last` and 
>>>>>>> `suffix(k)`. We could trivially Swiftify the names here; for example:
>>>>>>> 
>>>>>>> ```
>>>>>>> [1, 2, 3].first
>>>>>>> [1, 2, 3].any // or `choice`, or `some`, or...
>>>>>>> [1, 2, 3].last
>>>>>>> 
>>>>>>> [1, 2, 3].prefix(2)
>>>>>>> [1, 2, 3].sample(2)
>>>>>>> [1, 2, 3].suffix(2)
>>>>>>> ```
>>>>>>> 
>>>>>>> I'm going to advocate again for _not_ naming all of these distinct 
>>>>>>> things "random". Even in conducting this discussion, it's so hard to 
>>>>>>> keep track of what particular function a person is giving feedback 
>>>>>>> about.
>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> 
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

Reply via email to