[Discussion] stride behavior and a little bit of a call-back to digital numbers

Should ranges drop that precondition then? So they can represent forward and backward progressions?

···

On Mar 3, 2016, at 8:10 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

on Tue Mar 01 2016, Haravikk <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I still wonder if a better solution might involve the same syntax as ranges currently benefit from, i.e:

  0 ..< 10 // [0, 10) with an increment of 1
  (0 … 10).stride(2) // [0, 10] with an increment of 2

The most important change is that the default type for this should be able to handle higher starting indices, e.g:

  (10 … 0).stride(2) // [10, 0] with a decrement of 2

I like this approach a lot. We have lots of different ways to express
variations on ranges and intervals today that don't actually involve the
range operators (including prefixTo, suffixFrom, stride). IMO they
should.

The one problem I anticipate is that negative strides won't work well,
because forming (a...b) will have a precondition that a <= b.

I like (10 … 0).stride(2) including the change that (10 … 0) would be an
empty sequence and not an error.

···

On Friday, 4 March 2016, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

on Tue Mar 01 2016, Haravikk <swift-evolution@swift.org <javascript:;>> > wrote:

> I still wonder if a better solution might involve the same syntax as
ranges currently benefit from, i.e:
>
> 0 ..< 10 // [0, 10) with an increment of 1
> (0 … 10).stride(2) // [0, 10] with an increment of 2
>
> The most important change is that the default type for this should be
able to handle higher starting indices, e.g:
>
> (10 … 0).stride(2) // [10, 0] with a decrement of 2

I like this approach a lot. We have lots of different ways to express
variations on ranges and intervals today that don't actually involve the
range operators (including prefixTo, suffixFrom, stride). IMO they
should.

The one problem I anticipate is that negative strides won't work well,
because forming (a...b) will have a precondition that a <= b.

