> On Nov 30, 2017, at 2:30 PM, Xiaodi Wu <[email protected]> wrote:
>
> On Thu, Nov 30, 2017 at 3:58 PM, Dave DeLong via swift-evolution
> <[email protected] <mailto:[email protected]>> wrote:
>
>
>> On Nov 30, 2017, at 2:48 PM, Jonathan Hull via swift-evolution
>> <[email protected] <mailto:[email protected]>> 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.
I have also implemented some version of these APIs, both for Random and
RepeatablyRandom sources.
I get what you are saying about just being able to use the constructs from Int,
etc…, but we still need a public default. Let me give a concrete example of
CGSize. Yes, we want to just use CGFloat’s random, but if we don’t have a
publicly available way to call the default then we have to implement the same
algorithm twice, which is problematic. (Code written in Mail)
static func random(width widthRange: ClosedRange<CGFloat>, height heightRange:
ClosedRange<CGFloat>, using source: RandomSource = .default) -> CGSize {
let w = CGFloat.random(in: widthRange, using: source)
let h = CGFloat.random(in: heightRange, using: source)
return CGSize(width: w, height: h)
}
Without the default I would have to have a second version which used
CGFloat(in:) in order to use the default source/generator, which means I would
have to update both places when I make changes. Much better to just allow a
default value for ‘using:'.
Thanks,
Jon
>
>
> 👍
>
>>
>> Thanks,
>> Jon
>>
>>
>>> On Nov 27, 2017, at 10:14 AM, TellowKrinkle via swift-evolution
>>> <[email protected] <mailto:[email protected]>> 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 <[email protected]
>>>> <mailto:[email protected]>>のメール:
>>>>
>>>>
>>>> - Alejandro
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: Xiaodi Wu <[email protected] <mailto:[email protected]>>
>>>> Date: Nov 24, 2017, 3:05 PM -0600
>>>> To: Alejandro Alonso <[email protected]
>>>> <mailto:[email protected]>>
>>>> Cc: Brent Royal-Gordon <[email protected]
>>>> <mailto:[email protected]>>, Steve Canon via swift-evolution
>>>> <[email protected] <mailto:[email protected]>>
>>>> Subject: Re: [swift-evolution] [Proposal] Random Unification
>>>>
>>>>> On Fri, Nov 24, 2017 at 2:55 PM, Alejandro Alonso <[email protected]
>>>>> <mailto:[email protected]>> 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 <[email protected]
>>>>>> <mailto:[email protected]>> 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
>>>>>> <[email protected] <mailto:[email protected]>>, wrote:
>>>>>>> On Fri, Nov 17, 2017 at 7:11 PM, Brent Royal-Gordon
>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>> On Nov 17, 2017, at 3:09 PM, Xiaodi Wu via swift-evolution
>>>>>>>> <[email protected] <mailto:[email protected]>> 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
>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>> 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
>>>>> <[email protected] <mailto:[email protected]>>, wrote:
>>>>>
>>>>>> On Fri, Nov 17, 2017 at 7:11 PM, Brent Royal-Gordon
>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>> On Nov 17, 2017, at 3:09 PM, Xiaodi Wu via swift-evolution
>>>>>>> <[email protected] <mailto:[email protected]>> 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
>>>>>> [email protected] <mailto:[email protected]>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>
>
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution