Add a stride(by:) method to ClosedRange


(Tim Vermeulen) #1

If ClosedRange (Range in Swift 2.2.1) has a stride(by:) method, we can change

stride(from: 0, to: 10, by: 3)

to

(0..<10).stride(by: 3)

and similarly, we can change

stride(from: 0, through: 10, by: 3)

to

(0…10).stride(by: 3)

As we can see, this syntax can replace both stride(from:to:by:) and stride(from:through:by:), and in my opinion it is more in line with the rest of Swift 3, similar to how Range.init(start:end:) will be deprecated in Swift 3 in favor of the … and ..< operators.

I’m not sure if this proposed stride(by:) method could replace all uses of stride(from:to:by:) and stride(from:through:by:), but I think that at the very least it would be a nice addition to the standard library.


(Xiaodi Wu) #2

We've had this discussion on a few occasions. Unfortunately, copying links
at the moment is a little tough, but I hope to do so at a later time (or
others can jump in here).

The gist of the previous discussion centered on a few objections:
* that stride(by:), or rather striding(by:), was too verbose
* that both stride(from:to:by:) and Range.striding(by:) should not
co-exist, so one would have to be removed in favor of the other
* that there was no one obvious behavior with a negative stride size (range
operators require a smaller number on the lhs and a bigger one on the rhs,
so you can't write `9...0`, but stride(from:to:by) can start from a bigger
number to a smaller one, so there is a difference here that went through a
lot of bikeshedding; there were several important people that made it clear
that Range would not be modified for this use case, so it's stride
semantics that must change)
* that for floating point ranges, removing stride(from:to:by:) in favor of
striding(by:) would eliminate the possibility of expressing certain strides
with open lower bound and negative stride size, partially motivating new
range operators that are a whole nother issue

···

On Fri, May 20, 2016 at 4:19 PM, Tim Vermeulen via swift-evolution < swift-evolution@swift.org> wrote:

If ClosedRange (Range in Swift 2.2.1) has a stride(by:) method, we can
change

stride(from: 0, to: 10, by: 3)

to

(0..<10).stride(by: 3)

and similarly, we can change

stride(from: 0, through: 10, by: 3)

to

(0…10).stride(by: 3)

As we can see, this syntax can replace both stride(from:to:by:) and
stride(from:through:by:), and in my opinion it is more in line with the
rest of Swift 3, similar to how Range.init(start:end:) will be deprecated
in Swift 3 in favor of the … and ..< operators.

I’m not sure if this proposed stride(by:) method could replace all uses of
stride(from:to:by:) and stride(from:through:by:), but I think that at the
very least it would be a nice addition to the standard library.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Tim Vermeulen) #3

* that there was no one obvious behavior with a negative stride size (range operators require a smaller number on the lhs and a bigger one on the rhs, so you can't write `9...0`, but stride(from:to:by) can start from a bigger number to a smaller one, so there is a difference here that went through a lot of bikeshedding; there were several important people that made it clear that Range would not be modified for this use case, so it's stride semantics that must change)
* that for floating point ranges, removing stride(from:to:by:) in favor of striding(by:) would eliminate the possibility of expressing certain strides with open lower bound and negative stride size, partially motivating new range operators that are a whole nother issue

These are all great reasons why stride(from:to:by:) shouldn’t be removed, that I had not thought of. But isn’t this a good reason to let both function co-exist?

For example: (0..<10).striding(by: 3) and stride(from: 0, to: 10, by: 3) look quite similar. However, in case we already have a range variable, someRange.striding(by: 3) is obviously a lot more readable than stride(from: someRange.startIndex, to: someRange.endIndex, by: 3). The reason I’m giving this example is that the two functions can have quite different use cases, so I’m unsure why one of them must be removed in favor of the other.

* that stride(by:), or rather striding(by:), was too verbose

striding(by:) doesn’t have the from, to, though parameter labels that the Swift 3 stride functions have, so to me this new method seems less verbose than the others. Maybe it depends on how you look at it. “to” and “through” basically refer to the “.” and “<“ tails of the “…” and “..<“ operators respectively, so that’s mainly why I think striding(by:) would be a cleaner and more intuitive way to stride through a sequence.

···

On 21 May 2016, at 00:07, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

We've had this discussion on a few occasions. Unfortunately, copying links at the moment is a little tough, but I hope to do so at a later time (or others can jump in here).