> Basically I don’t like the stride global function in the first place =)
>
> The benefit of the Range syntax is that it’s clear whether the end
> point is inclusive or exclusive, and it’s nice and succinct. The
> problem right now is just that ranges have a limit on the direction
> they can be traversed in for things like accessing slices of
> collections, in which case we’ll need to make sure that these still
> retain the same limitation.
>
>> On 1 Mar 2016, at 08:54, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org <javascript:;>> 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!
>>
>> 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...
>>
>> 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".
>>
>> The saving grace of "to" and "through" in the current situation is
>> that the latter seems intuitively to go further than the former, 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. Here, you propose adding a third
>> stride style to solve that problem, 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:
>>
>> 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?
>>
>>
>> On Mon, Feb 29, 2016 at 7:14 PM, Erica Sadun via swift-evolution > >> <swift-evolution@swift.org <javascript:;>> wrote:
>>>
>>> On Feb 29, 2016, at 5:03 PM, Joe Groff <jgroff@apple.com > <javascript:;>> wrote:
>>> I agree, splitting into two proposals is a good idea.
>>>
>>> -Joe
>>>
>>>
>>> Conventionalizing stride semantics
>>>
>>> Proposal: SE-00NN
>>> Author(s): Erica Sadun
>>> Status: TBD
>>> Review manager: TBD
>>>
>>> Swift offers two stride functions, stride(to:, by:) and
stride(through:,
>>> by:). This proposal introduces a third style and renames the existing
to and
>>> through styles.
>>>
>>> This proposal was discussed on-list in the "[Discussion] stride
behavior and
>>> a little bit of a call-back to digital numbers"thread.
>>>
>>> Motivation
>>>
>>> Strideable's function names do not semantically match the progressions
they
>>> generate. Values produced by throughdo not pass through an end point;
they
>>> stop at or before that fence. For example, 1.stride(through: 10, by: 8)
>>> returns the progress (1, 9), not (1, 9, 17). Similarly, its to function
>>> values reaches its end point. 1.stride(to:4, by:1) returns 1, 2, and
3. It
>>> never makes it to 4:
>>>
>>> The current Swift definition of to returns values in [start, end) and
will
>>> never reach end. In other words, you will never get to end.
>>> The current Swift definition of through returns values in [start,
end]. It
>>> may never reach end and certainly never goes through that value.
>>>
>>> Some definitions with the help of the New Oxford American Dictionary
>>>
>>> Moving to a value expresses "a point reached at the end of a range".
>>> To pass through a value, you should move beyond "the position or
location of
>>> something beyond or at the far end of (an opening or an obstacle)".
>>> To move towards a value is to get "close or closer" or "getting closer
to
>>> achieving (a goal)".
>>>
>>> Current Art
>>>
>>> A Strideable to sequence returns the sequence of values (self, self +
>>> stride, self + stride + stride, ... last) where last is the last value
in
>>> the progression that is less than end.
>>>
>>> A Strideable through sequence currently returns the sequence of values
>>> (self, self + stride, self + tride + stride, ... last) where last is
the
>>> last value in the progression less than or equal to end. There is no
>>> guarantee that end is an element of the sequence.
>>>
>>> The name of the calling function through suggests the progression will
pass
>>> through the end point before stopping. It does not. The name to
suggests a
>>> progression will attempt to arrive at an end point. It does not.
>>>
>>> Detail Design
>>>
>>> When striding to or through a number, the behavior does not match the
>>> meaning of the word. Swift should provide three stride styles not two.
>>>
>>> Style 1: [start, end) by interval
>>> This style is currently called to. I propose to rename it towards as
each
>>> value works towards end. The final value in the progression is less
than end
>>>
>>> Style 2: [start, end] by interval
>>> This style is currently called through. I propose to rename it to. The
>>> progression concludes with a value that is less than or equal to end.
Swift
>>> provides no guarantee that end is an element of the sequence.
>>>
>>> Style 3: [start, >=end] by interval
>>> I propose to introduce a new style called through. The final value is
>>> guaranteed to pass through end, either by finishing on end or past
end. The
>>> final value is strictly less than end + interval.
>>>
>>> A Style 3 implementation works as follows:
>>>
>>> /// A `Strideable through` sequence currently returns the sequence of
values
>>> /// (`self`, `self + stride`, `self + stride + stride`, ... *last*)
where
>>> *last*
>>> /// is the first value in the progression **greater than or equal to**
>>> `end`.
>>> /// There is no guarantee that `end` is an element of the sequence.
>>>
>>> /// Advance to the next element and return it, or `nil` if no next
>>> /// element exists.
>>> public mutating func next() -> Element? {
>>> if done {
>>> return nil
>>> }
>>> if stride > 0 ? current >= end : current <= end {
>>> done = true
>>> return current
>>> }
>>> let result = current
>>> current = current.advancedBy(stride)
>>> return result
>>> }
>>> }
>>>
>>> This solution is minimally disruptive to developers, respectful to
existing
>>> code bases, and introduces a more complete semantic set of
progressions that
>>> better matches progression names to developer expectations. (For
example,
>>> "this argument says it goes through a value but it never even reaches
that
>>> value".)
>>>
>>> Upon adopting this change, out-of-sync strides now pass through end
values:
>>>
>>> // Unit stride
>>> print(Array(1.stride(through: 10, by: 1)))
>>> // prints [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], no change
>>>
>>> // Old out-of-sync stride
>>> print(Array(1.stride(through: 10, by: 8)))
>>> // prints [1, 9]
>>>
>>> // New out-of-sync stride
>>> print(Array(1.stride(through: 10, by: 8)))
>>> // prints[1, 9, 17]
>>>
>>> There are no functional changes existing stride implementations. Only
their
>>> names change.
>>>
>>> print(Array(1.stride(towards: 10, by: 8))) // was `to`
>>> // prints [1, 9]
>>>
>>> print(Array(1.stride(to: 10, by: 8))) // was `through`
>>> // prints [1, 9]
>>>
>>> Although floating point arithmetic presents a separate and orthogonal
>>> challenge, its behavior changes if this proposal is implemented under
the
>>> current generic system. For example, through now includes a value at
(or at
>>> least close to) 2.0 instead of stopping at 1.9 due to accumulated
floating
>>> point errors.
>>>
>>> // Old
>>> print(Array(1.0.stride(through: 2.0, by: 0.1)))
>>> // prints [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9]
>>>
>>> // New
>>> print(Array(1.0.stride(through: 2.0, by: 0.1)))
>>> // prints [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
>>>
>>> // Old, does not pass through 1.9
>>> print(Array(1.0.stride(through: 1.9, by: 0.25)))
>>> // prints [1.0, 1.25, 1.5, 1.75]
>>>
>>> // New, passes through 1.9
>>> print(Array(1.0.stride(through: 1.9, by: 0.25)))
>>> // prints [1.0, 1.25, 1.5, 1.75, 2.0]
>>>
>>> Impact on Existing Code
>>>
>>> Renaming two stride functions and adding a third does not change or
break
>>> existing code. The Swift 3 migrator can easily update the names for
the two
>>> existing styles. That said, the migrator will not find in-place
workarounds
>>> like a through: 2.01 epsilon adjustment to correct for floating-point
>>> fences. By adding FIXME: notes wherever through: is found and renamed
to
>>> to:, the migrator could warn against continued use without a full
inspection
>>> and could offer links to information about the semantic changes.
>>>
>>> Alternatives Considered
>>>
>>> The only alternative at this time is "no change" to existing semantics.
>>>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <javascript:;>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <javascript:;>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <javascript:;>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-- Howard.

I think I see where we've not been connecting. You've phrased the
problem to be solved this way: "this thing says it goes through and it
doesn't, this thing says it goes to and it doesn't".

I can see why you'd see this as one single issue. You want the things
to do what they say. And we very much still need the current function
of stride(to:by:), so you rename that 'towards'. That's how you end up
with three stride styles instead of two.

I haven't been thinking of it in that way. I see what you're proposing
here as two discrete concerns:
1. You think the current things are poorly named. You propose
different names for them.
2. You think we need a new third thing. You propose a new thing.

My feedback, in a nutshell, is that I agree with you on the issue
you've identified in (1), but I quibble about the exact names--I'm
sure whatever is adopted will be great, though. (And thank you for
taking the time to describe the problem and drive this!)

However, I'm not convinced that (2) is an issue. Reading your revised
gist, I'm still not convinced. I see one example about graph axes. As
it happens, I'm about to write some code to plot some stuff, and I
haven't been regretting the lack of this third stride style. The
reason is that I very much need to compute the top of the axis before
I start striding through anything. Drawing axis tick marks comes quite
a bit after computing the axis limits. And once I've got the axis
limits, I can use the second stride style. So, no convincing use case
yet, imho. I still think we can address (1) without doing anything
about (2).

···

On Tue, Mar 1, 2016 at 2:29 PM, Erica Sadun <erica@ericasadun.com> wrote:

On Mar 1, 2016, at 12:25 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

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.

Summarizing: "Using `towards` suggests that the by value picks up the vector
direction and
can be misleading.

Response:

1. yeah.
2. but no solution is going to be ideal.
3. alternatives: approaching, movingTowards, advancedTowards. Included in
the latest
revision of the proposal.

My big issues are "this thing says it goes through and it doesn't, this
thing says it goes to and it doesn't".
So long as those are fixed reasonably well, I am happy, even without the
naming being perfect.

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

In order to separate this into two proposals, I had to make sure they
weren't depending on each other.
So this proposal *only* addresses the semantic mismatch I described 4 lines
up.

Manual epsilon adjustment is simply a floating point thing, and is discussed
at length in the
other proposal (Again, keep refreshing gist.github because both are works in
progress.)

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

First, I renamed it with the two options a...>b, a..>=b and a..=>b to
suggest "reach or greater".

Second, yes, and I added a big new section on canonical use cases.

-- E

It is reversed in SE-0006.

Dmitri

···

On Wed, Mar 2, 2016 at 1:20 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

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.

So in other other words, the change from `stride(from: 1, to: 2, by: 0.1)` to `1.stride(to: 2, by: 0.1)` is the source of the problem and should be reversed.

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/

Do all types that can be arguments for stride(...) conform to
ForwardIndexType such that they can be the end points of a Range? How
about the other way round? The documentation available online does not
make it easy to figure this out.

···

On Thu, Mar 3, 2016 at 10:23 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Should ranges drop that precondition then? So they can represent forward and
backward progressions?

On Mar 3, 2016, at 8:10 AM, Dave Abrahams via swift-evolution > <swift-evolution@swift.org> wrote:

on Tue Mar 01 2016, Haravikk <swift-evolution@swift.org> wrote:

I still wonder if a better solution might involve the same syntax as ranges
currently benefit from, i.e:

0 ..< 10 // [0, 10) with an increment of 1
(0 … 10).stride(2) // [0, 10] with an increment of 2

The most important change is that the default type for this should be able
to handle higher starting indices, e.g:

(10 … 0).stride(2) // [10, 0] with a decrement of 2

I like this approach a lot. We have lots of different ways to express
variations on ranges and intervals today that don't actually involve the
range operators (including prefixTo, suffixFrom, stride). IMO they
should.

The one problem I anticipate is that negative strides won't work well,
because forming (a...b) will have a precondition that a <= b.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I'm very reluctant, though I'll admit my reasoning is based more on gut
design instict than anything rational.

If you look at the work Dmitri is doing, the requirements on indices are
being weakened to Equatable but then strengthened to Comparable, in part
so we can do range validation and catch errors early. It feels very
weird to me to say that you can form a Range of any two equatable
things. At that point, one almost might as well replace Range with
(T,T) where T:Equatable.

···

on Thu Mar 03 2016, Erica Sadun <erica-AT-ericasadun.com> wrote:

Should ranges drop that precondition then? So they can represent
forward and backward progressions?

--
-Dave

I don't think we're terribly far apart at this point. Looking forward to your thoughts
and insights as you ponder.

-- E

···

On Mar 1, 2016, at 2:02 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I think I see where we've not been connecting. You've phrased the
problem to be solved this way: "this thing says it goes through and it
doesn't, this thing says it goes to and it doesn't".

I can see why you'd see this as one single issue. You want the things
to do what they say. And we very much still need the current function
of stride(to:by:), so you rename that 'towards'. That's how you end up
with three stride styles instead of two.

I haven't been thinking of it in that way. I see what you're proposing
here as two discrete concerns:
1. You think the current things are poorly named. You propose
different names for them.
2. You think we need a new third thing. You propose a new thing.

My feedback, in a nutshell, is that I agree with you on the issue
you've identified in (1), but I quibble about the exact names--I'm
sure whatever is adopted will be great, though. (And thank you for
taking the time to describe the problem and drive this!)

However, I'm not convinced that (2) is an issue. Reading your revised
gist, I'm still not convinced. I see one example about graph axes. As
it happens, I'm about to write some code to plot some stuff, and I
haven't been regretting the lack of this third stride style. The
reason is that I very much need to compute the top of the axis before
I start striding through anything. Drawing axis tick marks comes quite
a bit after computing the axis limits. And once I've got the axis
limits, I can use the second stride style. So, no convincing use case
yet, imho. I still think we can address (1) without doing anything
about (2).

On Tue, Mar 1, 2016 at 2:29 PM, Erica Sadun <erica@ericasadun.com> wrote:

On Mar 1, 2016, at 12:25 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

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.

Summarizing: "Using `towards` suggests that the by value picks up the vector
direction and
can be misleading.

Response:

1. yeah.
2. but no solution is going to be ideal.
3. alternatives: approaching, movingTowards, advancedTowards. Included in
the latest
revision of the proposal.

My big issues are "this thing says it goes through and it doesn't, this
thing says it goes to and it doesn't".
So long as those are fixed reasonably well, I am happy, even without the
naming being perfect.

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

In order to separate this into two proposals, I had to make sure they
weren't depending on each other.
So this proposal *only* addresses the semantic mismatch I described 4 lines
up.

Manual epsilon adjustment is simply a floating point thing, and is discussed
at length in the
other proposal (Again, keep refreshing gist.github because both are works in
progress.)

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

First, I renamed it with the two options a...>b, a..>=b and a..=>b to
suggest "reach or greater".

Second, yes, and I added a big new section on canonical use cases.

-- E

So in other other words, the change from `stride(from: 1, to: 2, by: 0.1)` to `1.stride(to: 2, by: 0.1)` is the source of the problem and should be reversed.

It is reversed in SE-0006.

Wow, as of seven days ago. That's a very pleasant surprise (and one that's probably relevant to this thread).

