<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 31, 2017, at 4:20 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">On Tue, Jan 31, 2017 at 6:15 PM, Jaden Geller<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:jaden.geller@gmail.com" target="_blank" class="">jaden.geller@gmail.com</a>&gt;</span><span class="Apple-converted-space">&nbsp;</span>wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><div class=""><div class="h5"><blockquote type="cite" class=""><div class="">On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-4249512996091649943Apple-interchange-newline"><div class=""><div style="word-wrap: break-word;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-4249512996091649943Apple-interchange-newline"><div class=""><div dir="ltr" class="">On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:davesweeris@mac.com" target="_blank" class="">davesweeris@mac.com</a>&gt;</span><span class="Apple-converted-space">&nbsp;</span>wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Jan 31, 2017, at 2:04 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="m_-4249512996091649943m_4871187344016849002Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution<span class="m_-4249512996091649943m_4871187344016849002Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evoluti<wbr class="">on@swift.org</a>&gt;</span><span class="m_-4249512996091649943m_4871187344016849002Apple-converted-space">&nbsp;</span>wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="auto" class=""><span class="m_-4249512996091649943m_4871187344016849002gmail-"><div class=""><br class=""></div><div class="">On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><span class="">I think that is perfectly reasonable, but then it seems weird to be able to iterate over it (with no upper bound) independently of a collection). It would surprise me if</span><br class=""><span class="">```</span><br class=""><span class="">for x in arr[arr.startIndex…] { print(x) }</span><br class=""><span class="">```</span><br class=""><span class="">yielded different results than</span><br class=""><span class="">```</span><br class=""><span class="">for i in arr.startIndex… { print(arr[i]) } // CRASH</span><br class=""><span class="">```</span><br class=""><span class="">which it does under this model.</span><br class=""></div></blockquote><br class=""></span><div class="">(I<span class="m_-4249512996091649943m_4871187344016849002Apple-converted-space">&nbsp;</span><i class="">think</i><span class="m_-4249512996091649943m_4871187344016849002Apple-converted-space">&nbsp;</span>this how it works... semantically, anyway) Since the upper bound isn't specified, it's inferred from the context.</div><div class=""><br class=""></div><div class="">In the first case, the context is as an index into an array, so the upper bound is inferred to be the last valid index.</div><div class=""><br class=""></div><div class="">In the second case, there is no context, so it goes to Int.max. Then,<span class="m_-4249512996091649943m_4871187344016849002Apple-converted-space">&nbsp;</span><i class="">after</i><span class="m_-4249512996091649943m_4871187344016849002Apple-converted-space">&nbsp;</span>the "wrong" context has been established, you try to index an array with numbers from the too-large range.</div><div class=""><br class=""></div><div class="">Semantically speaking, they're pretty different operations. Why is it surprising that they have different results?</div></div></blockquote><div class=""><br class=""></div><div class="">I must say, I was originally rather fond of `0...` as a spelling, but IMO, Jaden and others have pointed out a real semantic issue.</div><div class=""><br class=""></div><div class="">A range is, to put it simply, the "stuff" between two end points. A "range with no upper bound" _has to be_ one that continues forever. The upper bound _must_ be infinity.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Depends… Swift doesn’t allow partial initializations, and neither the `.endIndex` nor the `.upperBound` properties of a `Range` are optional. From a strictly syntactic PoV, a "Range without an upperBound” can’t exist without getting into undefined behavior territory.</div><div class=""><br class=""></div><div class="">Plus, mathematically speaking, an infinite range would be written "[x, ∞)", with an open upper bracket. If you write “[x, ∞]”, with a<span class="Apple-converted-space">&nbsp;</span><i class="">closed</i><span class="Apple-converted-space">&nbsp;</span>upper bracket, that’s kind of a meaningless statement. I would argue that if we’re going to represent that “infinite” range, the closest Swift spelling would be “x..&lt;“. That leaves the mathematically undefined notation of “[x, ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by similar reasoning can’t mean "(∞, x]”) return one of these:</div></div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">enum</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>IncompleteRange&lt;T</span><span style="font-variant-ligatures: no-common-ligatures;" class="">&gt; {</span></div></div></div><div class=""><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">case</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>upperValue(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">T</span><span style="font-variant-ligatures: no-common-ligatures;" class="">)</span></div></div></div><div class=""><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">case</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>lowerValue(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">T)</span></div></div></div><div class=""><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">}</span></div></div></div></blockquote><div class=""><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">which we could then pass to the subscript function of a collection to create the actual Range like this:</span></div></div></div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures;" class="">Collection</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>{</span></div></span></div></div></div><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">subscript</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">_</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>ir:<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">IncompleteRange</span><span style="font-variant-ligatures: no-common-ligatures;" class="">&lt;Index&gt;) -&gt; SubSequence {</span></div></span></div></div><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">switch</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>ir {</span></div></span></div></div><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">case</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>.</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">lowerValue</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>lower):<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">return</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">self</span><span style="font-variant-ligatures: no-common-ligatures;" class="">[lower ..&lt;<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">self</span><span style="font-variant-ligatures: no-common-ligatures;" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">endIndex</span><span style="font-variant-ligatures: no-common-ligatures;" class="">]</span></div></span></div></div><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">case</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>.</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(49, 89, 93);" class="">upperValue</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>upper):<span class="Apple-converted-space">&nbsp;</span></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">return</span><span style="font-variant-ligatures: no-common-ligatures;" class=""></span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">self</span><span style="font-variant-ligatures: no-common-ligatures;" class="">[</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">self</span><span style="font-variant-ligatures: no-common-ligatures;" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">startIndex</span><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-converted-space">&nbsp;</span>..&lt; upper]</span></div></span></div></div><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp; &nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span>}</span></div></span></div></div><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span>}</span></div></span></div></div><div class=""><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">}</span></div></span></div></div></blockquote></div></blockquote><div class=""><br class=""></div><div class="">I understand that you can do this from a technical perspective. But I'm arguing it's devoid of semantics.&nbsp; That is, it's a spelling to dress up a number.</div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">It’s not any more devoid of semantics than a partially applied function.&nbsp; It is a number or index with added semantics that it provides a lower (or upper) bound on the possible value specified by its type.</div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">If we treat it as such, we shouldn’t allow users to iterate over it directly:</div><div class="">```</div><div class="">for x in 0… { // &lt;- doesn’t make sense; only partially specified</div><div class="">&nbsp;<span class="Apple-converted-space">&nbsp;</span>print(“hi”)</div><div class="">}</div><div class="">```</div><div class=""><br class=""></div><div class="">We __could__ introduce 2 types, `IncompleteRange` and `InfiniteRange`, providing an overload that constructs each. It would never be ambiguous because `InfiniteRange&nbsp;` would be the only `Sequence` and `IncompleteRange` would be the only one of these two that is accepted as a collections subscript.</div><div class=""><br class=""></div><div class="">This *isn’t* that crazy either. There’s precedent for this too. The `..&lt;` operator used to create both ranges and intervals (though it seems those type have started to merge).</div><div class=""><br class=""></div><div class="">¯\_(ツ)_/¯</div></div></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Mercifully, those types have completely merged AFAIK. IMO, the long-term aim should be to have ... and ..&lt; produce only one kind of range.</div></div></div></div></div></blockquote><div><br class=""></div>There are still 2 variants (`Range` and `CountableRange`), but I imagine conditional conformances will combine those entirely.&nbsp;</div><div><br class=""></div><div>(I hope conditional conformances are still in scope for Swift 4. They seem to have a very significant ABI impact.)</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word;" class=""><div class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">What is such an `IncompleteRange&lt;T&gt;` other than a value of type T? It's not an upper bound or lower bound of anything until it's used to index a collection. Why have a new type (IncompleteRange&lt;T&gt;), a new set of operators (prefix and postfix range operators), and these muddied semantics for something that can be written `subscript(upTo upperBound: Index) -&gt; SubSequence { ... }`? _That_ has unmistakable semantics and requires no new syntax.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Arguing that it adds too much complexity relative to the value it provides is reasonable.&nbsp; The value in this use case is mostly syntactic sugar so it’s relatively easy to make the case that it doesn’t cary its weight here.</div><div class=""><br class=""></div><div class="">The value in Ben’s use case is a more composable alternative to `enumerated`.&nbsp; I find this to be a reasonably compelling example of the kind of thing a partial range might enable.</div><div class=""><br class=""></div><div class="">I also tend to find concise notation important for clarity as long as it isn’t obscure or idiosyncratic.&nbsp; With that in mind, I think I lean in favor of `…` so long as we’re confident we won’t regret it if / when we take up variadic generics and / or tuple unpacking.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div></div><br class=""></div></div>______________________________<wbr class="">_________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class=""></blockquote></div><br class=""></div>______________________________<wbr class="">_________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a></div></blockquote></span></div></div></blockquote></div></div></div></div></blockquote></div><br class=""></body></html>