<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: </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:  (as yet not implemented) </div><div class=""><br class=""></div><div class="">- All numerical data types (Double, Float, Int, Money***, Decimal*** ) </div><div class="">- An arbitrary increment or decrement value.</div><div class="">- Working in the complete  - + numerical range</div><div class="">- Allow traversing in both   - + 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="">    (v1…v2).by(v3)     // this still is readable. and can be optimized by the compiler (predictable sequence)    </div><div class=""><br class=""></div><div class=""><div class=""><div class="">Rules:</div></div><div class=""><br class=""></div><div class="">    v1, v2, v3  are any numerical type scalar type  </div></div><div class="">    v1, v2, v3  must have the same numerical type.</div><div class="">    v1 >  v2:   is allowed and correctly evaluated.  e.g. (8.0…-3.14159).by(-0.0001) </div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">    The  ..<  half open operator is no longer allowed.   write e.g.   0...ar.count - 1</div><div class=""><br class=""></div><div class=""><div class="">    "by(…)”  is obligatory with floating point range.</div></div><div class=""><br class=""></div><div class="">           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="">    (5…9)                        // 5 6 7 8 9 Integer range without “by” defaults to 1 as increment value.</div><div class=""><div class="">    (1...10).by(2)             // 1 3 5 7 9.</div><div class=""></div><div class="">    (2...10).by(2)             // 2 4 6 8 10.</div><div class=""></div><div class="">    (4…-4).by(2)             // 4  2 0 -2 -4 .        // runs backwards</div></div><div class=""><div class="">    (30..-10).by(-2)        // 30 28 26 24 22 ….. -10.    </div></div><div class=""><div class="">    (10...0).by(-3)          // 10 7 4 1.                 </div></div><div class=""><br class=""></div><div class=""><div class="">    (12…-10)                 // is valid, but returns empty because default increment value = 1</div></div><div class=""><br class=""></div><div class="">    (12.0…-12.0).by(-1.5)       // 12.0  10.5  9.0….          // of course with float imprecision</div><div class="">                                                                       </div><div class="">   </div><div class=""><br class=""></div><div class="">   invalid examples:</div><div class=""><br class=""></div><div class=""><div class="">   (23.0..<60.5).by(0.5)         // half open ranges are no  longer allowed ** </div></div><div class=""><div class="">  (23.0…60.5)                     // “ by"  is obligatory with floats.</div></div><div class="">  (14...8).by(0.5)                //  v1 v2 and v3 don’t have the same numerical type </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..<-1)  afaics </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;  v1 += v3;  v1 += v3;  ….                       // 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++;   v1 = v3 * i++;   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. </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) </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) </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 </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, </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 </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  to a collection based for …  e.g.</div><div class=""><br class=""></div><div class="">for v in (v1…v2).by(v3)   // 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="">                                       </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  </div><div class="">     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, </div><div class="">but seemingly does not find much support,</div><div class="">(because I received very little reactions) </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? </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 </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="">**   note that a half open range would in most cases be unnecessary </div><div class="">      if  collection indexes started with 1 instead of 0, e.g. someArray[1…10] </div><div class="">     (but it’s too late to change that.) </div><div class="">     “the color of the first apple?”    vs</div><div class="">     “the color of the zeroth (0) ???  apple?”    ? Silly isn’t? </div><div class=""><br class=""></div><div class="">*** possible future numerical “native” types </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. </div><div class=""><br class=""></div><div class="">kind regards, mit freundlichen Grüssen, Met vriendelijke groeten, </div><div class="">Sigh, why do we Dutch always have to speak the languages of the bigger countries :o) </div><div class="">TedvG</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">on Wed Apr 06 2016, Erica Sadun <<a href="http://erica-at-ericasadun.com" class="">erica-AT-ericasadun.com</a>> wrote:<br class=""><br class=""><blockquote type="cite" class="">   On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution<br class="">   <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class="">   (0..<199).striding(by: -2)<br class=""><br class="">   are even or odd.<br class=""><br class="">(0..<199).striding(by: -2): 0..<199 == 0...198 Even<br class="">(1..<199).striding(by: -2): 1..<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..<198).striding(by: -2): 1..<198 == 0...197 Odd<br class="">(1..<198).striding(by: -2): 1..<198 == 1...197 Odd<br class=""><br class="">-- E<br class=""><br class=""></blockquote></blockquote><br class=""></div><blockquote type="cite" class=""><div class="">-- <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>