The gist of the previous discussion centered on a few objections:
* that stride(by:), or rather striding(by:), was too verbose
* that both stride(from:to:by:) and Range.striding(by:) should not co-exist, so one would have to be removed in favor of the other
* that there was no one obvious behavior with a negative stride size (range operators require a smaller number on the lhs and a bigger one on the rhs, so you can't write `9...0`, but stride(from:to:by) can start from a bigger number to a smaller one, so there is a difference here that went through a lot of bikeshedding; there were several important people that made it clear that Range would not be modified for this use case, so it's stride semantics that must change)
* that for floating point ranges, removing stride(from:to:by:) in favor of striding(by:) would eliminate the possibility of expressing certain strides with open lower bound and negative stride size, partially motivating new range operators that are a whole nother issue

On Fri, May 20, 2016 at 4:19 PM, Tim Vermeulen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
If ClosedRange (Range in Swift 2.2.1) has a stride(by:) method, we can change

stride(from: 0, to: 10, by: 3)

to

(0..<10).stride(by: 3)

and similarly, we can change

stride(from: 0, through: 10, by: 3)

to

(0…10).stride(by: 3)

As we can see, this syntax can replace both stride(from:to:by:) and stride(from:through:by:), and in my opinion it is more in line with the rest of Swift 3, similar to how Range.init(start:end:) will be deprecated in Swift 3 in favor of the … and ..< operators.

I’m not sure if this proposed stride(by:) method could replace all uses of stride(from:to:by:) and stride(from:through:by:), but I think that at the very least it would be a nice addition to the standard library.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #4

* that there was no one obvious behavior with a negative stride size
(range operators require a smaller number on the lhs and a bigger one on
the rhs, so you can't write `9...0`, but stride(from:to:by) can start from
a bigger number to a smaller one, so there is a difference here that went
through a lot of bikeshedding; there were several important people that
made it clear that Range would not be modified for this use case, so it's
stride semantics that must change)
* that for floating point ranges, removing stride(from:to:by:) in favor of
striding(by:) would eliminate the possibility of expressing certain strides
with open lower bound and negative stride size, partially motivating new
range operators that are a whole nother issue

These are all great reasons why stride(from:to:by:) shouldn’t be removed,
that I had not thought of. But isn’t this a good reason to let both
function co-exist?

For example: (0..<10).striding(by: 3) and stride(from: 0, to: 10, by: 3)
look quite similar. However, in case we already have a range variable,
someRange.striding(by: 3) is obviously a lot more readable than
stride(from: someRange.startIndex, to: someRange.endIndex, by: 3). The
reason I’m giving this example is that the two functions can have quite
different use cases, so I’m unsure why one of them must be removed in favor
of the other.

* that stride(by:), or rather striding(by:), was too verbose

striding(by:) doesn’t have the from, to, though parameter labels that the
Swift 3 stride functions have, so to me this new method seems less verbose
than the others. Maybe it depends on how you look at it. “to” and “through”
basically refer to the “.” and “<“ tails of the “…” and “..<“ operators
respectively, so that’s mainly why I think striding(by:) would be a cleaner
and more intuitive way to stride through a sequence.

Not all of these bullet points I've summarized above were points of view
that I personally espouse :slight_smile:

···

On Fri, May 20, 2016 at 5:40 PM, Tim Vermeulen <tvermeulen@me.com> wrote:

On 21 May 2016, at 00:07, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

We've had this discussion on a few occasions. Unfortunately, copying links
at the moment is a little tough, but I hope to do so at a later time (or
others can jump in here).

The gist of the previous discussion centered on a few objections:
* that stride(by:), or rather striding(by:), was too verbose
* that both stride(from:to:by:) and Range.striding(by:) should not
co-exist, so one would have to be removed in favor of the other
* that there was no one obvious behavior with a negative stride size
(range operators require a smaller number on the lhs and a bigger one on
the rhs, so you can't write `9...0`, but stride(from:to:by) can start from
a bigger number to a smaller one, so there is a difference here that went
through a lot of bikeshedding; there were several important people that
made it clear that Range would not be modified for this use case, so it's
stride semantics that must change)
* that for floating point ranges, removing stride(from:to:by:) in favor of
striding(by:) would eliminate the possibility of expressing certain strides
with open lower bound and negative stride size, partially motivating new
range operators that are a whole nother issue

On Fri, May 20, 2016 at 4:19 PM, Tim Vermeulen via swift-evolution < > swift-evolution@swift.org> wrote:

If ClosedRange (Range in Swift 2.2.1) has a stride(by:) method, we can
change

stride(from: 0, to: 10, by: 3)

to

(0..<10).stride(by: 3)

and similarly, we can change

stride(from: 0, through: 10, by: 3)

to

(0…10).stride(by: 3)

As we can see, this syntax can replace both stride(from:to:by:) and
stride(from:through:by:), and in my opinion it is more in line with the
rest of Swift 3, similar to how Range.init(start:end:) will be deprecated
in Swift 3 in favor of the … and ..< operators.

