> On 6 Oct 2017, at 06:25, David Hart via swift-evolution
> <[email protected]> wrote:
>
>
>
>> On 5 Oct 2017, at 20:23, Ben Cohen via swift-evolution
>> <[email protected]> wrote:
>>
>>
>>> On Oct 5, 2017, at 10:58, Nate Cook via swift-evolution
>>> <[email protected]> wrote:
>>>
>>> The edge case is really the same (empty ranges), it’s about what we do with
>>> the edge case. If we include the methods on integer types, usage will look
>>> like this:
>>>
>>> let x = Int.random(in: 0..<5) // 3
>>> let y = Int.random(in: 0..<0) // runtime error
>>>
>>
>> These examples are a bit misleading, because they use literals. Sometimes
>> they will, sure, but in practice, many use cases would define Int.random(in:
>> 0..<array.count) or similar, which has just the same pitfalls as
>> array.random().
>>
>> p.s. ideally Int.random(in: 0..<0) would be a compile time error...
>>
>>> If we only have the collection methods, usage will look like this:
>>>
>>> let x = (0..<5).random()! // 3
>>> let y = (0..<0).random()! // runtime error
>>>
>>
>> I don’t know if it’s a given that we must make randomElement optional. I’m
>> on the fence as to whether it should be optional vs trap on empty.
>
> I vote for making them optional because doing otherwise would be inconsistent
> with first and last, no?
I want to be able to check for empty at the same time as I get the value,
exactly like I do first first and last:
if let rand = array.randomElement() {
// use rand
} else {
// handle empty
}
OR
guard let rand = array.randomElement() else {
// handle empty
}
I also like those optional returning properties because it’s a small reminder
from the type system to check for the corner case (empty) and makes them
explicit when reading code. With a trapping function, I would often forget to
handle empty and it wouldn’t jump out at me when reading code.
>> Another option is to shadow randomElement on closed range to be non-optional.
>>
>>> But my suspicion is that lots of people will write things like this:
>>>
>>> guard let x = (0..<5).random()
>>> else { fatalError("not gonna happen") }
>>>
>>> I’d rather have the numeric methods trap than add the optional unwrapping
>>> step to every one of these calls. For me, getting a random number and
>>> picking a random element of a collection are two different operations—where
>>> it’s common to work with empty collections, especially in generic code,
>>> trying to get a random value from an empty range is really a programming
>>> error. I think it’s okay for them to have slightly different semantics.
>>>
>>> Nate
>>>
>>>
>>>> On Oct 5, 2017, at 12:27 PM, Alejandro Alonso <[email protected]>
>>>> wrote:
>>>>
>>>> Rather 0 ..< 0 my bad. I think if we include closedcountable, then there
>>>> needs to be support for countable, but there are edge cases where users
>>>> can input invalid ranges for countable.
>>>>
>>>> Enviado desde mi iPhone
>>>>
>>>> El oct. 5, 2017, a la(s) 12:22, Alejandro Alonso via swift-evolution
>>>> <[email protected]> escribió:
>>>>
>>>>> I agree with Ben here because users can still enter an invalid range with
>>>>> the static function. I.E. Int.random(in: 0 ... 0).
>>>>> I would really prefer excluding these static functions from numeric types.
>>>>>
>>>>> - Alejandro
>>>>>
>>>>> El oct. 5, 2017, a la(s) 12:03, Nate Cook via swift-evolution
>>>>> <[email protected]> escribió:
>>>>>
>>>>>>> On Oct 5, 2017, at 11:30 AM, Ben Cohen via swift-evolution
>>>>>>> <[email protected]> wrote:
>>>>>>>
>>>>>>>> On Oct 4, 2017, at 9:12 PM, Chris Lattner via swift-evolution
>>>>>>>> <[email protected]> wrote:
>>>>>>>>
>>>>>>>>> ```
>>>>>>>>> extension Int {
>>>>>>>>> static func random(in range: Countable{Closed}Range<Int>) -> Int
>>>>>>>>> }
>>>>>>>>
>>>>>>>> Nice. Should these be initializers like:
>>>>>>>>
>>>>>>>> extension Int {
>>>>>>>> init(randomIn: Countable{Closed}Range<Int>)
>>>>>>>> }
>>>>>>>>
>>>>>>>
>>>>>>> I don’t see much of a case for making it it random(in:
>>>>>>> SpecificCollection) instead of genericCollection.random().
>>>>>>
>>>>>> I see a couple points in favor of these static methods (or initializers)
>>>>>> on the numeric types:
>>>>>>
>>>>>> 1) The collection method will need to return an optional to match the
>>>>>> semantics of existing methods (like min()). If this is the only method
>>>>>> available, every time someone needs a random value in the range 1...10,
>>>>>> they’ll need to unwrap the result (with either force unwrapping, which
>>>>>> people will complain about, or some kind of conditional binding, which
>>>>>> is its own problem). Even if the semantics are the same (trapping on an
>>>>>> empty range), the user experience of using a non-optional method will be
>>>>>> better.
>>>>>>
>>>>>> 2) Floating-point ranges won’t get the collection method, so either
>>>>>> we’ll have inconsistent APIs (random FP value is non-optional, random
>>>>>> integer is optional) or we’ll make the FP API optional just to match.
>>>>>> Both of those seem bad.
>>>>>>
>>>>>>> One possible reason is if you exclude half-open ranges, only having
>>>>>>> CountableClosedRange, then you don’t have to account for the
>>>>>>> possibility of an empty collection (via an optional or a trap) because
>>>>>>> they cannot be empty. But closed ranges aren’t the currency type –
>>>>>>> half-open ranges are. So it’d hit usability if you have to convert from
>>>>>>> one to t'other often.
>>>>>>>
>>>>>>> Other possibility is discovery. But given the common use case is
>>>>>>> “random element from collection”, I don’t expect this to be an issue as
>>>>>>> it will quickly become common knowledge that this feature is available.
>>>>>>
>>>>>> Agreed here—I don’t think discovery is really an issue between the two
>>>>>> kinds. However, I don’t think the overlap in features (two ways to
>>>>>> generate random integers) are a problem, especially as we’d have better
>>>>>> alignment between integer and floating-point methods.
>>>>>>
>>>>>> Nate
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> [email protected]
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected]
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected]
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution