[swift-evolution] [Idea] Add `bounds` function to standard library

Tim Vermeulen tvermeulen at me.com
Mon Aug 29 12:25:33 CDT 2016


What would the point of a free function be if you already have a protocol extension?

> Georgios, Yes lets go with clamp for a name!
> 
> Pyry, Originally I thought of just adding a global function akin to `min`
> and `max` but I am also
> in favour of adding the above extension to `Comparable`.
> I think having both the global function and the protocol extension for
> `clamp` would be great.
> 
> - Nick
> 
> 
> On Thu, Aug 25, 2016 at 9:37 PM, Pyry Jahkola<pyry.jahkola at iki.fi>wrote:
> 
> > On 25 Aug 2016, at 12:05, Nicholas Maccharoli wrote:
> > 
> > I personally see merit in adding a function to bound the value of a
> > variable within a range and think it would be simple to write with the
> > existing implementations of `min` and `max` with something like:
> > 
> > public func bounds<T : Comparable>(value: T, _ lower: T, _ upper: T)
> > ->T {
> > return max(lower, min(value, upper))
> > }
> > 
> > Does this sound like something the community thinks would be worthwhile to
> > add?
> > 
> > 
> > I'd welcome that addition. In terms of function interface, I think we can
> > do better than the 3-argument `clamp(x, min, max)` function that is seen
> > in several math libraries.
> > 
> > Our ***Range types already have a `clamped(to:)` member function, e.g. here's
> > one for ClosedRange
> > <https://developer.apple.com/reference/swift/closedrange/1779071-clamped>.
> > It creates a new range constraining the receiver's bounds within the new
> > bounds given as argument.
> > 
> > I think the sensible thing would be to add a similar, and equally named,
> > method to the Comparable protocol, taking in the ClosedRange<Self>to
> > limit the value to:
> > 
> > extension Comparable {
> > public func clamped(to limits: ClosedRange<Self>) ->Self {
> > return self<limits.lowerBound ? limits.lowerBound
> > : self>limits.upperBound ? limits.upperBound
> > : self
> > }
> > }
> > 
> > (-0.1).clamped(to: 0 ... 1) // 0.0
> > 3.14.clamped(to: 0 ... .infinity) // 3.14
> > "foo".clamped(to: "a" ... "f") // "f"
> > "foo".clamped(to: "a" ... "g") // "foo"
> > 
> > From my experience, I'd say it'd be most useful for clamping
> > floating-point numbers and collection indices.
> > 
> > — Pyry
> 
> 
> 


More information about the swift-evolution mailing list