I’m not sure if this proposed stride(by:) method could replace all uses
of stride(from:to:by:) and stride(from:through:by:), but I think that at
the very least it would be a nice addition to the standard library.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #5

    * that there was no one obvious behavior with a negative stride size (range
    operators require a smaller number on the lhs and a bigger one on the rhs,
    so you can't write `9...0`, but stride(from:to:by) can start from a bigger
    number to a smaller one, so there is a difference here that went through a
    lot of bikeshedding; there were several important people that made it clear
    that Range would not be modified for this use case, so it's stride semantics
    that must change)
    * that for floating point ranges, removing stride(from:to:by:) in favor of
    striding(by:) would eliminate the possibility of expressing certain strides
    with open lower bound and negative stride size, partially motivating new
    range operators that are a whole nother issue

These are all great reasons why stride(from:to:by:) shouldn’t be removed, that I
had not thought of. But isn’t this a good reason to let both function co-exist?

I am very fond of the idea of getting rid of the somewhat ugly and
potentially misinterpretable to:/through: labels by using the semantics
already embedded in ranges (in fact, I proposed it originally).
However, I appreciate the reasons we might need the other forms and am
wary of creating a design with duplicated functionality that doesn't
appear to have coherence. My conclusion is that we don't quite yet know
what the right design is.

For example: (0..<10).striding(by: 3) and stride(from: 0, to: 10, by: 3) look
quite similar. However, in case we already have a range variable,
someRange.striding(by: 3) is obviously a lot more readable than stride(from:
someRange.startIndex, to: someRange.endIndex, by: 3). The reason I’m giving this
example is that the two functions can have quite different use cases, so I’m
unsure why one of them must be removed in favor of the other.

We don't normally add duplicated functionality as syntactic sugar unless
the use case for it is *extremely* common and compelling. I'm not sure
this rises to that level. If stride(from:to:by:) is more general than
Range.striding(by:), I am hard pressed to justify adding the latter
form, as much as I love it.

···

on Fri May 20 2016, Tim Vermeulen <swift-evolution@swift.org> wrote:

    * that stride(by:), or rather striding(by:), was too verbose

striding(by:) doesn’t have the from, to, though parameter labels that the Swift
3 stride functions have, so to me this new method seems less verbose than the
others. Maybe it depends on how you look at it. “to” and “through” basically
refer to the “.” and “<“ tails of the “…” and “..<“ operators respectively, so
that’s mainly why I think striding(by:) would be a cleaner and more intuitive
way to stride through a sequence.

    On 21 May 2016, at 00:07, Xiaodi Wu > <xiaodi.wu@gmail.com> wrote:

    We've had this discussion on a few occasions. Unfortunately, copying links
    at the moment is a little tough, but I hope to do so at a later time (or
    others can jump in here).

    The gist of the previous discussion centered on a few objections:

    * that stride(by:), or rather striding(by:), was too verbose
    * that both stride(from:to:by:) and Range.striding(by:) should not co-exist,
    so one would have to be removed in favor of the other
    * that there was no one obvious behavior with a negative stride size (range
    operators require a smaller number on the lhs and a bigger one on the rhs,
    so you can't write `9...0`, but stride(from:to:by) can start from a bigger
    number to a smaller one, so there is a difference here that went through a
    lot of bikeshedding; there were several important people that made it clear
    that Range would not be modified for this use case, so it's stride semantics
    that must change)
    * that for floating point ranges, removing stride(from:to:by:) in favor of
    striding(by:) would eliminate the possibility of expressing certain strides
    with open lower bound and negative stride size, partially motivating new
    range operators that are a whole nother issue

    On Fri, May 20, 2016 at 4:19 PM, Tim Vermeulen via swift-evolution > <swift-evolution@swift.org> wrote:

    If ClosedRange (Range in Swift 2.2.1) has a stride(by:) method, we can
        change

        stride(from: 0, to: 10, by: 3)

        to

        (0..<10).stride(by: 3)

        and similarly, we can change

        stride(from: 0, through: 10, by: 3)

        to

        (0…10).stride(by: 3)

        As we can see, this syntax can replace both stride(from:to:by:) and
        stride(from:through:by:), and in my opinion it is more in line with the
        rest of Swift 3, similar to how Range.init(start:end:) will be
        deprecated in Swift 3 in favor of the … and ..< operators.

        I’m not sure if this proposed stride(by:) method could replace all uses
        of stride(from:to:by:) and stride(from:through:by:), but I think that at
        the very least it would be a nice addition to the standard library.
        _______________________________________________
        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

--
Dave