[swift-evolution] Let range operators always return empty ranges if the upper bound is smaller than the lower bound.
Kevin Ballard
kevin at sb.org
Wed Jan 20 15:09:44 CST 2016
I'm a minor -1 as well. I think there's value in catching logic errors like this. I'd rather see a ..<? or ...? operator that introduces this behavior.
FWIW, the Range type doesn't actually test this at all. You can say `Range(start: 2, end: 1)` just fine, since Range can be used with elements that aren't Comparable. It's just an overload on ... and ..< for Comparable elements that adds the check.
Also, if we change Range, we'll also need to change ClosedInterval and HalfOpenInterval (both of which include the end >= start check in their initializer, since they maintain an invariant that end >= start, rather than checking in the ... / ..< operators). But unfortunately, this means that the only way to make `2...1` work for ClosedInterval is to relax the invariant that says that end >= start, and I don't feel comfortable doing that. I think that invariant is important to maintain.
The end result of all this is I think we can safely introduce ..<? / ...? operators for Range that require a Comparable element, which make the end of the range equal to the start if it would otherwise be less (because `Range(start: 2, end: 1)` isn't actually empty, instead it contains all values starting at two and incrementing until wraparound hits 1). But the operators wouldn't be able to produce intervals, and wouldn't work for non-comparable elements (the normal ..< / ... operators work just fine on non-comparable elements already). Basically, something like
public func ..< <Pos : ForwardIndexType where Pos : Comparable>(start: Pos, end: Pos) -> Range<Pos> {
return Range(start: start, end: max(start, end))
}
public func ... <Pos : ForwardIndexType where Pos : Comparable>(start: Pos, end: Pos) -> Range<Pos> {
let end = max(start, end)
_precondition(end.successor() > end, "Range end index has no valid successor")
return Range(start: start, end: end.successor())
}
-Kevin Ballard
On Wed, Jan 20, 2016, at 11:42 AM, Jordan Rose via swift-evolution wrote:
> I'm a minor -1; it feels like this is in the same family as nil-messaging in that it can silently treat invalid input as a no-op. I'm not convinced that "upper bound less than the lower bound" is a strong enough signal for "empty" rather than "logic error". But it seems I'm in the minority.
>
> Jordan
>
>
> > On Jan 19, 2016, at 12:46, Uwe Falck via swift-evolution <swift-evolution at swift.org> wrote:
> >
> > I’m looking for feedback on this request if its worth to start an evolution proposal.
> >
> >
> > Let range operators always return empty ranges if the upper bound is smaller than the lower bound.
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list