> 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
