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


(Nicholas Maccharoli) #1

​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) // 50foo.clamp(to: 200...300) //
200foo.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.​


applyCap and applyThreshold
(Jaden Geller) #2

+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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jaden Geller) #3

You definitely ought to add “do nothing” to the alternative considered section. Also, any reason you didn’t implement `clamped` in terms of `min` and `max`?

···

On Mar 12, 2017, at 10:16 AM, Nicholas Maccharoli via swift-evolution <swift-evolution@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Nicholas Maccharoli) #4

Jaden,

Awesome feedback, and yes I totally agree that support for Half-Open ranges
would be awesome so I updated the proposal adding your code and also
updating the example code in the motivation to include the Half-Open range
variant and updating the "Alternatives Considered" section to accurately
reflect that no alternatives have been considered.

As for the implementation, an implementation using min-max would also be
fine but I thought although a little verbose using an if-if-else-else
clause would read a little easier.

I personally think either way is great, just thought I would try an
alternative.

- Nick

Add clamp(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
// 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/clamp_function/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 {
        return clamped(to: range.lowerBound...(range.upperBound - 1))
    }
}

<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

Aside from doing nothing, no other alternatives were considered.

···

On Mon, Mar 13, 2017 at 7:47 AM, Jaden Geller <jaden.geller@gmail.com> wrote:

You definitely ought to add “do nothing” to the alternative considered
section. Also, any reason you didn’t implement `clamped` in terms of `min`
and `max`?

On Mar 12, 2017, at 10:16 AM, Nicholas Maccharoli via swift-evolution < > swift-evolution@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) // 50foo.clamp(to: 200...300) // 200foo.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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Nicholas Maccharoli) #5

As a side note, if anyone is interested the proposal markdown can be cloned
from the fork I made of the swift-evolution repository here:

https://github.com/Nirma/swift-evolution/blob/clamp_function/proposals/NNNN-add-clamp-function.md

- Nick

···

On Mon, Mar 13, 2017 at 10:21 AM, Nicholas Maccharoli <nmaccharoli@gmail.com > wrote:

Jaden,

Awesome feedback, and yes I totally agree that support for Half-Open
ranges would be awesome so I updated the proposal adding your code and also
updating the example code in the motivation to include the Half-Open range
variant and updating the "Alternatives Considered" section to accurately
reflect that no alternatives have been considered.

As for the implementation, an implementation using min-max would also be
fine but I thought although a little verbose using an if-if-else-else
clause would read a little easier.

I personally think either way is great, just thought I would try an
alternative.

- Nick

Add clamp(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
// 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/clamp_function/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 {
        return clamped(to: range.lowerBound...(range.upperBound - 1))
    }
}

<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

Aside from doing nothing, no other alternatives were considered.

On Mon, Mar 13, 2017 at 7:47 AM, Jaden Geller <jaden.geller@gmail.com> > wrote:

You definitely ought to add “do nothing” to the alternative considered
section. Also, any reason you didn’t implement `clamped` in terms of `min`
and `max`?

On Mar 12, 2017, at 10:16 AM, Nicholas Maccharoli via swift-evolution < >> swift-evolution@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) // 50foo.clamp(to: 200...300) // 200foo.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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution