[swift-evolution] [draft] Add `clamped(to:)` to the stdlib

Jaden Geller jaden.geller at gmail.com
Sun Mar 12 17:44:59 CDT 2017


+1

I think `clamp` is a very reasonable function to include in the standard library. The semantics are clear, and it is definitely much easier to read than the alternative.

I think we should also include an open range variant. Note that this is only defined on types with integer strides since the semantics only make sense when values of the type are discrete.

extension Strideable where Stride: Integer {
    func clamped(to range: Range<Self>) -> Self {
        return clamped(to: range.lowerBound...(range.upperBound - 1))
    }
}

Cheers,
Jaden Geller

> On Mar 12, 2017, at 10:16 AM, Nicholas Maccharoli via swift-evolution <swift-evolution at swift.org> wrote:
> 
> ​Swift-Evolution.
> 
> This is a draft of a proposal adding `clamped(to:)` as an extension on `Comparable`.
> For now I have only included a version of the `clamped(to:)` function that accepts `ClosedRange` but if the community decided that it is feasible to add a version that takes half open ranges I would also love to include that as well in this proposal. 
> 
> That you so much for the feedback so far and I am looking forward 
> to the community's feedback on this draft. 
> 
> - Nick 
> 
> 
> Add clamp​ed​(to:) to the stdlib
> 
> Proposal: SE-NNNN <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-filename.md>
> Authors: Nicholas Maccharoli <https://github.com/Nirma>
> Review Manager: TBD
> Status: Awaiting review
> During the review process, add the following fields as needed:
> 
> Decision Notes: Rationale <https://lists.swift.org/pipermail/swift-evolution/>, Additional Commentary <https://lists.swift.org/pipermail/swift-evolution/>
> Bugs: SR-NNNN <https://bugs.swift.org/browse/SR-NNNN>, SR-MMMM <https://bugs.swift.org/browse/SR-MMMM>
> Previous Revision: 1 <https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/NNNN-filename.md>
> Previous Proposal: SE-XXXX <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/XXXX-filename.md>
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#introduction>Introduction
> 
> This proposal aims to add functionality to the standard library for clamping a value to a ClosedRange. The proposed function would allow the user to specify a range to clamp a value to where if the value fell within the range, the value would be returned as is, if the value being clamped exceeded the upper or lower bound in value the value of the boundary the value exceeded would be returned.
> 
> Swift-evolution thread: Add a clamp function to Algorithm.swift <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170306/thread.html#33674>
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#motivation>Motivation
> 
> There have been quite a few times in my professional and personal programming life where I reached for a clampedfunction and was disappointed it was not part of the standard library.
> 
> Having functionality like clamped(to:) added to Comparable as a protocol extension would benefit users of the Swift language who wish to guarantee that a value is kept within bounds.
> 
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#proposed-solution>Proposed solution
> 
> The solution proposed is simply that there be a clamped(to:) function added to the Swift Standard Library. The function would behave much like its name describes.
> 
> Given a clamped(to:) function existed it could be called in the following way, yielding the results in the adjacent comments:
> 
> var foo = 100
> foo.clamp(to: 0...50) // 50
> foo.clamp(to: 200...300) // 200
> foo.clamp(to: 0...150) // 100
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#detailed-design>Detailed design
> 
> The implementation for clamped(to:) as an extension to Comparable accepting a range of type ClosedRange<Self>would look like the following:
> 
> extension Comparable {
>     func clamped(to range: ClosedRange<Self>) -> Self {
>         if self > range.upperBound {
>             return range.upperBound
>         } else if self < range.lowerBound {
>             return range.lowerBound
>         } else {
>             return self
>         }
>     }
> }
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#source-compatibility>Source compatibility
> 
> This feature is purely additive; it has no effect on source compatibility.
> 
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#effect-on-abi-stability>Effect on ABI stability
> 
> This feature is purely additive; it has no effect on ABI stability.
> 
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#effect-on-api-resilience>Effect on API resilience
> 
> The proposed function would become part of the API but purely additive.
> 
>  <https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md#alternatives-considered>Alternatives considered
> 
> clamped(to:) could be made a global function like min and max but a protocol extension seems like a better choice.​
> _______________________________________________
> 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/20170312/165ff273/attachment.html>


More information about the swift-evolution mailing list