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