# ClosedRange init with unordered bounds

Hello Swift Community.

During discussion of clamped function Add a `clamp` function to Algorithm.swift, it was found an interesting case with Ranges initialization.

``````func doSomething(val1: Double, val2: Double) {
let offset = 10.clamped(to: val1...val2)
}
``````

If val1 > val2, the app will crash with error "Can't form Range with upperBound < lowerBound"
To prevent this, we are forced to check that val1 < val2 every time, which is annoying.

``````let offset = 10.clamped(to: val1 <= val2 ? val1...val2 : val2...val1)
``````

There also other situations, where Range bounds come from function arguments and because of that can't be checked at compile time:

``````func validatePaymentAmount(_ amount: Int, minAmount: Int, maxAmount: Int) -> ValidationResult {
let validRange = ClosedRange(uncheckedBounds: (minAmount, maxAmount))
}

func didEndEditing(text: String) {
let validator = SymbolsCountValidator(validCount: ClosedRange(uncheckedBounds: (lowerBound, upperBound))
}

let horizontalArea = ClosedRange(uncheckedBounds: (view1.frame.origin.x, view2.frame.origin.x)
``````

## Proposed solution

The idea is to add new initializer to Range, thanks to @benrimmington

``````extension ClosedRange {
init(unorderedBounds: (leftBound: Bound, rightBound: Bound)) {
let (leftBound, rightBound) = unorderedBounds

let bounds: (lower: Bound, upper: Bound) = (leftBound <= rightBound ? (leftBound, rightBound) : (rightBound, leftBound))

self.init(uncheckedBounds: bounds)
}
}
``````

## Source compatibility

This change is purely additive and should not affect source compatibility.

No known effect.

## Effect on API resilience

No known effect.

1 Like

If the intention is that the bounds are unordered, what is the meaning of â€śleftâ€ť and â€śrightâ€ť here, and why do they need to be labeled?

1 Like

â€śleftâ€ť and â€śrightâ€ť are used here as an example and for readability, keeping in mind number axis. I don't propose for this variant. We can just as well use "firstBound" / "secondBound" names or even unlabeled tuple.

My own thoughts now is that labeled tuple is better than unlabeled.

1. labeled variables are not visible form the call site, ClosedRange(unorderedBounds: (1, 3)).
In that time, they are visible when reading method documentation and declaration.
2. "firstBound" / "secondBound" seems to be more suitable than "leftBound" / "rightBound"

Who do others think?