[swift-evolution] [Proposal] Add clamp(to:) to the stdlib

Nicholas Maccharoli nmaccharoli at gmail.com
Thu Mar 23 23:14:38 CDT 2017


Sorry did I skip a step in the proposal process?

On Tue, Mar 21, 2017 at 7:09 PM, Nicholas Maccharoli <nmaccharoli at gmail.com>
wrote:

> ​Swift-Evolution,
>
> I propose that `clamp(to:)` be added to the standard library as detailed
> in the proposal written below.
> There is also an open pull request to the swift-evolution repository open
> here:
>
> https://github.com/apple/swift-evolution/pull/641
>
> The idea was discussed on previous threads and a few people helped make
> the draft proposal better.
> Since the reception of the ​idea was overall good, I thought it might be
> worth it
> to formally propose the idea.
>
> Please tell me what you think.
>
> - Nick
>
> Add clamp(to:) to the stdlib
>
>    - Proposal: SE-NNNN
>    <https://github.com/Nirma/swift-evolution/blob/2ecfd45f4636e44f1000177fa509b1412cebef92/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/2ecfd45f4636e44f1000177fa509b1412cebef92/proposals/XXXX-filename.md>
>
>
> <https://github.com/Nirma/swift-evolution/blob/2ecfd45f4636e44f1000177fa509b1412cebef92/proposals/NNNN-add-clamp-function.md#introduction>
> Introduction
>
> This proposal aims to add functionality to the standard library for
> clamping a value to a provided Range. 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/2ecfd45f4636e44f1000177fa509b1412cebef92/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 function to limit a value to a given
> range and was disappointed it was not part of the standard library.
>
> There already exists an extension to CountableRange in the standard
> library implementing clamped(to:) that will limit the calling range to
> that of the provided range, so having the same functionality but just for
> types that conform to the Comparable protocol would be conceptually
> consistent.
>
> 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, perhaps one example of this coming in
> handy would be to limit the result of some calculation between two
> acceptable numerical limits, say the bounds of a coordinate system.
>
> <https://github.com/Nirma/swift-evolution/blob/2ecfd45f4636e44f1000177fa509b1412cebef92/proposals/NNNN-add-clamp-function.md#proposed-solution>Proposed
> solution
>
> The proposed solution is to add a clamped(to:) function to the Swift
> Standard Library as an extension to Comparable and Strideable. The
> function would return a value within the bounds of the provided range, if
> the value clamped(to:) is being called on falls within the provided range
> then the original value would be returned. If the value was less or greater
> than the bounds of the provided range then the respective lower or upper
> bound of the range would be returned.
>
> It does not make sense to call clamped(to:) with an empty range,
> therefore calling clamped(to:) and passing an empty range like foo.clamped(to:
> 0..<0) would result in a fatal error.
>
> Given a clamped(to:) function existed it could be called in the following
> way, yielding the results in the adjacent comments:
>
> let foo = 100
> // Closed range variant
> foo.clamped(to: 0...50) // 50foo.clamped(to: 200...300) // 200foo.clamped(to: 0...150) // 100// Half-Open range variant
> foo.clamped(to: 0..<50) // 49foo.clamped(to: 200..<300) // 200foo.clamped(to: 0..<150) // 100
>
>
> <https://github.com/Nirma/swift-evolution/blob/2ecfd45f4636e44f1000177fa509b1412cebef92/proposals/NNNN-add-clamp-function.md#detailed-design>Detailed
> design
>
> The implementation of clamped(to:) that is being proposed is composed of
> two protocol extensions; one protocol extension on Comparable and another
> on Strideable.
>
> 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
>         }
>     }
> }
>
> The implementation of clamped(to:) as an extension on Strideable would be
> confined to cases where the stride is of type Integer. The implementation
> would be as follows:
>
> extension Strideable where Stride: Integer {
>     func clamped(to range: Range<Self>) -> Self {
>         guard !range.isEmpty { fatalError("Can not clamp to an empty range.") }
>         return clamped(to: range.lowerBound...(range.upperBound - 1))
>     }
> }
>
>
> <https://github.com/Nirma/swift-evolution/blob/2ecfd45f4636e44f1000177fa509b1412cebef92/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/2ecfd45f4636e44f1000177fa509b1412cebef92/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/2ecfd45f4636e44f1000177fa509b1412cebef92/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/2ecfd45f4636e44f1000177fa509b1412cebef92/proposals/NNNN-add-clamp-function.md#alternatives-considered>Alternatives
> considered
>
> Aside from doing nothing, no other alternatives were considered.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170324/d0887f42/attachment.html>


More information about the swift-evolution mailing list