Brent--<br><br>In general, I agree with the direction of your thinking. Time constraints prevent me from responding as thoroughly as I&#39;d like, but briefly, where we don&#39;t agree at the moment boil down to a few points:<br><br>* Agree that &quot;to&quot; vs &quot;through&quot; is not ideal. However, having spent a lot of time on this issue, I&#39;m quite convinced there is no single word in English that will accurately describe the distinction. Certainly, we can mimic the English language by doing something like `stride(from: a, to: b, .exclusive, by: c)`. However, one other solution to provide clarity is to pick a convention and solidify user understanding by frequent and consistent use, which is the diametric opposite of your stance that we shouldn&#39;t use the convention elsewhere.<br><br>In general, I think we contort ourselves in the wrong way when the first listed motivation for a new feature is to work around a naming difficulty: the solution to not having found the right name is to find the right name.<br><br>* It is not redundant API simply because the same thing can be achieved by composing two other functions. One must assess ergonomics, footgun likelihood, etc. But in any case, the point you make here is equally applicable to your proposed feature, i.e. arr[0...][..&lt;2] == arr[0..&lt;2].<br><br>* I fully expect subscript labels to start making an appearance in stdlib APIs sooner or later. I don&#39;t think its absence is indicative of a conscious rejection of them, just that they haven&#39;t been needed. (Lenient subscripts will one day make an appearance, given how often it&#39;s requested, and I sure hope they are labeled.)<br><br>* Disagree that the labeled subscript is ad-hoc. In the contrary, I think &quot;incomplete ranges&quot; are the more ad-hoc choice for array subscripting. My point is that an &quot;incomplete range&quot; is, by definition, not a range; it is a bound, which is an Index. We don&#39;t need a wrapper around the Index in the form of IncompleteRange&lt;Index&gt; because it provides little if any semantic value: the bounds of such a range are not knowable divorced from the sequence being indexed, and so the upperboundedness or lowerboundedness of IncompleteRange&lt;Index&gt; is not a useful piece of information without the sequence. Thus, it is more appropriately a label when you invoke a subscript on a sequence, not a property of the argument, which is a bound.<br><br>* Removing one of the bounds _is_ a natural impulse, but the natural result one would expect to get is a half-unbounded range (i.e. infinite range), not an &quot;incomplete range.&quot; As I argued above, one must distinguish these semantics. You are proposing something with the semantics of an &quot;incomplete range.&quot;<br><br>* Your example of switch statements is (a) mostly sugar (the exhaustiveness checking made possible could also be proposed independent of syntax changes); and (b) arguably an infinite range in semantics. I&#39;ll have to think more on this, though.<br><br>Bottom line, I can support an infinite range, but I don&#39;t think I like the idea of an &quot;incomplete range.&quot; An &quot;incomplete range&quot; is an Index used as a lower or upper bound and should be expressed as a plain Index, because it is not a range. An infinite range, OTOH, is a range. However, the array subscripting use case is not a use case for infinite ranges, as I&#39;ve argued above.<br><div class="gmail_quote"><div dir="ltr">On Wed, Feb 1, 2017 at 08:29 Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com">matthew@anandabits.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br class="gmail_msg">
&gt; On Feb 1, 2017, at 6:58 AM, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;&gt; On Jan 31, 2017, at 2:04 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg">
&gt;&gt;<br class="gmail_msg">
&gt;&gt; Therefore I&#39;d conclude that `arr[upTo: i]` is the most consistent spelling. It also yields the sensible result that `arr[from: i][upTo: j] == arr[upTo: j][from: i] == arr[i..&lt;j]`.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; There&#39;s a lot I dislike about `subscript(upTo/through/from:)`:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; 1. We have not previously been very satisfied with how understandable these labels are—for instance, we fiddled around with them a lot when we were looking at `stride(from:to/through:by:)` in Swift 3, and eventually settled on the originals because we couldn&#39;t find anything better. I don&#39;t think entrenching them further makes very much sense.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; 2. The fact that you *can* write `arr[from: i][upTo: j]`, and that this is equivalent to both `arr[upTo: j][from: i]` and `arr[i..&lt;j]`, seems a bit weird. We aren&#39;t typically in the habit of providing redundant APIs like this.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; 3. Neither Stdlib nor the Apple frameworks currently contain *any* labeled subscripts, so this design would be unprecedented in the core language.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; 4. After a new programmer learns about subscripting with two-sided ranges, removing one of the bounds is a straightforward extension of what they already know. The argument label solution is more ad-hoc.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; 5. The argument label solution solves the immediate problem, but doesn&#39;t give us anything else.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; To understand what I mean by #5, consider the implementation. The plan is to introduce a `RangeExpression` protocol:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       protocol RangeExpression {<br class="gmail_msg">
&gt;               associatedtype Bound: Comparable<br class="gmail_msg">
&gt;               func relative&lt;C: Collection(to collection: C) where C.Index == Bound -&gt; Range&lt;Bound&gt;<br class="gmail_msg">
&gt;       }<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; And then reduce the many manually-generated variants of `subscript(_: Range&lt;Index&gt;)` in `Collection` to just two:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       protocol Collection {<br class="gmail_msg">
&gt;               ...<br class="gmail_msg">
&gt;               subscript(bounds: Range&lt;Index&gt;) -&gt; SubSequence { get }<br class="gmail_msg">
&gt;               ...<br class="gmail_msg">
&gt;       }<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       extension Collection {<br class="gmail_msg">
&gt;               ...<br class="gmail_msg">
&gt;               subscript&lt;Bounds: RangeExpression&gt;(bounds: Bounds) where Bounds.Bound == Index -&gt; SubSequence {<br class="gmail_msg">
&gt;                       return self[bounds.relative(to: self)]<br class="gmail_msg">
&gt;               }<br class="gmail_msg">
&gt;               ...<br class="gmail_msg">
&gt;       }<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; This design would automatically, source-compatibly, handle several different existing types you can slice with:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; * ClosedRange<br class="gmail_msg">
&gt; * CountableRange<br class="gmail_msg">
&gt; * CountableClosedRange<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; Plus the new types associated with incomplete ranges:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; * IncompleteRange<br class="gmail_msg">
&gt; * IncompleteClosedRange<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; Plus anything else we, or users, might want to add. For instance, I have a prototype built on `RangeExpression` which lets you write things like:<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt;       myString[.startIndex + 1 ..&lt; .endIndex - 1]<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; This strikes me as a pretty cool thing that some people might want.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; Similarly, IncompleteRange and IncompleteClosedRange can most likely be put to other uses. They could easily fill a gap in `switch` statements, which don&#39;t have a good way to express open-ended comparisons except with a `where` clause. As some have mentioned, when applied to a `Strideable` type they *could* be treated as infinite sequences, although it&#39;s not clear if we really want to do that. And, you know, sometimes you really *do* have a case where one or both bounds of a range may be missing in some cases; incomplete ranges are a built-in, batteries-included way to model that.<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; To put it simply, slicing with incomplete ranges gives us several valuable tools we can apply to other problems. Labeled subscripts, on the other hand, are just another weird little thing that you have to memorize, and probably won’t.<br class="gmail_msg">
<br class="gmail_msg">
+1 in general.  But I’m still curious how postfix `…` would impact our options for variadic generics and tuple unpacking in the future.<br class="gmail_msg">
<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; --<br class="gmail_msg">
&gt; Brent Royal-Gordon<br class="gmail_msg">
&gt; Architechies<br class="gmail_msg">
&gt;<br class="gmail_msg">
&gt; _______________________________________________<br class="gmail_msg">
&gt; swift-evolution mailing list<br class="gmail_msg">
&gt; <a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div>