No I would not be surprised by a limit based on Int provided that: 1. It was articulated in the documentation 2. The error occurred when the Range/stride was created 3. The error message stated that there were too many steps and what the step limit was
What I don't think would be acceptable was if: 1. The error occurred part way through the iteration; not at creation time 2. There was no error and the loop turned into an infinite loop silently On Friday, 1 April 2016, Xiaodi Wu <[email protected]> wrote: > All true. I call that Erica's solution because her proposal is where I > first found it sketched out. > > I'm not convinced that Erica's solution is definitely the right answer > because: > > (a) Use of an iteration counter of type Int to stride through Doubles is > an implementation detail which is not an obviously correct choice; users > might find it surprising that how many steps they get for StrideTo<Double> > is constrained by Int.max > > (b) I'm not completely certain that there is no use case for a loop with > more than Int.max steps so long as you break before the end, so I'm not > completely certain that an error right off the bat is the most ideal > behavior; for example, someone may wish to increment by a user-supplied > epsilon from one user-supplied value to another but break after a certain > amount of time has elapsed > > (c) I agree with you that it's Swiftier to do nothing than to start > returning approximately correct values, but in a scenario such as `for _ in > stride(from: 0, to: DBL_MAX, by: someAbsurdlySmallValue) { }` it may not > matter (I cannot imagine a use case for this ridiculous loop, but for the > sake of argument here let's take it); one alternative solution someone > might propose, for example, would be to fall back to the old > error-accumulating algorithm after the iteration counter has reached its > max possible value > > So I guess the feedback I'm interested in is: > > - Would you be surprised to find that Stride<Double> may become > constrained by an upper limit in the number of steps? > > - If not, would it irk you that such a limit is based on the size of a > totally unrelated numeric type (namely, Int) which is an implementation > detail? Would you prefer that the limit be something related to the nature > of the type itself (for example, a maximum number of steps for > StrideTo<Double> that reflects the maximum exactly representable integer in > a Double)? > > - If there is to be an upper limit on steps, would you prefer an error > when the Stride is being initialized or when the iteration counter > overflows? > > - Would you rather instead be able to stride indefinitely, as is currently > the case in Swift 2, accepting that error will start accumulating at some > point? > > On Thu, Mar 31, 2016 at 4:33 PM Howard Lovatt via swift-evolution < > [email protected] > <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: > >> If you define a range as range[i] = first + i * stride where i is an Int >> then this generates an error when there are more than Int_Max steps, see >> code previously posted. The error is generated when the range is formed, >> which is ideal since an error part way along an iteration or a never ending >> iteration would be difficult to track down. >> >> On Friday, 1 April 2016, Stephen Canon via swift-evolution < >> [email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');>> wrote: >> >>> >>> > On Mar 31, 2016, at 11:16 AM, Rainer Brockerhoff via swift-evolution < >>> [email protected]> wrote: >>> > >>> > On 3/31/16 15:06, Dave Abrahams via swift-evolution wrote: >>> >> >>> >> on Thu Mar 31 2016, Xiaodi Wu <xiaodi.wu-AT-gmail.com> wrote: >>> >> >>> >>> Thoughts on an edge case: so long as it's possible to use >>> >>> `stride(from:to:by:)` with Double, we'll need to figure out what >>> >>> happens when you have `stride(from: 0.0, to: DBL_MAX, by: DBL_MIN)`. >>> >>> Bounds may be unknown at compile time, obviously. >>> >>> >>> >>> Currently (this is by reasoning through the code, not actually >>> >>> observing it run), `for i in stride(from: 0.0, to: DBL_MAX, by: >>> >>> DBL_MIN) { }` degenerates into an infinite loop once you reach >>> >>> sufficient large values such that `current + stride == current`, >>> which >>> >>> for a stride of DBL_MIN should happen pretty quickly. >>> >>> >>> >>> In Erica's proposed floating point Stride, an Int is used to count >>> >>> iterations (and iterations need to be counted in order to avoid >>> >>> accumulating error). Thus, one must break from `for i in stride(from: >>> >>> 0.0, to: DBL_MAX, by: DBL_MIN) { }` before the iteration counter >>> >>> overflows or it will trap. IMO, trapping at some point is fine, but I >>> >>> think a limit of Int.max iterations might be rather arbitrary for a >>> >>> StrideTo<Double> (or whatever it will be named) and I'm not sure how >>> >>> one can justify why the behavior of StrideTo<Double> would change >>> from >>> >>> machine to machine based on the size of Int. >>> >>> >>> >>> I've been waffling between using an Int counter as Erica does or a >>> >>> counter of type Strideable.Stride in `StrideTo<Strideable where >>> >>> Strideable.Stride : FloatingPoint>`. In the latter alternative, no >>> >>> trapping occurs, but error begins to accumulate when the iteration >>> >>> counter is too large to represent integers exactly (e.g., 2^53 for >>> >>> Double). In that case, `for i in stride(from: 0.0, to: DBL_MAX, by: >>> >>> DBL_MIN) { }` degenerates into an infinite loop eventually (once >>> >>> `iterationCount + 1.0 == iterationCount`) and never traps, which I'm >>> >>> not sure I like, but a limit of 2^53 iterations bears at least a >>> >>> rational connection to Double and is known at compile time >>> independent >>> >>> of the supplied bounds. We could alternatively return nil on reaching >>> >>> 2^53 iterations, trap, etc. >>> >>> >>> >>> Comments? >>> >> >>> >> I think I want to hear Steve Canon's input on this one. I defer to >>> him >>> >> on most things numeric. >>> > >>> > In particular, should Steve confirm that the IEEE754 Decimal128 format >>> > is being worked on, and if simple decimal constants like those in >>> > `for i in stride(from: 0.0, to: DBL_MAX, by: DBL_MIN) { }` >>> > will be type-inferred as Decimal128, all that would "just work". >>> >>> Decimal is something that I would like to see happen. However, I would >>> not expect any such proposal to result in that loop being type inferred to >>> Decimal, since the to: and by: values are explicitly (binary >>> floating-point) Doubles. >>> >>> I also don’t think that such a loop is particularly useful. For >>> floating-point types, something like stride(from: T, to: T, steps: Int) >>> seems safer and more workable to me (this is just my immediate reaction, I >>> haven’t thought this through in detail, and am likely to change my mind if >>> someone makes a good case). >>> >>> – Steve >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >> >> >> -- >> -- Howard. >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> > -- -- Howard.
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
