<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="">Grrrr Typos… Sorry, here it is again: vital corrections look at<<<<<< <<<<<<<<<<br class=""><div><div class=""><br class=""></div><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div 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="">v = v1 + v3 * i++; v = v1 + v3 * i++; v = v1 + v3 * i++; v = 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></div></div></div><br class=""></body></html>