While I’m in favour of the basic idea I think the operator selection is too 
complex, and I’m not sure about the need for negative strides. Really all I 
want are the following:

        (0 ... 6).striding(by: 2)       // [0, 2, 4, 6]         x from 0 to 6
        (0 ..< 6).striding(by: 2)       // [0, 2, 4]            x from 0 while 
<6
        (6 ... 0).striding(by: 2)       // [6, 4, 2, 0]         x from 6 to 0
        (6 ..> 0).striding(by: 2)       // [6, 4, 2]            x from 6 while 
>0

Everything else should be coverable either by flipping the order, or using 
.reverse(). The main advantage is that there’s only one new operator to clarify 
the 6 ..> 0 case, though you could always just reuse the existing operator if 
you just interpret it as “x from 6 to, but not including, 0"

I dunno, I just don’t think that introducing tons of new operators is going to 
simplify things, and could lead to way more mistakes in practice; the only 
mistake above would be putting the indices in the wrong order and accidentally 
reversing the result.

Also, I’m against negative strides; while they could be useful for convenience 
(avoid the need for .reverse or flipping values) I’m just not sure that it 
makes sense. To me a stride is a distance, thus absolute, what matters is the 
direction of the range. Naturally we’d need ranges with a direction, but with 
collections requiring it to be in a particular order (or ignoring it and 
flipping where necessary).

> On 8 Apr 2016, at 19:37, Erica Sadun via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Draft here: https://gist.github.com/erica/a51a981ee0352235204692affa959307 
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307>  Feedback 
> solicited, both positive and negative. 
> We've also got a related proposal about expanding ranges, which you can look 
> at here (https://gist.github.com/erica/af92c541a0fb69fce1b7aaf8374a5aa9 
> <https://gist.github.com/erica/af92c541a0fb69fce1b7aaf8374a5aa9>)
>  but we want to float this one first.
> 
> Thanks, -- E
> 
> 
> 
> Proposal: SE-XXXX 
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307/edit>
> Author(s): Xiaodi Wu <https://github.com/xwu>, Pyry Jahkola 
> <http://github.com/pyrtsa>, Nate Cook <http://github.com/natecook1000>, Erica 
> Sadun <http://github.com/erica>
> Status: TBD
> Review manager: TBD
>  
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307#introduction>Introduction
> 
> We propose to introduce a striding(by:) method on the revised 3.0 Range type.
> 
> This proposal was discussed on the Swift Evolution list in the Feature 
> proposal: Range operator with step 
> <http://search.gmane.org/search.php?group=gmane.comp.lang.swift.evolution&query=Feature+proposal%3A+Range+operator+with+step>
>  thread. (Direct link 
> <http://thread.gmane.org/gmane.comp.lang.swift.evolution/12801/focus=13051> 
> to original thread)
> 
>  
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307#motivation>Motivation
> 
> Updating Range for Swift 3 offers a window of opportunity to simultaneously 
> improve strides.
> 
> Under current Swift 3 plans, n.stride(to:/through:, by:) will be replaced 
> with a standalone stride(from:, to:/through:, by:) function. We propose to 
> replace this change with a method on ranges. Using a method reduces overall 
> API surface area compared to free functions.
> 
> In its current incarnation, the standalone stride function uses confusing 
> semantics. The current to implementation returns values in [start, end) and 
> will never reach or get to end. The current through implementation returns 
> values in [start, end]. It may never reach end and certainly never goes 
> through that value. Our proposed method introduces simple, expected semantics 
> that can be extended to both countable and continuous ranges, and to open and 
> closed intervals (both half-open and fully-open).
> 
>  
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307#detail-design>Detail
>  Design
> 
> The striding(by:) method is called on ranges. When used with a positive step 
> size, the count starts from the lower bound. With a negative step size, the 
> count starts from the upper bound. These bounds apply regardless of whether 
> they are inclusive or exclusive. 
> 
> The following examples should cover all corner cases and include possible 
> cases should Swift 3 introduce a full complement of open and closed ranges. 
> The syntax for non-canonical range types is not fixed and can be discussed 
> under separate cover.
> 
> (0 ... 9).striding(by: 2) == [0, 2, 4, 6, 8]
> (0 ..< 9).striding(by: 2) == [0, 2, 4, 6, 8]
> (0 <.. 9).striding(by: 2) ==    [2, 4, 6, 8]
> (0 <.< 9).striding(by: 2) ==    [2, 4, 6, 8]
> 
> (0 ... 9).striding(by: 3) == [0, 3, 6, 9]
> (0 ..< 9).striding(by: 3) == [0, 3, 6]
> (0 <.. 9).striding(by: 3) ==    [3, 6, 9]
> (0 <.< 9).striding(by: 3) ==    [3, 6]
> 
> (0 ... 9).striding(by: -2) == [9, 7, 5, 3, 1]
> (0 ..< 9).striding(by: -2) ==    [7, 5, 3, 1]
> (0 <.. 9).striding(by: -2) == [9, 7, 5, 3, 1]
> (0 <.< 9).striding(by: -2) ==    [7, 5, 3, 1]
> 
> (0 ... 9).striding(by: -3) == [9, 6, 3, 0]
> (0 ..< 9).striding(by: -3) ==    [6, 3, 0]
> (0 <.. 9).striding(by: -3) == [9, 6, 3]
> (0 <.< 9).striding(by: -3) ==    [6, 3]
> To reverse a stride, call reverse() on the results:
> 
> (0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]
> We note that striding by 0 should be always be a precondition failure.
> 
>  
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307#alternatives-considered>Alternatives
>  Considered
> 
> During the on-list discussion, we considered various scenarios that took 
> closed/inclusive bounds into account or excluded open bounds for starting 
> values. For example, we might have prohibited scenarios where multiple 
> interpretations of an intended behavior might exist: is (0 ..< 
> 9).striding(by: -2) a precondition failure? We settled on the simplest, most 
> straight-forward implementation involving the fewest compiler warnings and 
> the lowest likelihood of precondition failures. We subscribe to the "Dave 
> Abrahams Philosophy": excessive special casing and warning scenarios more 
> likely indicates bad language design than bad user comprehension.
> 
>  
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307#future-directions>Future
>  Directions
> 
> We intend to follow up with an expanded operator vocabulary that includes 
> fully open ranges (<.<), fully closed ranges (...) and both half open ranges 
> (<.., ..<). These will support the full vocabulary laid out in the Detail 
> Design section.
> 
> Upon adoption, the Swift community may consider expanding this approach to 
> collection indices, for example:
> 
> let a = [8, 6, 7, 5, 3, 0, 9]
> for e in a.striding(by: 3) {
>     print(e) // 8, then 5, then 9
> }
> Striding offers a fundamental operation over collections. The consistent 
> approach introduced in this proposal 
> <http://article.gmane.org/gmane.comp.lang.swift.evolution/13936> helps 
> support the extension of stride semantics to collections.
> 
>  
> <https://gist.github.com/erica/a51a981ee0352235204692affa959307#acknowlegements>Acknowlegements
> 
> Thanks, Dave Abrahams, Matthew Judge
> 
> _______________________________________________
> 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