[swift-evolution] [Draft]: Introducing a striding(by:) method on 3.0 ranges

Taras Zakharko taras.zakharko at uzh.ch
Fri Apr 8 18:01:21 CDT 2016


I am agnostic on a .striding() method, but I am strongly agains any suggestions of removing/replacing the global stride() function. The stride function does not pollute the global namespace as it is a universally useful construct (among others, for implementing classical iterating for loops), has its history in contemporary programming (comparable functions in languages like Python, R), and is IMO more readable and clear than a range with a striding method method. Furthermore, a stride is not a range — its a special sequence, while for ranges other rules apply. All in all, I don’t see why stride() and .striding() can’t coexist. 

— Taras 

P.S. As a side note, I would prefer if the stride() function be renamed sequence() or seq(), but thats just cosmetic personal preference. 


> On 08 Apr 2016, at 20:37, Erica Sadun via swift-evolution <swift-evolution at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160409/5e054b81/attachment.html>


More information about the swift-evolution mailing list