[swift-evolution] Feature proposal: Range operator with step

Dave Abrahams dabrahams at apple.com
Fri Mar 25 16:34:31 CDT 2016


on Fri Mar 25 2016, Xiaodi Wu <xiaodi.wu-AT-gmail.com> wrote:

> Ah, I think the conceptual muddle arises in the plan
> then. Specifically, I'd argue that not all Ranges with Strideable
> bounds should conform to Collection.
>
> Conceptually, whether a type can be advanced by some distance
> (guaranteed by Strideable) is orthogonal to whether a type has an
> obviously correct increment when calling next() on its iterator. Thus,
> although *strides* with Strideable bounds should obviously conform to
> Collection, Ranges that conform to Collection should be constrained to
> types which imply that the Range represents a countable set (as the
> mathematicians say) of numbers.

I think any countable set should be OK, regardless of whether the
elements are numbers.  Ranges of UnsafePointers, for example, are
countable.

> This distinction may come in handy for implementing strides that don't
> accumulate error. Striding through a Range that represents a countable
> set of elements shouldn't accumulate error and we can use what we
> already have--i.e. increment the current value every iteration without
> inspecting the value of the starting bound. Striding through a Range
> that represents an uncountable set of elements definitely requires
> reckoning from the starting bound every iteration.  

So, what does this Countable protocol look like?  It seems like it would
bring back the Index protocols that are otherwise obviated by this
plan... not a jolly prospect.

> On Fri, Mar 25, 2016 at 11:25 AM Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> on Thu Mar 24 2016, Xiaodi Wu <swift-evolution at swift.org> wrote:
>>
>> > On Thu, Mar 24, 2016 at 4:18 PM, Dave Abrahams via swift-evolution
>> > <swift-evolution at swift.org> wrote:
>> >>
>> >> on Wed Mar 23 2016, Xiaodi Wu <swift-evolution at swift.org> wrote:
>> >>
>> >>> So, in other words, you'd be satisfied with the following addition to
>> >>> the standard library?
>> >
>> >>>
>> >>> ```
>> >>> extension Range where Element: Strideable {
>> >>>     func by(step: Element.Stride) -> StrideTo<Element> {
>> >>>         return startIndex.stride(to: endIndex, by: step)
>> >>>     }
>> >>> }
>> >>>
>> >>> /*
>> >>> example of usage:
>> >>>
>> >>> for i in (1..<10).by(2) {
>> >>>     print(i)
>> >>> }
>> >>> */
>> >>> ```
>> >>
>> >>
>> >> My current thinking is that:
>> >>
>> >> * `for x in 0.0..<3.0 {}` should probably be an error, because 1.0 is
>> >>   not the obviously-right stride to use for non-integral numbers.  That
>> >>   would imply that floating types should not conform to Strideable,
>> >>   which raises the question of whether Strideable should be folded into
>> >>   the Integer protocol.
>> >
>> > Well, maybe I'm missing something, but `for x in 0.0..<3.0 { }`
>> > doesn't work as it is, and it doesn't seem to have anything to do with
>> > Strideable. Rather, HalfOpenInterval<Double> doesn't conform to
>> > SequenceType.
>>
>> True, but the plan is that:
>>
>> * Interval is going away
>> * Range will only require that its Bound be Comparable
>> * Ranges with Strideable bounds will conform to Collection
>>
>> (see the swift-3-indexing-model branch on GitHub)
>>
>> > I agree that `for x in 0.0..<3.0 { }` should continue not working, but
>> > maybe let's keep floating point types conforming to Strideable :)
>>
>> Those two things are not compatible with the plan we're going to
>> propose, as described above.
>>
>> >>
>> >> * `for x in (0.0..<20.0).striding(by: 1.3) {}` should work without
>> >>   accumulating error
>> >>
>> >
>> > +1.
>> >
>> >> * `for x in 0..<3 {}` should work (obviously; that's the status quo)
>> >>
>> >> * `for x in (0..<20).striding(by: 2)` should work
>> >>
>> >> I think this might also handle the concerns that
>> >>
>> https://github.com/apple/swift-evolution/blob/master/proposals/0051-stride-semantics.md
>> >> was trying to address.
>> >>
>> >> If I thought extreme concision was important for this application, I'd
>> be
>> >> proposing something like
>> >>
>> >>   for x in 0.0..<20.0//1.3 {}
>> >>
>> >> but personally, I don't, which is why I propose `.striding(by: x)`
>> >> rather than simply `.by(x)`, the latter being more open to
>> >> misinterpretation.
>> >
>> > Yeah, `.striding(by: x)` is pretty good.
>> >
>> >>
>> >> --
>> >> Dave
>> >>
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> --
>> Dave
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>

-- 
Dave


More information about the swift-evolution mailing list