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

James Froggatt james.froggatt at me.com
Fri Mar 10 16:48:14 CST 2017


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.


More information about the swift-evolution mailing list