[swift-evolution] [Proposal] Conventionalizing stride semantics

Xiaodi Wu xiaodi.wu at gmail.com
Tue Mar 1 13:25:40 CST 2016

Inline below.

On Tue, Mar 1, 2016 at 11:36 AM, Erica Sadun <erica at ericasadun.com> wrote:
> Do you want the stride to pick up the sign automatically? Instead of
> print(Array(10.stride(to: 0, by: -1))) // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
> current Swift
> have
> print(Array(10.stride(to: 0, by: 1))) // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
> adjusted sign
> Or am I missing your point of "if I stride from 10 towards 0 by 1"?

To clarify, I am not troubled that stride(to:by:) as it is now doesn't
pick up the sign. The point is that, if renamed to
stride(towards:by:), the English meaning of "towards" implies that it
would pick up the sign. It is a critique of the suggested renaming,
not a critique of the algorithm being renamed.

> I'm searching for a word that means "in the direction of but never
> reaching".
> print(Array(10.stride(to: 0, by: -1))) // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
> current Swift
> This never reaches 0.

I understand the aim, and I'd be greatly pleased if you found such a
word. Here my point is that "towards" doesn't quite fulfill that
purpose because, in English, (a) making strides "towards" something
has no relation to whether one in fact gets there; and (b) the
intention behind making strides "towards" something is that one does
in fact get there. The only thing that "towards" unambiguously
suggests (IMO) is that it picks up the sign, which is the one thing
that stride(towards:by:) would not do after a simple renaming from

> `until` to me suggests reaching the end-point.

If I tell someone that I'm here "until" 6 p.m., I would hope that they
do not try to find me there at 6. The implication is that, at 6, I get
up to leave.

But that's tangential to the point I'm trying to make, which is this--

Proposition 1: "Until" is one of the only words I can find where the
dictionary gives at least one definition that suggests never reaching
the end point. [For example: OED until 6(B)(c): "In similar sense
without a negative: Before the time that; before. Cf. till conj. 1c."]

Proposition 2: [I think we both accept this.] There are other meanings
of the word "until" that do suggest reaching the end point.

Conclusion with a little leap of logic: I can't think of a word in
English without this ambiguity. Clarity in naming these stride styles
may have to rely on factors other than the English meaning of the the
prepositions used for labels. One such source of clarity (for me) are
the parallels between the two stride styles and two range operators.

> Quite often, it doesn't really:
> print(Array(1.stride(to:10, by: 8))) // [1, 9]
> print(Array(1.stride(through:10, by: 8))) // [1, 9]

I'm aware, and it doesn't bother me. I'm satisfied that *when* the two
do differ, `through` goes further than `to`, as their names would
imply. The argument is that this is enough to deduce, by analogy with
range operators, that one is closed and the other half-open.

> Actually, I've tweaked it this morning to take care of that. Reload:
> https://gist.github.com/erica/cf50f3dc54bb3a090933

I must misunderstand what it is you tweaked. You still write that the
other proposal doesn't remove the need for manual epsilon adjustment?

> It's really solving the 1/10/by 8 problem more than the 2.0 problem. Which
> is a big reason why I even
> brought up the issue of separating the proposals in the first place.  To me,
> the following just doesn't make
> sense:
> print(Array(1.stride(through:10, by: 8))) // [1, 9]

I'm not pleased with it, but I can make sense of it if I contort my
thinking a little:
Take the numbers 1 through 10, stride through that range by 8. You
must get: 1, 9.

In other words, the contortion I must accept is this: "through"
doesn't go with "stride", even though it should. Mentally rearrange to
put "through" between start and end, moving the word "stride" after
the end: 1 through 10, stride by 8. With this approach, I can
understand why someone would name the two stride styles "to" and
"through". Consider the typical (American?) English phrase "open Mon
thru Fri, 9 to 5": Fri is included, but 5 is excluded.

> Canonical use-cases for all three styles:
> 1 towards 5 by 1: [1, 2, 3, 4]
> This style mimics a..<b but allows non-unit and negative progressions
> 1 to 5 by 1: [1, 2, 3, 4, 5]
> This style mimics a...b but allows non-unit and negative progressions
> 1 through 10 by 8: [1, 9, 17]
> This style ensures a non-unit and negative progression that passes to or
> through the final value,
> ensuring that the range of the progression fully includes the range of the
> from and to values:
> [first...last] subsumes [from...through]. You might call this a..>b

I understand that you believe this makes the behavior of "through"
more sensible. I could even agree. But do we need this third stride
style, whatever it's called? Essentially, my question is: besides the
issue of epsilon adjustments, when have you encountered a case in your
code where you've needed to stride beyond the end point?

> I like that quite a lot actually.

:) Thanks.

More information about the swift-evolution mailing list