[swift-evolution] Add a `clamp` function to Algorithm.swift

Xiaodi Wu xiaodi.wu at gmail.com
Fri Mar 10 18:05:26 CST 2017


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.


On Fri, Mar 10, 2017 at 4:48 PM, James Froggatt via swift-evolution <
swift-evolution at swift.org> 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
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170310/51da2b70/attachment.html>


More information about the swift-evolution mailing list