<div dir="ltr">On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris <span dir="ltr">&lt;<a href="mailto:davesweeris@mac.com" target="_blank">davesweeris@mac.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On Jan 31, 2017, at 2:04 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="m_4871187344016849002Apple-interchange-newline"><div><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">On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution<span class="m_4871187344016849002Apple-converted-space"> </span><span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-<wbr>evolution@swift.org</a>&gt;</span><span class="m_4871187344016849002Apple-converted-space"> </span>wrote:<br><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"><span class="m_4871187344016849002gmail-"><div><br></div><div>On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><span>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><span>```</span><br><span>for x in arr[arr.startIndex…] { print(x) }</span><br><span>```</span><br><span>yielded different results than</span><br><span>```</span><br><span>for i in arr.startIndex… { print(arr[i]) } // CRASH</span><br><span>```</span><br><span>which it does under this model.</span><br></div></blockquote><br></span><div>(I<span class="m_4871187344016849002Apple-converted-space"> </span><i>think</i><span class="m_4871187344016849002Apple-converted-space"> </span>this how it works... semantically, anyway) Since the upper bound isn&#39;t specified, it&#39;s inferred from the context.</div><div><br></div><div>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><br></div><div>In the second case, there is no context, so it goes to Int.max. Then,<span class="m_4871187344016849002Apple-converted-space"> </span><i>after</i><span class="m_4871187344016849002Apple-converted-space"> </span>the &quot;wrong&quot; context has been established, you try to index an array with numbers from the too-large range.</div><div><br></div><div>Semantically speaking, they&#39;re pretty different operations. Why is it surprising that they have different results?</div></div></blockquote><div><br></div><div>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><br></div><div>A range is, to put it simply, the &quot;stuff&quot; between two end points. A &quot;range with no upper bound&quot; _has to be_ one that continues forever. The upper bound _must_ be infinity.</div></div></div></div></div></blockquote><div><br></div></span><div>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 &quot;Range without an upperBound” can’t exist without getting into undefined behavior territory.</div><div><br></div><div>Plus, mathematically speaking, an infinite range would be written &quot;[x, ∞)&quot;, with an open upper bracket. If you write “[x, ∞]”, with a <i>closed</i> 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 &quot;x…” in Swift, free to let us have “x…” or “…x” (which by similar reasoning can’t mean &quot;(∞, x]”) return one of these:</div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">enum</span><span style="font-variant-ligatures:no-common-ligatures"> IncompleteRange&lt;T</span><span style="font-variant-ligatures:no-common-ligatures">&gt; {</span></div></div></div><div><div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">case</span><span style="font-variant-ligatures:no-common-ligatures"> upperValue(</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">T</span><span style="font-variant-ligatures:no-common-ligatures">)</span></div></div></div><div><div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">case</span><span style="font-variant-ligatures:no-common-ligatures"> lowerValue(</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">T)</span></div></div></div><div><div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">}</span></div></div></div></blockquote><div><div><div><span style="font-variant-ligatures:no-common-ligatures">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:0 0 0 40px;border:none;padding:0px"><div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">extension</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000"> </span><span style="font-variant-ligatures:no-common-ligatures">Collection</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000"> {</span></div></span></div></div></div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">subscript</span><span style="font-variant-ligatures:no-common-ligatures">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">_</span><span style="font-variant-ligatures:no-common-ligatures"> ir: </span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">IncompleteRange</span><span style="font-variant-ligatures:no-common-ligatures">&lt;Index&gt;) -&gt; SubSequence {</span></div></span></div></div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">        </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">switch</span><span style="font-variant-ligatures:no-common-ligatures"> ir {</span></div></span></div></div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">        </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">case</span><span style="font-variant-ligatures:no-common-ligatures"> .</span><span style="font-variant-ligatures:no-common-ligatures;color:#31595d">lowerValue</span><span style="font-variant-ligatures:no-common-ligatures">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">let</span><span style="font-variant-ligatures:no-common-ligatures"> lower): </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">return</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">self</span><span style="font-variant-ligatures:no-common-ligatures">[lower ..&lt; </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">self</span><span style="font-variant-ligatures:no-common-ligatures">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa">endIndex</span><span style="font-variant-ligatures:no-common-ligatures">]</span></div></span></div></div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">        </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">case</span><span style="font-variant-ligatures:no-common-ligatures"> .</span><span style="font-variant-ligatures:no-common-ligatures;color:#31595d">upperValue</span><span style="font-variant-ligatures:no-common-ligatures">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">let</span><span style="font-variant-ligatures:no-common-ligatures"> upper): </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">return</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">self</span><span style="font-variant-ligatures:no-common-ligatures">[</span><span style="font-variant-ligatures:no-common-ligatures;color:#bb2ca2">self</span><span style="font-variant-ligatures:no-common-ligatures">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa">startIndex</span><span style="font-variant-ligatures:no-common-ligatures"> ..&lt; upper]</span></div></span></div></div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">        }</span></div></span></div></div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">    }</span></div></span></div></div><div><div><span style="font-variant-ligatures:no-common-ligatures"><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">}</span></div></span></div></div></blockquote></div></blockquote><div><br></div><div>I understand that you can do this from a technical perspective. But I&#39;m arguing it&#39;s devoid of semantics. That is, it&#39;s a spelling to dress up a number.</div><div><br></div><div>What is such an `IncompleteRange&lt;T&gt;` other than a value of type T? It&#39;s not an upper bound or lower bound of anything until it&#39;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><br></div></div><br></div></div>