Pitch: Offsetting Indices and Relative Ranges

Currently, if you say a..<b it will invoke an overload of the operator ..<. There is one generic over Comparable which produces a Range<T>. There's a bunch of hacks overloads that mimic omitted arguments, though they lose some precedence information.

But, what if you wanted to have your own kind of range type that could be produced by ..<. You might consider adding an overload of ..<, but that could clash and become ambiguous with Range's, as is what happened here. You run this risk if there's any overlap between your bounds types and Comparable. Also, for completeness, you'd add an overload of infix ..., prefix ..., postfix ..., prefix ..<, and no-fix .... Also, you'd probably want to add more overloads as in here because prefix and postfix don't have the right precedence.

This is faking language syntax with operators. You're also replacing something pretty fast (parsing) with something slow (overload resolution in the presence of Swift's rich type system). If you wanted to extend this fake syntax further, you'd use more operators, which restricts you to the operator name space (e.g. -> and : are not available). If instead we had a range-expr, such as (total strawman and completely off-the-cuff):

range-expr -> expression? ... expression?
range-expr -> expression? ..< expression

This would express syntactically what we're getting at with operators. Then, the semantics could be that this is similar to other kinds of library-directed expressions, such as literals and string interpolations, so that some conformance to ExpressibleByRangeExpression is invoked with the kind of expression that was written and the left-hand side and right-hand side. The default would be the existing Range structs.

Then, if we wanted to extend this with say -> and <- to apply a relative offset, we could do something like that (hand-wavy):

index-expression -> expression -> integer-expression
index-expression -> expression <- integer-expression

And get the precedence we want out of it. Again, this is super hand-wavy and we'd want to tighten it down some and make sure we don't accidentally lose the ability for e.g. generalized destructuring pattern matching with <-.