[swift-evolution] [Proposal] Conventionalizing stride semantics

Erica Sadun erica at ericasadun.com
Tue Mar 1 11:36:20 CST 2016

> On Mar 1, 2016, at 1:54 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> It's so nice to see such care devoted to clarifying these existing
> names. I agree with the premise that stride(to:by:) and
> stride(through:by:) are poorly named, but I'd like to make two
> critiques of this proposal--
> Critique 1:
> The basic distinction between the two current stride styles is that
> one is inclusive and the other is exclusive of the end value. I agree
> with you that "to" doesn't imply an exclusive end value, but "towards"
> doesn't imply that the parameter is any sort of end value at
> all--rather, it implies just a direction (or as you quote from the
> NOAD, getting close or closer).
> Two implications:
> First, if I stride from 10 towards 0 by 1, by the plain English
> meaning of the word "towards", I would expect to obtain 10, 9, 8, 7,
> 6, etc. If we simply rename stride(to:by:) to stride(towards:by:), I
> would not get that result. By contrast, it makes sense from the
> current name that stride(to:by:) attempts to increment using the `by`
> parameter without considering whether the end value is greater than or
> less than the start value; if you can't get from here "to" there by
> such increments, too bad!

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


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"?

> Second, if I stride from 0 towards 10 by 1 (in the English language,
> not in Swift), I may or may not stop short of 10 itself. That is,
> whether "towards" is inclusive or exclusive of the end value can't be
> inferred from the meaning of the word; after all, if I'm making
> strides towards a goal, I do intend to reach it, or at least that's
> what I tell people when they ask how my PhD is going...

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.

> Generalizing from the word "towards", I don't know that any two
> prepositions in the English language can be used unambiguously to
> convey the distinction between inclusive and exclusive end values.
> Although, on some additional thought--if I had to suggest a
> preposition, perhaps "until" or "till" would be more apt than
> "towards".

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

> The saving grace of "to" and "through" in the current situation is
> that the latter seems intuitively to go further than the former,

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]

> and
> if one deduces by analogy with the range operators that one of these
> must exclude the end value and the other include it, then the two
> names must mean what they do today. With three stride styles and three
> prepositions, but only two range operators, this intuition is broken,
> while the prepositions may not get much clearer (though I must admit
> that your proposed use of "to" is an improvement).
> Critique 2:
> The original motivation behind your twin proposals was the epsilon
> adjustment necessary for floating point end values. Your other
> proposal fixes an issue with accumulated errors but doesn't solve the
> need for an epsilon adjustment.

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

> Here, you propose adding a third
> stride style to solve that problem

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

print(Array(1.stride(through:10, by: 8))) // [1, 9]

> , along the way shuffling the naming
> of the existing stride styles. Since you haven't presented other use
> cases for that third stride style here, and you haven't listed
> alternatives considered for solving the original motivating problem
> (i.e. epsilon adjustment), let me propose one alternative:

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

> Keep the naming of stride styles as-is (inapt as they may be), and for
> floating point end values make stride(through: aNumber, by: something)
> equivalent to stride(to: theNextLargestRepresentableNumber, by:
> somethingPositive) or stride(to: theNextSmallestRepresentableNumber,
> by: somethingNegative). Would that solve your original issue
> adequately?
> Alternatively, if there are lots of examples that can be envisioned
> for this third stride style, would the same examples suggest perhaps
> that `..>` might be a useful third range operator? 

I like that quite a lot actually.

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

More information about the swift-evolution mailing list