<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=""><div class="">The tricky thing with ranges at the moment is that they can’t actually represent a full range of an integer type, for example a Range&lt;UInt8&gt; can only represent a range from 0 to 254 (endIndex is 255 but is exclusive). This actually means that a collection type that used a UInt8 for indexes is limited to 255 entries, not 256 as you would expect, which is unfortunate if the collection type allocates storage in powers of two.</div><div class=""><br class=""></div><div class="">I think this means that if ranges were changed to have an inclusive end index then collections would need to be modified to function on the same principal, otherwise we could end up with a range that represents an upper limit that collections cannot, or alternatively we have to artificially limit the supported values for .end, i.e- for a UInt8 .end would be limited to a value of 254, so that .endIndex can be set to 255.</div><div class=""><br class=""></div><div class="">For use with collections I’d love to use inclusive rather than exclusive end indexes for this reason, as while 1 inaccessible element doesn’t seem like much, it still annoys me an unreasonable amount. But would this change the meaning of a range? i.e- 1 ..&lt; 4 isn’t necessarily the same as 1 … 3, it’s only functionally equivalent when dealing with integers since there are no stages in between.</div><br class=""><div><blockquote type="cite" class=""><div class="">On 20 Jan 2016, at 23:19, Andrew Bennett via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I agree with Kevin/Jordan, I also expect this to always be true:<div class=""><br class=""></div><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp; Range&lt;Int&gt;(start: a, end: b).startIndex == a</span><br class=""><div class=""><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;</span><span style="font-family:monospace,monospace" class="">&nbsp;</span><font face="monospace, monospace" class="">Range&lt;Int&gt;(start: a, end: b).endIndex == b</font></div><div class=""><br class=""></div><div class="">Possibly you could adjust Range to be something like this:</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""></blockquote><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:monospace,monospace" class="">struct Range&lt;T: ForwardIndexType&gt; {</span><br class=""><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""></blockquote><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:monospace,monospace" class="">var start: T</span>,&nbsp;<span style="font-family:monospace,monospace" class="">end: T</span><br class=""><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""></blockquote><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:monospace,monospace" class="">}</span><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class="">Ensuring that this is true:</div><div class=""><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;</span><span style="font-family:monospace,monospace" class="">&nbsp;</span><span style="font-family:monospace,monospace" class="">Range&lt;Int&gt;(start: a, end: b).start == a</span><br class=""><div class=""><font face="monospace, monospace" class="">&nbsp; &nbsp; Range&lt;Int&gt;(start: a, end: b).end == b</font></div><div class=""><br class=""></div><div class="">Then startIndex and endIndex are simply for CollectionType conformance.</div><div class=""><br class=""></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""></blockquote><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:monospace,monospace" class="">extension Range: CollectionType {</span><br class=""><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""></blockquote><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp; var startIndex: T { return start }</span><br class=""><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><font face="monospace, monospace" class="">&nbsp; &nbsp; var endIndex: T { return start &lt; end ? end : start }<br class=""></font><span style="font-family:monospace,monospace" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family:monospace,monospace" class="">}</span><div class=""><div class=""><br class=""></div></div></div><div class="">You can still test the validity of the range:</div><div class=""><font face="monospace, monospace" class="">&nbsp; &nbsp; assert(range.start &lt; range.end)</font></div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, Jan 21, 2016 at 8:23 AM, Jordan Rose via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Mm. The reason '..&lt;' doesn't have this behavior, though, is because you get the useful property that "collection[collection.startIndex..&lt;collection.endIndex]" contains the same elements as "collection" itself. It's definitely useful to be able to represent an empty slice at a particular position (say, for replacing with another slice). It's a lot rarer to use '...' for slicing.<br class="">
<br class="">
Jordan<br class="">
<div class="HOEnZb"><div class="h5"><br class="">
<br class="">
&gt; On Jan 20, 2016, at 13:17 , Haravikk &lt;<a href="mailto:me@haravikk.com" class="">me@haravikk.com</a>&gt; wrote:<br class="">
&gt;<br class="">
&gt; I’m inclined to agree though I’m pretty uncertain all round.<br class="">
&gt;<br class="">
&gt; To me it seems like the only cases where someone seems likely to end up with an end index lower than their start index is either from input (in which case the value should be tested first), or some kind of logic error, in which case silently failing isn’t going to help resolve that issue (or detect it).<br class="">
&gt;<br class="">
&gt; Personally I’d much prefer the opposite solution, which would be to have stride throw an error if the range given is invalid; this would still mean both cases are consistent, but without the risk of silent failures ruining your program.<br class="">
&gt;<br class="">
&gt; - Haravikk<br class="">
&gt;<br class="">
&gt;&gt; On 20 Jan 2016, at 19:42, Jordan Rose via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;&gt;<br class="">
&gt;&gt; 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.<br class="">
&gt;&gt;<br class="">
&gt;&gt; Jordan<br class="">
&gt;&gt;<br class="">
&gt;&gt;<br class="">
&gt;&gt;&gt; On Jan 19, 2016, at 12:46, Uwe Falck via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;&gt;&gt;<br class="">
&gt;&gt;&gt; I’m looking for feedback on this request if its worth to start an evolution proposal.<br class="">
&gt;&gt;&gt;<br class="">
&gt;&gt;&gt;<br class="">
&gt;&gt;&gt; Let range operators always return empty ranges if the upper bound is smaller than the lower bound.<br class="">
&gt;&gt;<br class="">
&gt;&gt; _______________________________________________<br class="">
&gt;&gt; swift-evolution mailing list<br class="">
&gt;&gt; <a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
&gt;&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
&gt;<br class="">
<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</div></div></blockquote></div><br class=""></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>