> Am 01.04.2016 um 00:23 schrieb Xiaodi Wu via swift-evolution 
> <swift-evolution@swift.org>:
> 
> 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

Couldn’t we use a BigInt internally (if necessary)? This would make this 
problem disappear.

-Thorsten


> (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 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
> > On Mar 31, 2016, at 11:16 AM, Rainer Brockerhoff via swift-evolution 
> > <swift-evolution@swift.org <>> 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 
> >> <http://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
> swift-evolution@swift.org <>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
> -- 
> -- Howard.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to