<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="">Hi Erica, Dave</div><div class=""><br class=""></div><div class="">Based on what I’ve (not all) read under this topic:&nbsp;</div><div class=""><br class=""></div><div class="">I’d suggest a more complete approach:</div><div class=""><br class=""></div><div class="">Ranges should support: &nbsp;(as yet not implemented)&nbsp;</div><div class=""><br class=""></div><div class="">- All numerical data types (Double, Float, Int, Money***, Decimal*** )&nbsp;</div><div class="">- An arbitrary increment or decrement value.</div><div class="">- Working in the complete &nbsp;- + numerical range</div><div class="">- Allow traversing in both &nbsp; - + directions.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">The basics:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; (v1…v2).by(v3) &nbsp; &nbsp; // this still is readable. and can be optimized by the compiler (predictable sequence) &nbsp; &nbsp;</div><div class=""><br class=""></div><div class=""><div class=""><div class="">Rules:</div></div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; v1, v2, v3 &nbsp;are any numerical type scalar type &nbsp;</div></div><div class="">&nbsp; &nbsp; v1, v2, v3 &nbsp;must have the same numerical type.</div><div class="">&nbsp; &nbsp; v1 &gt; &nbsp;v2: &nbsp; is allowed and correctly evaluated. &nbsp;e.g. (8.0…-3.14159).by(-0.0001)&nbsp;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; The &nbsp;..&lt; &nbsp;half open operator is no longer allowed. &nbsp; write e.g. &nbsp; 0...ar.count - 1</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; "by(…)” &nbsp;is obligatory with floating point range.</div></div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;the default “by(…)” value of 1 makes sense only with integer ranges.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">valid examples:</div><div class="">&nbsp; &nbsp; (5…9) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 5 6 7 8 9 Integer range without “by” defaults to 1 as increment value.</div><div class=""><div class="">&nbsp; &nbsp; (1...10).by(2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 1 3 5 7 9.</div><div class=""></div><div class="">&nbsp; &nbsp; (2...10).by(2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 2 4 6 8 10.</div><div class=""></div><div class="">&nbsp; &nbsp; (4…-4).by(2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 4 &nbsp;2 0 -2 -4 . &nbsp; &nbsp; &nbsp; &nbsp;// runs backwards</div></div><div class=""><div class="">&nbsp; &nbsp; (30..-10).by(-2) &nbsp; &nbsp; &nbsp; &nbsp;// 30 28 26 24 22 ….. -10. &nbsp; &nbsp;</div></div><div class=""><div class="">&nbsp; &nbsp; (10...0).by(-3) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 10 7 4 1. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div></div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp; (12…-10) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // is valid, but returns empty because default increment value = 1</div></div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; (12.0…-12.0).by(-1.5) &nbsp; &nbsp; &nbsp; // 12.0 &nbsp;10.5 &nbsp;9.0…. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// of course with float imprecision</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="">&nbsp; &nbsp;</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;invalid examples:</div><div class=""><br class=""></div><div class=""><div class="">&nbsp; &nbsp;(23.0..&lt;60.5).by(0.5) &nbsp; &nbsp; &nbsp; &nbsp; // half open ranges are no &nbsp;longer allowed **&nbsp;</div></div><div class=""><div class="">&nbsp; (23.0…60.5) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // “ by" &nbsp;is obligatory with floats.</div></div><div class="">&nbsp; (14...8).by(0.5) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// &nbsp;v1 v2 and v3 don’t have the same numerical type&nbsp;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Half open ranges make no real sense (are not really useful) with floating point values.</div><div class="">and no sense at all with e.g (12..&lt;-1) &nbsp;afaics&nbsp;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">At least for float iterations the increment value should not each time be accumulated like</div><div class="">v1 += v3; &nbsp;v1 += v3; &nbsp;v1 += v3; &nbsp;…. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // causes float number drift.</div><div class="">but be freshly multiplied with each iteration, e.g. by using an internal iteration counter</div><div class="">like so:</div><div class=""><br class=""></div><div class="">v1 = v3 * i++; &nbsp; v1 = v3 * i++; &nbsp; v1 = v3 * i++;….</div><div class=""><br class=""></div><div class="">for reasons of precision.</div><div class=""><br class=""></div><div class="">If one has worked with floating point data more often</div><div class="">awareness of its precision limitations become a second nature conscience.&nbsp;</div><div class="">E.g. it is perfectly acceptable and known (also in classical for-loops) that</div><div class="">(0.0…1.0).by(0.1) is not guaranteed to reach the humanly expected value of 1.0.</div><div class="">This is normal. Due to the nature of what mostly is done in the</div><div class="">floating point numbers domain, this does not often cause a problem</div><div class="">(e.g like working with a slide ruler)&nbsp;</div><div class="">if it is important to reach the “expected end” then one could</div><div class="">-add an epsilon value like so (v1…v2 + 0.1)&nbsp;</div><div class="">-generate the desired float sequence within an integer loop.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">The above “range” (imho) improvement makes the&nbsp;</div><div class="">stride.. function/keyword completely unnecessary.</div><div class=""><br class=""></div><div class="">Due to its ability to process reversed ranges as is,&nbsp;</div><div class="">the .reverse() is optional (no longer necessary in most cases,</div><div class="">allowing the compiler to optimize without having to process&nbsp;</div><div class="">it like a collection.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Now that we have a fully functional range, which can do all things desired, one can</div><div class="">then of course, pass this range without any change &nbsp;to a collection based for … &nbsp;e.g.</div><div class=""><br class=""></div><div class="">for v in (v1…v2).by(v3) &nbsp; // optionally add other collection operators/filters/sorts here</div><div class=""><br class=""></div><div class="">(or in any other construct you might see fit)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class=""><br class=""></div><div class="">This seems to be a reasonable alternative for</div><div class=""><br class=""></div><div class="">- the classical for ;; loop</div><div class="">-the collection-free for-loop &nbsp;</div><div class="">&nbsp; &nbsp; &nbsp;for v from v1 to v2 by v3</div><div class=""><br class=""></div><div class="">As you know, the latter is what I have been suggesting,&nbsp;</div><div class="">but seemingly does not find much support,</div><div class="">(because I received very little reactions)&nbsp;</div><div class="">making it doubtful if I will ever make a proposal for this for loop.</div><div class="">Anyone out there should I stil do that?&nbsp;</div><div class=""><br class=""></div><div class="">When one does not further extend the range</div><div class="">with filters like sort etc. the compiler can still optimize&nbsp;</div><div class="">a collection-in-between out of the way.</div><div class="">(Thank you Taras, für das Mitdenken. :o)</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">** &nbsp; note that a half open range would in most cases be unnecessary&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; if &nbsp;collection indexes started with 1 instead of 0, e.g. someArray[1…10]&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp;(but it’s too late to change that.)&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp;“the color of the first apple?” &nbsp; &nbsp;vs</div><div class="">&nbsp; &nbsp; &nbsp;“the color of the zeroth (0) ??? &nbsp;apple?” &nbsp; &nbsp;? Silly isn’t?&nbsp;</div><div class=""><br class=""></div><div class="">*** possible future numerical “native” types&nbsp;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">It could be that (at least) partly something similar has already been suggested.</div><div class="">but so much is here of this topic that i can’t see the wood for the trees, so to speak.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Your (all) opinions are appreciated.&nbsp;</div><div class=""><br class=""></div><div class="">kind regards, mit freundlichen Grüssen, Met vriendelijke groeten,&nbsp;</div><div class="">Sigh, why do we Dutch always have to speak the languages of the bigger countries :o)&nbsp;</div><div class="">TedvG</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">on Wed Apr 06 2016, Erica Sadun &lt;<a href="http://erica-at-ericasadun.com" class="">erica-AT-ericasadun.com</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class="">&nbsp;&nbsp;&nbsp;On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution<br class="">&nbsp;&nbsp;&nbsp;&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">&nbsp;&nbsp;&nbsp;(0..&lt;199).striding(by: -2)<br class=""><br class="">&nbsp;&nbsp;&nbsp;are even or odd.<br class=""><br class="">(0..&lt;199).striding(by: -2): 0..&lt;199 == 0...198 Even<br class="">(1..&lt;199).striding(by: -2): 1..&lt;199 == 1...198 Even<br class=""></blockquote><br class="">I understand the logic that got you there, but I find it incredibly<br class="">counter-intuitive that striding by 2s over a range with odd endpoints<br class="">should produce even numbers... I can't imagine any way I'd be convinced<br class="">that was a good idea.<br class=""><br class=""><blockquote type="cite" class="">(0..&lt;198).striding(by: -2): 1..&lt;198 == 0...197 Odd<br class="">(1..&lt;198).striding(by: -2): 1..&lt;198 == 1...197 Odd<br class=""><br class="">-- E<br class=""><br class=""></blockquote></blockquote><br class=""></div><blockquote type="cite" class=""><div class="">--&nbsp;<br class=""><blockquote type="cite" class="">Dave</blockquote></div></blockquote><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>