> On 11 Mar 2017, at 00:21, James Froggatt <[email protected]> wrote:
> 
> 
>> On 11 Mar 2017, at 00:05, Xiaodi Wu <[email protected]> wrote:
>> 
>> Some days ago, Ben Cohen laid out the criteria for helper functions in the 
>> Standard Library. Here's some of his very enlightening text and the six 
>> criteria:
>> 
>>> The operation needs to carry its weight. Even once we have ABI stability, 
>>> so the size of the std lib becomes less of a concern as it could ship as 
>>> part of the OS, we still need to keep helper method growth under control. 
>>> APIs bristling with methods like an over-decorated Xmas tree are bad for 
>>> usability. As mentioned in the String manifesto, String+Foundation 
>>> currently has over 200 methods/properties. Helpers are no good if you can’t 
>>> find them to use them.
>>  
>>> 1. Is it truly a frequent operation?
>>> 2. Is the helper more readable? Is the composed equivalent obvious at a 
>>> glance?
>>> 3. Does the helper have the flexibility to cover all common cases?
>>> 4. Is there a correctness trap with the composed equivalent? Is there a 
>>> correctness trap with the helper?
>>> 5. Is there a performance trap with the composed equivalent? Or with the 
>>> helper?
>>> 6. Does the helper actually encourage misuse?
>> 
>> 
>> The reasons I'm opposed to adding `clamp` are as follows:
>> 
>> It is trivially composed from `min` and `max`, with no correctness traps.
>> 
>> As the discussion above shows, there are correctness traps when you have a 
>> `clamp` operation that takes open ranges, whereas the composed form using 
>> `min` and `max` does not suffer from the same issue.
>> 
>> It encourages misuse, because Dave's desired use case (for indices) works 
>> *only* for arrays and falls down for collections. This is similar to the 
>> problem which motivates removal of `enumerated()` as discussed in other 
>> threads. In this case, it is not guaranteed that a collection with indices 
>> `0..<10` has an index 9.
>> 
> 
> You make a good point, but then how exactly did the range-clamping function 
> make it into the standard library in the first place? I can't think of 
> frequent reason to want to clamp a range to within another range putting my 
> mind to it, yet a clamp function on the Bound type has uses with arrays and 
> offers a clear improvement to readability. Then there's the (potential) 
> correctness trap of mixing up min and max, which I find leads me to need to 
> double-check the logic after typing.
> 
> Seeing those criteria just makes it all the more frustrating that the 
> range-clamping version is the one to have made the cut.

Rereading, you're point is that the range-clamping version does solve a 
correctness trap (and that the Bound version does not?). Could you explain how 
you reached to this conclusion?

>> 
>> On Fri, Mar 10, 2017 at 4:48 PM, James Froggatt via swift-evolution 
>> <[email protected]> wrote:
>>> This topic caught my attention. I support the idea, I'm currently using an 
>>> extension for this.
>>> 
>>> >>Should “16.clamped(to: 0..<10)” produce 9 or 10?
>>> 
>>> >9
>>> 
>>> Sounds good.
>>> 
>>> >>What about “16.clamped(to: 0..<0)”, which is an empty range?
>>> 
>>> >For `Int`? Crash (which, until about 5 minutes ago, is what I thought 
>>> >would happen if you tried to create a range that’s empty like that). For 
>>> >types that support it, I’d say NaN or something like “nil”/“empty” is the 
>>> >most appropriate return value
>>> 
>>> Nasty but reasonable. I'd support it returning nil in this case, this would 
>>> provide a warning that the result may not be a valid number, as well as 
>>> providing this elegant range validation:
>>> 
>>> `if let index = candidate.clamped(to: array.indices) { … }`
>>> 
>>> (or a possible alternative spelling:)
>>> 
>>> `if let index = array.indices.clamp(candidate) { … }`
>>> 
>>> >>Does “16.0.clamped(to: 0..<10)” yield 10.0 or the next-smaller 
>>> >>representable Double?
>>> 
>>> >Next-smaller, IMHO. It’s not exactly semantically correct, but AFAIK 
>>> >that’s as correct as Float/Double can be.
>>> 
>>> One could argue the most ‘correct’ value here is the closest representation 
>>> of the theoretical value, `10.0 - (1 / ∞)`, which should clearly round to 
>>> 10. However, this also rounds the result back out of the range, meaning 
>>> it's unsuitable as a result. Both possibilities are, for lack of a better 
>>> word, ugly.
>>> 
>>> >Mostly though I’d really like to be able to clamp to array indices, which 
>>> >are pretty much always written as a `Range`, rather than a `ClosedRange`. 
>>> >We could write the function for `Range` to only be generic over 
>>> >`Comparable&Integer`, if the floating point corner cases are too much.
>>> 
>>> > - Dave Sweeris
>>> 
>>> My conclusion also. I'd like to see this added to the standard library, if 
>>> it's in scope for Swift 4.
>>> 
>>> Sidenote: I can't help but think index validation would be better solved in 
>>> many cases by an optional-returning array subscript (`array[ifPresent: 
>>> index]`), but I've seen this solution turned down several times due to the 
>>> lack of discoverability (read: lack of Xcode autocompletion, which I 
>>> originally thought was a bug until it stayed that way for ~3 years). I'd 
>>> also like to see this feature get added in some form, eventually.
>>> _______________________________________________
>>> 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

Reply via email to