···

--
Brent Royal-Gordon
Architechies

I agree with Xiaodi that the use case given for the third stride style
isn't compelling because you can simply increase the upper bound of the
range that you're striding across. I'd be curious to see a reason why you'd
want to stride past a bound and only stop one "by" past the bound. Seems
like an esoteric function to include in stdlib.

Assuming there exists a compelling use case, I definitely like "beyond" or
"past" better than "through", as again the definition used for "through" in
the proposal is not a numerical one. I think the current "Strideable
through" style should keep its name.

The current "Strideable to" style is less ideally named, but I think it's
more obvious than "toward" or any of the other proposed names in the
updated gist for the reasons already discussed. Perhaps "Strideable until"
would make more sense, as that better captures the finality of "we're
stopping when we see this upper bound".

Thanks,
Seth

···

On Tue, Mar 1, 2016 at 1:20 PM Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

I don't think we're terribly far apart at this point. Looking forward to
your thoughts
and insights as you ponder.

-- E

> On Mar 1, 2016, at 2:02 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
>
> I think I see where we've not been connecting. You've phrased the
> problem to be solved this way: "this thing says it goes through and it
> doesn't, this thing says it goes to and it doesn't".
>
> I can see why you'd see this as one single issue. You want the things
> to do what they say. And we very much still need the current function
> of stride(to:by:), so you rename that 'towards'. That's how you end up
> with three stride styles instead of two.
>
> I haven't been thinking of it in that way. I see what you're proposing
> here as two discrete concerns:
> 1. You think the current things are poorly named. You propose
> different names for them.
> 2. You think we need a new third thing. You propose a new thing.
>
> My feedback, in a nutshell, is that I agree with you on the issue
> you've identified in (1), but I quibble about the exact names--I'm
> sure whatever is adopted will be great, though. (And thank you for
> taking the time to describe the problem and drive this!)
>
> However, I'm not convinced that (2) is an issue. Reading your revised
> gist, I'm still not convinced. I see one example about graph axes. As
> it happens, I'm about to write some code to plot some stuff, and I
> haven't been regretting the lack of this third stride style. The
> reason is that I very much need to compute the top of the axis before
> I start striding through anything. Drawing axis tick marks comes quite
> a bit after computing the axis limits. And once I've got the axis
> limits, I can use the second stride style. So, no convincing use case
> yet, imho. I still think we can address (1) without doing anything
> about (2).
>
>
> On Tue, Mar 1, 2016 at 2:29 PM, Erica Sadun <erica@ericasadun.com> > wrote:
>> On Mar 1, 2016, at 12:25 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
>>
>> 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.
>>
>>
>> Summarizing: "Using `towards` suggests that the by value picks up the
vector
>> direction and
>> can be misleading.
>>
>> Response:
>>
>> 1. yeah.
>> 2. but no solution is going to be ideal.
>> 3. alternatives: approaching, movingTowards, advancedTowards. Included
in
>> the latest
>> revision of the proposal.
>>
>> My big issues are "this thing says it goes through and it doesn't, this
>> thing says it goes to and it doesn't".
>> So long as those are fixed reasonably well, I am happy, even without the
>> naming being perfect.
>>
>> I must misunderstand what it is you tweaked. You still write that the
>> other proposal doesn't remove the need for manual epsilon adjustment?
>>
>>
>> In order to separate this into two proposals, I had to make sure they
>> weren't depending on each other.
>> So this proposal *only* addresses the semantic mismatch I described 4
lines
>> up.
>>
>> Manual epsilon adjustment is simply a floating point thing, and is
discussed
>> at length in the
>> other proposal (Again, keep refreshing gist.github because both are
works in
>> progress.)
>>
>> [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?
>>
>>
>> First, I renamed it with the two options a...>b, a..>=b and a..=>b to
>> suggest "reach or greater".
>>
>> Second, yes, and I added a big new section on canonical use cases.
>>
>> -- E
>>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Should ranges drop that precondition then? So they can represent
forward and backward progressions?

I think that makes a lot of sense, except for one thing: how would we express an empty range??

I'm very reluctant, though I'll admit my reasoning is based more on gut
design instict than anything rational.

If you look at the work Dmitri is doing, the requirements on indices are
being weakened to Equatable but then strengthened to Comparable, in part
so we can do range validation and catch errors early. It feels very
weird to me to say that you can form a Range of any two equatable
things. At that point, one almost might as well replace Range with
(T,T) where T:Equatable.

The difference would be that a Range can contain behavior like stride() which makes it more than just a tuple.

-Thorsten

···

Am 03.03.2016 um 23:25 schrieb Dave Abrahams via swift-evolution <swift-evolution@swift.org>:

on Thu Mar 03 2016, Erica Sadun <erica-AT-ericasadun.com> wrote:

Indeed! For me, the reverted syntax makes sufficient sense.

···

On Wed, Mar 2, 2016 at 3:58 AM Brent Royal-Gordon <brent@architechies.com> wrote:

>> So in other other words, the change from `stride(from: 1, to: 2, by:
0.1)` to `1.stride(to: 2, by: 0.1)` is the source of the problem and should
be reversed.
>
> It is reversed in SE-0006.

Wow, as of seven days ago. That's a very pleasant surprise (and one that's
probably relevant to this thread).

--
Brent Royal-Gordon
Architechies

+1 from me as well

-Thorsten

···

Am 02.03.2016 um 15:34 schrieb Xiaodi Wu via swift-evolution <swift-evolution@swift.org>:

Indeed! For me, the reverted syntax makes sufficient sense.

On Wed, Mar 2, 2016 at 3:58 AM Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:
>> So in other other words, the change from `stride(from: 1, to: 2, by: 0.1)` to `1.stride(to: 2, by: 0.1)` is the source of the problem and should be reversed.
>
> It is reversed in SE-0006.

Wow, as of seven days ago. That's a very pleasant surprise (and one that's probably relevant to this thread).

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution