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