Re: [swift-evolution] Feature proposal: Range operator with step

2016-06-06 Thread Hans Huck via swift-evolution
Thorsten Seitz via swift-evolution  writes:
> 
> > Am 03.05.2016 um 13:42 schrieb Hans Huck via swift-evolution
 swift.org>:
> > 
> > Thorsten Seitz via swift-evolution  ...> writes:
> >> 
> >> -1
> >> 
> >> I don't see the need for special syntax where a method can be easily used
> > and is more general.
> >> 
> >> -Thorsten 
> >> 
> > 
> > That, dear Thorsten, is a non-argument. Why? Let's see, how about "I don't
> > see the need for a For-loop where a While-loop can be easily used and is
> > more general.“
> 
> I meant „more general“ in the sense of allowing reuse (of these methods)
in other contexts and of
> allowing more powerful abstractions (in this case expressed by simple
methods on sequences) to be used easily.
>
Yup. And that's exactly what a While-loop does in comparison to a classic
For-loop: it allows reuse in other and more general contexts, because it's a
superset in terms of functionality. So do we get rid of the latter? Of
course not, because iterating up and down is used so abundantly that it's
well worth a special case syntax.

And the special case of a "step" syntax is justified on the same grounds as
implementing a For-loop as a special case of a While-loop: you technically
don't need it, but it saves you a significant amount of redundant typing and
cognitive load.


> For the same reason I would not rate Swift’s for-loop as more general than
Scala’s for-loop which is
> more akin to Haskell’s monadic do-notation. More basic or more low level,
yes, but not more general.
> 
> -Thorsten
>
What may that possibly have got to do with the question at hand? Nobody
wants a "more general" For-loop in Swift, quite the opposite in fact: we've
just removed (due to it being a fully-fledged While-loop instead of just a
subset) the highly general C-style For-loop from the language.

You can have and keep your "powerful abstraction" in the form of "for
(0..<10).striding(by:2)"; all we ask for is to also provide "for i in 0..<10
step 2" and map it to the former internally.

The fashionable propensity towards smothering even the most basic and
iterative tasks with OOP boilerplate is exceedingly annoying. Let's keep
simple things simple, shall we?

-- Hans

 
> > 
> > The "special syntax" summarized below by Vladimir is absolutely justified,
> > because
> > 
> > a) Zipf's Law and
> 
> > b) forcing people to use convoluted OOP notation for basic, iterative tasks
> > is simply offensive.
> 
> > 
> > -- Hans
> > 
> > 
> >>> Am 18.04.2016 um 17:28 schrieb Vladimir.S via swift-evolution
> >  swift.org>:
> >>> 
> >>> On 15.04.2016 3:57, Hans Huck via swift-evolution wrote:
>  Anyway, why not just make it .step() then, like in Ruby?
>  
>  Instead of a "by" keyword, I'd be happy with syntactic sugar in the
> > form of
>  
>  for i in p1.. >>> 
> >>> As for 'step' word: It seems like for now IMO this is the best
> > suggestion : very explicit, anyone knows what
> >> "step" means especially in context of loop, clear that "step" belongs to
> > for-in construction(not to
> >> range itself).
> >>> 
> >>> for i in 0..<10 step 2 {
> >>> }
> >>> 
> >>> for i in 0..<10 step -2 {
> >>> }
> >>> 
> >>> for i in 0.1..<10.5 step 0.5 {
> >>> }
> >>> 
> >>> all are mapped to needed ranges/intervals under the hood
> >>> Do you want some custom Range-specific methods to provide steps for loop
> > - no problems, use what you need.
> >> But don't force any of us to use (0..<10).striding(by:2) for myriads of
> > simple loops in our code.
> >>> 
> >>> I want to see such constructions in our Swift. Who is with me ? :)
> > 

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-05-09 Thread Thorsten Seitz via swift-evolution

> Am 03.05.2016 um 13:42 schrieb Hans Huck via swift-evolution 
> :
> 
> Thorsten Seitz via swift-evolution  writes:
>> 
>> -1
>> 
>> I don't see the need for special syntax where a method can be easily used
> and is more general.
>> 
>> -Thorsten 
>> 
> 
> That, dear Thorsten, is a non-argument. Why? Let's see, how about "I don't
> see the need for a For-loop where a While-loop can be easily used and is
> more general.“

I meant „more general“ in the sense of allowing reuse (of these methods) in 
other contexts and of allowing more powerful abstractions (in this case 
expressed by simple methods on sequences) to be used easily.
For the same reason I would not rate Swift’s for-loop as more general than 
Scala’s for-loop which is more akin to Haskell’s monadic do-notation. More 
basic or more low level, yes, but not more general.

-Thorsten


> 
> The "special syntax" summarized below by Vladimir is absolutely justified,
> because
> 
> a) Zipf's Law and


> b) forcing people to use convoluted OOP notation for basic, iterative tasks
> is simply offensive.

> 
> -- Hans
> 
> 
>>> Am 18.04.2016 um 17:28 schrieb Vladimir.S via swift-evolution
>  swift.org>:
>>> 
>>> On 15.04.2016 3:57, Hans Huck via swift-evolution wrote:
 Anyway, why not just make it .step() then, like in Ruby?
 
 Instead of a "by" keyword, I'd be happy with syntactic sugar in the
> form of
 
 for i in p1..>> 
>>> As for 'step' word: It seems like for now IMO this is the best
> suggestion : very explicit, anyone knows what
>> "step" means especially in context of loop, clear that "step" belongs to
> for-in construction(not to
>> range itself).
>>> 
>>> for i in 0..<10 step 2 {
>>> }
>>> 
>>> for i in 0..<10 step -2 {
>>> }
>>> 
>>> for i in 0.1..<10.5 step 0.5 {
>>> }
>>> 
>>> all are mapped to needed ranges/intervals under the hood
>>> Do you want some custom Range-specific methods to provide steps for loop
> - no problems, use what you need.
>> But don't force any of us to use (0..<10).striding(by:2) for myriads of
> simple loops in our code.
>>> 
>>> I want to see such constructions in our Swift. Who is with me ? :)
> 
> 
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-05-03 Thread Hans Huck via swift-evolution
Thorsten Seitz via swift-evolution  writes:
> 
> -1
> 
> I don't see the need for special syntax where a method can be easily used
and is more general.
> 
> -Thorsten 
>

That, dear Thorsten, is a non-argument. Why? Let's see, how about "I don't
see the need for a For-loop where a While-loop can be easily used and is
more general."

The "special syntax" summarized below by Vladimir is absolutely justified,
because

a) Zipf's Law and
b) forcing people to use convoluted OOP notation for basic, iterative tasks
is simply offensive.

-- Hans

 
> > Am 18.04.2016 um 17:28 schrieb Vladimir.S via swift-evolution
 swift.org>:
> > 
> > On 15.04.2016 3:57, Hans Huck via swift-evolution wrote:
> > > Anyway, why not just make it .step() then, like in Ruby?
> > >
> > > Instead of a "by" keyword, I'd be happy with syntactic sugar in the
form of
> > >
> > > for i in p1.. > 
> > As for 'step' word: It seems like for now IMO this is the best
suggestion : very explicit, anyone knows what
> "step" means especially in context of loop, clear that "step" belongs to
for-in construction(not to
> range itself).
> > 
> > for i in 0..<10 step 2 {
> > }
> > 
> > for i in 0..<10 step -2 {
> > }
> > 
> > for i in 0.1..<10.5 step 0.5 {
> > }
> > 
> > all are mapped to needed ranges/intervals under the hood
> > Do you want some custom Range-specific methods to provide steps for loop
- no problems, use what you need.
> But don't force any of us to use (0..<10).striding(by:2) for myriads of
simple loops in our code.
> > 
> > I want to see such constructions in our Swift. Who is with me ? :)


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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-19 Thread Thorsten Seitz via swift-evolution
-1

I don't see the need for special syntax where a method can be easily used and 
is more general.

-Thorsten 

> Am 18.04.2016 um 17:28 schrieb Vladimir.S via swift-evolution 
> :
> 
> On 15.04.2016 3:57, Hans Huck via swift-evolution wrote:
> > Anyway, why not just make it .step() then, like in Ruby?
> >
> > Instead of a "by" keyword, I'd be happy with syntactic sugar in the form of
> >
> > for i in p1.. 
> As for 'step' word: It seems like for now IMO this is the best suggestion : 
> very explicit, anyone knows what "step" means especially in context of loop, 
> clear that "step" belongs to for-in construction(not to range itself).
> 
> for i in 0..<10 step 2 {
> }
> 
> for i in 0..<10 step -2 {
> }
> 
> for i in 0.1..<10.5 step 0.5 {
> }
> 
> all are mapped to needed ranges/intervals under the hood
> Do you want some custom Range-specific methods to provide steps for loop - no 
> problems, use what you need. But don't force any of us to use 
> (0..<10).striding(by:2) for myriads of simple loops in our code.
> 
> I want to see such constructions in our Swift. Who is with me ? :)
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-18 Thread Vladimir.S via swift-evolution

On 15.04.2016 3:57, Hans Huck via swift-evolution wrote:
> Anyway, why not just make it .step() then, like in Ruby?
>
> Instead of a "by" keyword, I'd be happy with syntactic sugar in the form of
>
> for i in p1..As for 'step' word: It seems like for now IMO this is the best suggestion : 
very explicit, anyone knows what "step" means especially in context of 
loop, clear that "step" belongs to for-in construction(not to range itself).


for i in 0..<10 step 2 {
}

for i in 0..<10 step -2 {
}

for i in 0.1..<10.5 step 0.5 {
}

all are mapped to needed ranges/intervals under the hood
Do you want some custom Range-specific methods to provide steps for loop - 
no problems, use what you need. But don't force any of us to use 
(0..<10).striding(by:2) for myriads of simple loops in our code.


I want to see such constructions in our Swift. Who is with me ? :)
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-15 Thread Hans Huck via swift-evolution
Brent Royal-Gordon via swift-evolution  writes:
> 
> > for i in p1.. > 
> > as syntactic sugar for and internally mapped to
> > 
> > for i in (p1.. > 
> > Best of both worlds?
> 
> Look. It is very, very unlikely that you will get people to add syntactic
> sugar *just* for striding and *just* for the for loop. If this:
> 
>   for i in (1..<10).striding(by: 2) { … }
> 
> Is so ugly that we need special syntactic sugar for it, then so is this:
> 
>   (1..<10).striding(by: 2).map { … }
> 

It's unnecessarily unwieldy, and I'd prefer `.by(x)`, `.step(x)`, or even
`.stride(x)` over `.striding(by: x)` any day. I understand potential
reservations towards "by", even though I don't share them, but these cannot
possibly apply to "step" or "stride".

> That means we would need an expression along the lines of:
> 
>   1..<10 by 2
> 
> Which could be used anywhere.
>

That's where I disagree. You see, what I'm trying to achieve here is not to
fight tooth and claw for an ever shorter step syntax in collections.

I just want to *get rid of an anomaly*, which imo justifies a new keyword
for a (heavily utilized) special case.

So far, you can fully use all core control structures in Swift without
resorting to methods/protocols, let alone noisy ones. While, While-Repeat,
If-Else, Switch, and (plain) For-In all work in a straight forward,
imperative, expected way, and that's highly desirable, because it's
intuitive and comes free of cognitive load.

But by removing (which btw I fully support) the C-style For-loop from the
language, suddenly one of the simplest and most primal tasks stands out
unpleasantly:

Counting from x to y with a step size of z -- which is the very application
the For-loop originally was created for.

Would you like to be forced to work with a While-loop like the one below?

while i.loop(initialize: 1, conditionlessorequal: 10, increaseby: 3)
 
Yeah, me neither ;)

Again: I'm not aiming at collection syntax in general; it just gets in the
line of fire, because the only remaining For-loop in Swift currently doesn't
know how to step through a sequence of numbers without making a fuss. 

-- Hans

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Dave via swift-evolution
“|” often means “with” in math, which is only one word off from “with step”.
func |  (range: Range, stride: 
T.Stride) -> IntegerStrideTo {
return IntegerStrideTo(_start: range.startIndex, end: range.endIndex, 
stride: stride)
}
var arr = [Int]()
for i in (0 ..< 10) | 2 {
arr.append(i)
}
arr //[0,2,4,6,8]

I couldn’t figure out how to do it without the parens… everything I could think 
to try is determined to parse as `(0) ..< (10 | 2)`, so `arr` ends up equalling 
[0,1,2,3,4,5,6,7,8,9]. If operator precedence and associativity were 
per-function rather than per-op, it could be made to work without the ().

- Dave Sweeris

> On Apr 14, 2016, at 8:27 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> That means we would need an expression along the lines of:
> 
>   1..<10 by 2
> 
> Which could be used anywhere. Unfortunately, Swift does not allow word 
> characters in identifiers, so `by` as an operator is a non-starter. I can't 
> think of a non-letter operator for `by` that would make sense, so we're 
> probably not going to go that route, either (but if you have a 
> suggestion—preferably one backed by existing notation from, say, math—by all 
> means suggest it).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Brent Royal-Gordon via swift-evolution
> for i in p1.. 
> as syntactic sugar for and internally mapped to
> 
> for i in (p1.. 
> Best of both worlds?

Look. It is very, very unlikely that you will get people to add syntactic sugar 
*just* for striding and *just* for the for loop. If this:

for i in (1..<10).striding(by: 2) { … }

Is so ugly that we need special syntactic sugar for it, then so is this:

(1..<10).striding(by: 2).map { … }

That means we would need an expression along the lines of:

1..<10 by 2

Which could be used anywhere. Unfortunately, Swift does not allow word 
characters in identifiers, so `by` as an operator is a non-starter. I can't 
think of a non-letter operator for `by` that would make sense, so we're 
probably not going to go that route, either (but if you have a 
suggestion—preferably one backed by existing notation from, say, math—by all 
means suggest it).

I don't think you're going to make anything happen here.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Brandon Knope via swift-evolution
What about "strideby"

Brandon 

> On Apr 14, 2016, at 8:57 PM, Hans Huck via swift-evolution 
>  wrote:
> 
> Erica Sadun via swift-evolution  writes:
>> 
>> 
>>> On Apr 14, 2016, at 1:42 PM, Hans Huck via swift-evolution
>  swift.org> wrote:
>>> Please elaborate. How could
>>> 
>>> for i in (1...10).by(3)
>>> 
>>> possibly be misinterpreted?
>> 
>> (1..<11), (4..<14), (7..<17)...
> 
> Or (3..<30)? :)
> 
> With that reasoning, "for in" would have to be changed to "for each" to
> avoid possible misinterpretation; after all, "i" could be a range and "for i
> in" could test if it's a subrange of (1...10).
> 
> Basically, there is no such thing as "unmistakable", not least because the
> very same keywords and symbols are being used for different purposes in
> different languages. There are only degrees of clarity.
> 
> Anyway, why not just make it .step() then, like in Ruby?
> 
> Instead of a "by" keyword, I'd be happy with syntactic sugar in the form of
> 
> for i in p1.. 
> too, btw.
> 
> -- Hans
> 
> 
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Hans Huck via swift-evolution
Erica Sadun via swift-evolution  writes:
> 
> 
> > On Apr 14, 2016, at 1:42 PM, Hans Huck via swift-evolution
 swift.org> wrote:
> > Please elaborate. How could
> > 
> > for i in (1...10).by(3)
> > 
> > possibly be misinterpreted?
> > 
> 
> (1..<11), (4..<14), (7..<17)...
> 

Or (3..<30)? :)

With that reasoning, "for in" would have to be changed to "for each" to
avoid possible misinterpretation; after all, "i" could be a range and "for i
in" could test if it's a subrange of (1...10).

Basically, there is no such thing as "unmistakable", not least because the
very same keywords and symbols are being used for different purposes in
different languages. There are only degrees of clarity.

Anyway, why not just make it .step() then, like in Ruby?

Instead of a "by" keyword, I'd be happy with syntactic sugar in the form of

for i in p1..https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Hans Huck via swift-evolution
Dave Abrahams via swift-evolution  writes:
> 
> 
> on Thu Apr 14 2016, Hans Huck  swift.org> wrote:
> 
> > Dave Abrahams via swift-evolution  ...> writes:
> >
> >> 
> >> If I thought extreme concision was important for this application, I'd be
> >> proposing something like 
> >> 
> >>   for x in 0.0..<20.0//1.3 {}
> >> 
> >> but personally, I don't,
> >>
> > And that is why exactly? The For-loop is at the very core of the language
> > and one of its most frequently used structures. Any unnecessary noise should
> > be avoided here.
> >
> >> which is why I propose `.striding(by: x)`
> >> rather than simply `.by(x)`, the latter being more open to
> >> misinterpretation.
> >> 
> > Please elaborate. How could
> >
> > for i in (1...10).by(3)
> >
> > possibly be misinterpreted?
> 
>   (p1.. 
> Doesn't exactly tell me what role lineCount is playing or what "by"
> does.  Maybe it means give me the range sorted by line count.  In this
> case a little more verbosity can be the difference between
> understandable and unmistakable.
> 

I find that unlikely, unless one is completely new to the language, but I
see your point -- for ranges in general.

It is impossible though to misinterprete it in the context of a For-loop, so
to keep the latter concise and the former unmistakable, what do you think of 

for i in p1..https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Erica Sadun via swift-evolution

> On Apr 14, 2016, at 1:42 PM, Hans Huck via swift-evolution 
>  wrote:
> Please elaborate. How could
> 
> for i in (1...10).by(3)
> 
> possibly be misinterpreted?
> 

(1..<11), (4..<14), (7..<17)...

-- E


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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Dave Abrahams via swift-evolution

on Thu Apr 14 2016, Hans Huck  wrote:

> Dave Abrahams via swift-evolution  writes:
>
>> 
>> If I thought extreme concision was important for this application, I'd be
>> proposing something like 
>> 
>>   for x in 0.0..<20.0//1.3 {}
>> 
>> but personally, I don't,
>>
> And that is why exactly? The For-loop is at the very core of the language
> and one of its most frequently used structures. Any unnecessary noise should
> be avoided here.
>
>> which is why I propose `.striding(by: x)`
>> rather than simply `.by(x)`, the latter being more open to
>> misinterpretation.
>> 
> Please elaborate. How could
>
> for i in (1...10).by(3)
>
> possibly be misinterpreted?


  (p1..https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-14 Thread Hans Huck via swift-evolution
Dave Abrahams via swift-evolution  writes:

> 
> If I thought extreme concision was important for this application, I'd be
> proposing something like 
> 
>   for x in 0.0..<20.0//1.3 {}
> 
> but personally, I don't,
>
And that is why exactly? The For-loop is at the very core of the language
and one of its most frequently used structures. Any unnecessary noise should
be avoided here.

> which is why I propose `.striding(by: x)`
> rather than simply `.by(x)`, the latter being more open to
> misinterpretation.
> 
Please elaborate. How could

for i in (1...10).by(3)

possibly be misinterpreted?

-- Hans

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-08 Thread Dave Abrahams via swift-evolution

on Fri Apr 08 2016, Erica Sadun  wrote:

>> On Apr 6, 2016, at 3:32 PM, Dave Abrahams  wrote:
>> 
>> 
>> on Wed Apr 06 2016, Erica Sadun  wrote:
>> 
>
>>>On Apr 6, 2016, at 3:25 PM, Dave Abrahams  wrote:
>>> 
>>>These all look reasonable to me.
>>> 
>>>Lastly, if you want the positive stride reversed, you'd do just that:
>>> 
>>>(0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]
>>> 
>>>Also reasonable.
>>> 
>>>-- 
>>>Dave
>>> 
>>> Unless there's a compelling reason to fight here, it looks like the
>>> opinion against where I'm standing is pretty overwhelming at least in
>>> this subgroup. To simplify things going forward (and to avoid compiler
>>> warnings, which as Dave A points out is probably an indication of bad
>>> design more than bad users), I'm willing to adopt in as well.
>> 
>> Thanks.  In that case, I suggest that we entertain two separate
>> proposals:
>> 
>> 1. add the .striding(by: n) method.
>> 2. add the other range operators.
>> 
>> Though they both have obvious benefits, I expect #1 is a much easier
>> sell than #2, which is one good reason to separate them.
>> 
>> -- 
>> Dave
>
> I may have misunderstood the intent so I want to clarify: Dave, you'd like to 
> push on these
> now (starting with #1) and not wait for the rest of the Range stuff to
> come online, right?

I'd like to make progress on #1. I think we should hold
the review until the new range stuff is reviewed (happening in the next
few days).  I'm still slightly undecided about #2, but I think it
deserves its own distinct discussion in this list.  #2 might imply some
changes to the protocols we're introducing in the swift-3-indexing-model
branch/proposal, so it needs a little time to percolate here I think.

needing-to-get-back-to-proposal-writing-now'ly yr's,

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-08 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 3:32 PM, Dave Abrahams  wrote:
> 
> 
> on Wed Apr 06 2016, Erica Sadun  wrote:
> 
>>On Apr 6, 2016, at 3:25 PM, Dave Abrahams  wrote:
>> 
>>These all look reasonable to me.
>> 
>>Lastly, if you want the positive stride reversed, you'd do just that:
>> 
>>(0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]
>> 
>>Also reasonable.
>> 
>>-- 
>>Dave
>> 
>> Unless there's a compelling reason to fight here, it looks like the
>> opinion against where I'm standing is pretty overwhelming at least in
>> this subgroup. To simplify things going forward (and to avoid compiler
>> warnings, which as Dave A points out is probably an indication of bad
>> design more than bad users), I'm willing to adopt in as well.
> 
> Thanks.  In that case, I suggest that we entertain two separate
> proposals:
> 
> 1. add the .striding(by: n) method.
> 2. add the other range operators.
> 
> Though they both have obvious benefits, I expect #1 is a much easier
> sell than #2, which is one good reason to separate them.
> 
> -- 
> Dave

I may have misunderstood the intent so I want to clarify: Dave, you'd like to 
push on these
now (starting with #1) and not wait for the rest of the Range stuff to come 
online, right?

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-08 Thread Brent Royal-Gordon via swift-evolution
> At the risk of asking one of those newbie questions, why bother with StrideTo 
> and StrideThrough? Isn't a Generator or Array more to the point?

You don't want to return an Array because you want to generate the values 
lazily. If `stride(over: 1..<1_000_000, by: 10)` returned an Array, you would 
have to allocate an array with 100,000 elements. A StrideTo, by contrast, is 
the size of roughly 3 elements; it creates the values on demand.

You can't return Generator because Generator is a protocol with no real 
behavior associated with it; you need a concrete type. StrideTo and 
StrideThrough conform to Sequence, a protocol whose main purpose is to return a 
Generator. (well, Iterator in Swift 3). So in essence, StrideTo and 
StrideThrough *are* how you return a Generator.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Dave via swift-evolution
> On Mar 30, 2016, at 12:26 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I didn't seem to ever need division. See attached playground (which
> borrows shamelessly from existing code and Erica's proposal, and which
> is written in Swift 2.2 because that's what I had handy).

Appending the following code to the playground reveals a bug/glitch:
import Darwin
let start = pow(2.0, 54)
let end = nextafter(start, Double.infinity)
let containsRepeatedValues = Array((start..___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Dave via swift-evolution
At the risk of asking one of those newbie questions, why bother with StrideTo 
and StrideThrough? Isn't a Generator or Array more to the point?
> On Apr 7, 2016, at 5:59 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> I'm confused. There is an instance owning the start and end. It's called 
>> StrideTo or StrideThrough, conforms to Sequence (with a FIXME comment that 
>> it should conform to Collection) and is distinct from Range and from the 
>> Strideable bounds themselves. Is that different from what you're describing?
> 
> Yes, it is different. StrideTo and StrideThrough represent the sequence 
> resulting from the striding operation. If there was only one of them, you 
> would probably call it StrideSequence. They are the *result* of the `stride` 
> function or `striding` method.

- Dave Sweeris
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Xiaodi Wu via swift-evolution
Conceptually, maybe? But of course the sequence is lazily evaluated, so the
only state stored in an instance of StrideTo is one value for the current
iteration; all the other properties in a StrideTo are just the inputs to
the stride function, and no length is computed let alone stored. I get that
you want something that represents the input instead of the output, but
what do you gain from that type not achievable otherwise?
On Thu, Apr 7, 2016 at 6:59 PM Brent Royal-Gordon 
wrote:

> > I'm confused. There is an instance owning the start and end. It's called
> StrideTo or StrideThrough, conforms to Sequence (with a FIXME comment that
> it should conform to Collection) and is distinct from Range and from the
> Strideable bounds themselves. Is that different from what you're describing?
>
> Yes, it is different. StrideTo and StrideThrough represent the sequence
> resulting from the striding operation. If there was only one of them, you
> would probably call it StrideSequence. They are the *result* of the
> `stride` function or `striding` method.
>
> What I'm talking about is a single instance which represents what you are
> striding *over*, but *not* the length of the stride. It is an *input* to
> the `stride` function or `striding` method.
>
> Does that make sense?
>
> --
> Brent Royal-Gordon
> Architechies
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Brent Royal-Gordon via swift-evolution
> I'm confused. There is an instance owning the start and end. It's called 
> StrideTo or StrideThrough, conforms to Sequence (with a FIXME comment that it 
> should conform to Collection) and is distinct from Range and from the 
> Strideable bounds themselves. Is that different from what you're describing?

Yes, it is different. StrideTo and StrideThrough represent the sequence 
resulting from the striding operation. If there was only one of them, you would 
probably call it StrideSequence. They are the *result* of the `stride` function 
or `striding` method.

What I'm talking about is a single instance which represents what you are 
striding *over*, but *not* the length of the stride. It is an *input* to the 
`stride` function or `striding` method.

Does that make sense?

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Xiaodi Wu via swift-evolution
I'm confused. There is an instance owning the start and end. It's called
StrideTo or StrideThrough, conforms to Sequence (with a FIXME comment that
it should conform to Collection) and is distinct from Range and from the
Strideable bounds themselves. Is that different from what you're describing?

If I'm not misunderstanding, you're asking for a protocol common to
StrideTo and StrideThrough to which other types such as a hypothetical
NSDateStride could conform?

On Thu, Apr 7, 2016 at 5:25 PM Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> >> Actually, it would need to be something like
> >> `calendar[startDate.. >> NSCalendarUnit is not itself a stride, it is the *unit* of the
> >> stride.
> >
> > Maybe:
> >
> >  calendar.days[startDate..
> I've been leaning towards parameters for additional flexibility, but the
> difference there is only slightly more than bikeshedding.
>
> > However, it doesn't explain why
> >
> >  calendar[startDate.. >
> > “doesn't quite help.”  It seems to me that
> >
> >  calendar[startDate.. >
> > does factor in the calendar and unit.
>
> Yes, it does—as long as Strideable changes so that the instance created by
> this expression participates in the striding. My point is that, as long as
> the operations in Strideable are performed on one of the two strides, the
> "range" we're moving over can't be involved enough to help. Striding has to
> be done with the assistance of the instance owning the start and end, not
> just the start and end themselves.
>
> Basically, what I'm saying is that Strideable needs a redesign along the
> lines of the indexing system. We redesigned indexing so that the collection
> manipulates the indexes, rather than the indexes manipulating themselves,
> because the indexes don't always have enough information to do the job. We
> need to do the same thing with Strideable.
>
> >> For example, suppose you modify `Strideable` so that, instead of
> >> applying to the values participating in the striding, it applies to
> >> the instance containing those values:
> >>
> >>  public protocol Strideable {
> >>  associatedtype Element: Comparable
> >>  associatedtype Stride: SignedNumber
> >>
> >>  var start: Value
> >>  var end: Value
> >>
> >>  public func distance(from earlier: Element, to later:
> Element) -> Stride
> >>  public func advance(element: Element, by stride: Stride)
> -> Element
> >>  }
> >
> > Presumably you mean for Strideable to have a striding(by:_) method as
> well?
>
> Yes, there would be an extension method like that (or there would be a
> `func stride(over: StrideableType, by:
> StrideableType.Stride) -> …`, which is the same thing). I didn't include it
> because it's not a requirement imposed on the conforming type.
>
> > If so, how is this fundamentally different from Collection?  Shouldn't
> > every Collection support this?
>
> Huh, interesting. Very, very interesting.
>
> Strideable is more widely applicable than Collection; for instance, a
> Range can't be a Collection (except via `nextafter`), but it is
> Strideable. But every RandomAccessCollection can be Strideable. (So could
> any BidirectionalCollection, for that matter, although it would be slower.)
> `array.striding(by: 2)` is a coherent and useful operation.
>
> So yes, I think every Collection (with a suitable index) could be
> Strideable. But there are Strideable things which aren't collections.
>
> > Except we don't have that capability today.  Instead we'd be using
> > overloads of ..< and ... to produce more-capable range types, c.f.
> >
> https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/Range.swift#L504
> >
> https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/Range.swift#L519
>
> That works too, I suppose. You would end up with a StrideableRange
> "between" your current CountableRange (which is a Collection) and Range
> (which is a glorified tuple).
>
> --
> Brent Royal-Gordon
> Architechies
>
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Brent Royal-Gordon via swift-evolution
>> Actually, it would need to be something like
>> `calendar[startDate..> NSCalendarUnit is not itself a stride, it is the *unit* of the
>> stride. 
> 
> Maybe:
> 
>  calendar.days[startDate.. However, it doesn't explain why
> 
>  calendar[startDate.. 
> “doesn't quite help.”  It seems to me that 
> 
>  calendar[startDate.. 
> does factor in the calendar and unit.

Yes, it does—as long as Strideable changes so that the instance created by this 
expression participates in the striding. My point is that, as long as the 
operations in Strideable are performed on one of the two strides, the "range" 
we're moving over can't be involved enough to help. Striding has to be done 
with the assistance of the instance owning the start and end, not just the 
start and end themselves.

Basically, what I'm saying is that Strideable needs a redesign along the lines 
of the indexing system. We redesigned indexing so that the collection 
manipulates the indexes, rather than the indexes manipulating themselves, 
because the indexes don't always have enough information to do the job. We need 
to do the same thing with Strideable.

>> For example, suppose you modify `Strideable` so that, instead of
>> applying to the values participating in the striding, it applies to
>> the instance containing those values:
>> 
>>  public protocol Strideable {
>>  associatedtype Element: Comparable
>>  associatedtype Stride: SignedNumber
>> 
>>  var start: Value
>>  var end: Value
>> 
>>  public func distance(from earlier: Element, to later: Element) 
>> -> Stride
>>  public func advance(element: Element, by stride: Stride) -> 
>> Element
>>  }
> 
> Presumably you mean for Strideable to have a striding(by:_) method as well?

Yes, there would be an extension method like that (or there would be a `func 
stride(over: StrideableType, by: 
StrideableType.Stride) -> …`, which is the same thing). I didn't include it 
because it's not a requirement imposed on the conforming type.

> If so, how is this fundamentally different from Collection?  Shouldn't
> every Collection support this?

Huh, interesting. Very, very interesting.

Strideable is more widely applicable than Collection; for instance, a 
Range can't be a Collection (except via `nextafter`), but it is 
Strideable. But every RandomAccessCollection can be Strideable. (So could any 
BidirectionalCollection, for that matter, although it would be slower.) 
`array.striding(by: 2)` is a coherent and useful operation.

So yes, I think every Collection (with a suitable index) could be Strideable. 
But there are Strideable things which aren't collections.

> Except we don't have that capability today.  Instead we'd be using
> overloads of ..< and ... to produce more-capable range types, c.f.  
> https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/Range.swift#L504
> https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/Range.swift#L519

That works too, I suppose. You would end up with a StrideableRange "between" 
your current CountableRange (which is a Collection) and Range (which is a 
glorified tuple).

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Ted F.A. van Gaalen via swift-evolution
Hi All.

nearly no one has yet reacted on my mail, echoed here again,

which leaves by me the following questions pending:

-does what I define and describe completely cover all the required functionality
 for ranges for all numerical types?

-does it eliminate the need for using “Stride(...)”  at least for numerical 
scalars?

-combined with for .. in…  , is it an adequate replacement for the  classical 
for loop?

-can we eliminate  half open operators? Because imho that would simplify things 
greatly.
  -to which text of Dijkstra is this related?  


Objections? 
improvements? 
Things that I have missed? 
Feasibility? 
Implementable?

Thanks
TedvG





> On 06.04.2016, at 22:43, Ted F.A. van Gaalen  wrote:
> 
> 
> 
> Hi Erica, Dave
> 
> Based on what I’ve (not all) read under this topic: 
> 
> I’d suggest a more complete approach:
> 
> Ranges should support:  (as yet not implemented) 
> 
> - All numerical data types (Double, Float, Int, Money***, Decimal*** ) 
> - An arbitrary increment or decrement value.
> - Working in the complete  - + numerical range
> - Allow traversing in both   - + directions.
> 
> 
> 
> The basics:
> 
> (v1…v2).by(v3) // this still is readable. and can be optimized by the 
> compiler (predictable sequence)
> 
> Rules:
> 
> v1, v2, v3  are any numerical type scalar type  
> v1, v2, v3  must have the same numerical type.
> v1 >  v2:   is allowed and correctly evaluated.  e.g. 
> (8.0…-3.14159).by(-0.0001) 
> 
> 
> The  ..<  half open operator is no longer allowed.   write e.g.   
> 0...ar.count - 1
> 
> "by(…)”  is obligatory with floating point range.
> 
>the default “by(…)” value of 1 makes sense only with integer 
> ranges.
> 
> 
> valid examples:
> (5…9)// 5 6 7 8 9 Integer range without “by” 
> defaults to 1 as increment value.
> (1...10).by(2) // 1 3 5 7 9.
> (2...10).by(2) // 2 4 6 8 10.
> (4…-4).by(-2) // 4  2 0 -2 -4 .// runs backwards  
> <<<
> (30..-10).by(-2)// 30 28 26 24 22 ….. -10.
> (10...0).by(-3)  // 10 7 4 1. 
> 
> (12…-10) // is valid, but returns empty because default 
> increment value = 1
> 
> (12.0…-12.0).by(-1.5)   // 12.0  10.5  9.0….  // of course 
> with float imprecision
>
>
> 
>invalid examples:
> 
>(23.0..<60.5).by(0.5) // half open ranges are no  longer allowed 
> ** 
>   (23.0…60.5) // “ by"  is obligatory with floats.
>   (14...8).by(0.5)//  v1 v2 and v3 don’t have the same 
> numerical type 
> 
> 
> Half open ranges make no real sense (are not really useful) with floating 
> point values.
> and no sense at all with e.g (12..<-1)  afaics 
> 
> 
> At least for float iterations the increment value should not each time be 
> accumulated like
> v1 += v3;  v1 += v3;  v1 += v3;  ….   // causes float 
> number drift.
> but be freshly multiplied with each iteration, e.g. by using an internal 
> iteration counter
> like so:
> 
> v = v1 + v3 * i++; v = v1 + v3 * i++;  v = v1 + v3 * i++;  v = v1 + 
> v3 * i++; <<<
> 
> for reasons of precision.
> 
> If one has worked with floating point data more often
> awareness of its precision limitations become a second nature conscience. 
> E.g. it is perfectly acceptable and known (also in classical for-loops) that
> (0.0…1.0).by(0.1) is not guaranteed to reach the humanly expected value of 
> 1.0.
> This is normal. Due to the nature of what mostly is done in the
> floating point numbers domain, this does not often cause a problem
> (e.g like working with a slide ruler) 
> if it is important to reach the “expected end” then one could
> -add an epsilon value like so (v1…v2 + 0.1) 
> -generate the desired float sequence within an integer loop.
> 
> 
> The above “range” (imho) improvement makes the 
> stride.. function/keyword completely unnecessary.
> 
> Due to its ability to process reversed ranges as is, 
> the .reverse() is optional (no longer necessary in most cases,
> allowing the compiler to optimize without having to process 
> it like a collection.
> 
> 
> Now that we have a fully functional range, which can do all things desired, 
> one can
> then of course, pass this range without any change  to a collection based for 
> …  e.g.
> 
> for v in (v1…v2).by(v3)   // optionally add other collection 
> operators/filters/sorts here
> 
> (or in any other construct you might see fit)
>
> 
> This seems to be a reasonable alternative for
> 
> - the classical for ;; loop
> -the collection-free for-loop  
>  for v from v1 to v2 by v3
> 
> As you know, the latter is what I have been suggesting, 
> but seemingly does not find much support,
> (because I received very lit

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Dave Abrahams via swift-evolution

on Thu Apr 07 2016, Brent Royal-Gordon  wrote:

>>> calendar.using(.Day).stride(from: startDate, to: endDate, by: 1)
>> 
>>> The `start` and `end` parameters could be grouped together into a
>>> single parameter to match `stride(over:by:)`, but you can't put the
>>> calendar or the unit into the stride—without them, there is no
>
>>> coherent way to calculate the distance between two dates.
>>> 
>>> So if some types need a strider, and will need to have the method
>>> structured as `strider.stride(something:by:)`, it seems like the
> free
>>> function version for types which *don't* need a strider ought to be
>>> `stride(something:by:)`. The `something.striding(by:)` design can't
> be
>>> easily adapted to this situation.
>> 
>>  calendar[startDate..> 
>> ?
>
> Actually, it would need to be something like
> `calendar[startDate.. NSCalendarUnit is not itself a stride, it is the *unit* of the
> stride. 

Maybe:

  calendar.days[startDate.. But even that doesn't quite help.
>
> Here's the issue.
>
> Take a look at today's Strideable. Stripped of comments and irrelevant
> annotations, you have:
>
>   protocol Strideable : Comparable {
>   associatedtype Stride : SignedNumberType
>   func distanceTo(other: Self) -> Stride
>   func advancedBy(n: Stride) -> Self
>   }
>
> The problem is that there's no good way to get the calendar and unit
> into these methods. If you package them inside `Stride`, then
> `distanceTo` has no idea what calendar or unit it's supposed to
> return. If you package them inside `Self`, then `distanceTo` has two
> calendars and two units, and they might not agree (and the type system
> can't catch this issue).
>
> To fix this, you need to have a single instance which performs the
> calculation. For simple Strideable types, this instance would not do
> very much, but for dates, it would factor in the calendar and unit.

I follow all the above; it's a good explanation of the problem.
However, it doesn't explain why

  calendar[startDate.. For example, suppose you modify `Strideable` so that, instead of
> applying to the values participating in the striding, it applies to
> the instance containing those values:
>
>   public protocol Strideable {
>   associatedtype Element: Comparable
>   associatedtype Stride: SignedNumber
>
>   var start: Value
>   var end: Value
>
>   public func distance(from earlier: Element, to later: Element) 
> -> Stride
>   public func advance(element: Element, by stride: Stride) -> 
> Element
>   }

Presumably you mean for Strideable to have a striding(by:_) method as well?

If so, how is this fundamentally different from Collection?  Shouldn't
every Collection support this?

> Now, with some *really* aggressive conditional conformance work, you
> could do this:
>
>   extension Range: Strideable where Element == Int {
>   typealias Stride = Int
>
>   public func distance(from earlier: Int, to later: Int)
> -> Int {
>   return later - earlier
>   }
>   public func advance(element: Int, by stride: Int) {
>   return value + stride
>   }
>   }
>   extension Range: Strideable where Element == Double {
>   // Ignoring the accumulation issue.
>   typealias Stride = Double
>
>   public func distance(from earlier: Int, to later: Int) -> Int {
>   return later - earlier
>   }
>   public func advance(element: Double, by stride: Double) {
>   return element + stride
>   }
>   }

Except we don't have that capability today.  Instead we'd be using
overloads of ..< and ... to produce more-capable range types, c.f.  
https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/Range.swift#L504
https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/Range.swift#L519

>   
>   // etc., for each type you care about.
>   // 
>   // This could be automated by creating a `RangeStrideable` protocol 
> similar to the old Strideable,
>   // and having types with this automatic behavior conform to it. You 
> could then have a single:
>   // extension Range: Strideable where Element: RangeStrideable
>
> It would not be possible to stride directly over a range of NSDates,
> but you could have a "calendar range" which could be `Strideable`,
> like so:
>
>   struct NSCalendarRange {
>   var start: NSDate
>   var end: NSDate
>
>   var calendar: NSCalendar
>   var unit: NSCalendarUnit
>
>   var options: NSCalendarOptions
>   // This mainly contains rounding options. Interestingly, NSDate 
> is like Double in that
>   // it accumulates errors through repeated addition. To fix 
> that, I have discovered
> 

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-07 Thread Brent Royal-Gordon via swift-evolution
>>  calendar.using(.Day).stride(from: startDate, to: endDate, by: 1)
> 
>> The `start` and `end` parameters could be grouped together into a
>> single parameter to match `stride(over:by:)`, but you can't put the
>> calendar or the unit into the stride—without them, there is no
>> coherent way to calculate the distance between two dates.
>> 
>> So if some types need a strider, and will need to have the method
>> structured as `strider.stride(something:by:)`, it seems like the free
>> function version for types which *don't* need a strider ought to be
>> `stride(something:by:)`. The `something.striding(by:)` design can't be
>> easily adapted to this situation.
> 
>  calendar[startDate.. 
> ?

Actually, it would need to be something like `calendar[startDate.. Stride
func advancedBy(n: Stride) -> Self
}

The problem is that there's no good way to get the calendar and unit into these 
methods. If you package them inside `Stride`, then `distanceTo` has no idea 
what calendar or unit it's supposed to return. If you package them inside 
`Self`, then `distanceTo` has two calendars and two units, and they might not 
agree (and the type system can't catch this issue). 

To fix this, you need to have a single instance which performs the calculation. 
For simple Strideable types, this instance would not do very much, but for 
dates, it would factor in the calendar and unit.

For example, suppose you modify `Strideable` so that, instead of applying to 
the values participating in the striding, it applies to the instance containing 
those values:

public protocol Strideable {
associatedtype Element: Comparable
associatedtype Stride: SignedNumber

var start: Value
var end: Value

public func distance(from earlier: Element, to later: Element) 
-> Stride
public func advance(element: Element, by stride: Stride) -> 
Element
}

Now, with some *really* aggressive conditional conformance work, you could do 
this:

extension Range: Strideable where Element == Int {
typealias Stride = Int

public func distance(from earlier: Int, to later: Int) -> Int {
return later - earlier
}
public func advance(element: Int, by stride: Int) {
return value + stride
}
}
extension Range: Strideable where Element == Double {
// Ignoring the accumulation issue.
typealias Stride = Double

public func distance(from earlier: Int, to later: Int) -> Int {
return later - earlier
}
public func advance(element: Double, by stride: Double) {
return element + stride
}
}
// etc., for each type you care about.
// 
// This could be automated by creating a `RangeStrideable` protocol 
similar to the old Strideable,
// and having types with this automatic behavior conform to it. You 
could then have a single:
//  extension Range: Strideable where Element: RangeStrideable

It would not be possible to stride directly over a range of NSDates, but you 
could have a "calendar range" which could be `Strideable`, like so:

struct NSCalendarRange {
var start: NSDate
var end: NSDate

var calendar: NSCalendar
var unit: NSCalendarUnit

var options: NSCalendarOptions
// This mainly contains rounding options. Interestingly, NSDate 
is like Double in that 
// it accumulates errors through repeated addition. To fix 
that, I have discovered 
// a truly marvelous design which this email is too small to 
contain.
}
extension NSCalendarRange: Strideable {
typealias Value = NSDate
typealias Stride = Int

public func distance(from earlier: NSDate, to later: NSDate) -> 
Int {
let components = calendar.components(unit, from: 
earlier, to: later, options: options)
return components.value(forComponent: unit)
}
public func advance(value: NSDate, by stride: Int) -> NSDate {
return calendar.date(byAdding: unit, value: distance, 
to: value, options: options)!
}
}

So I guess `striding(by:)` can be adapted to date arithmetic, but only if we 
adjust our conception of what a stride is striding over.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Thorsten Seitz via swift-evolution
Dijkstra is talking about intervals of natural numbers, i.e. indices.
Range is much more general than that, including floating point ranges, so 
Dijkstra's arguments do not apply here.

-Thorsten 

Am 06.04.2016 um 23:41 schrieb Brent Royal-Gordon via swift-evolution 
:

>> From a purely numerically aesthetic point of view, I'd much prefer ranges to 
>> be 
>> openable and closable at both ends. 
>> 
>> My primary use-case has been teaching math using playgrounds but I'm sure 
>> there are lots of other real-world situations more specific to common 
>> numerical
>> method tasks.
> 
> By coincidence, a Perl hacker I know commented on Twitter yesterday that he 
> thought 1-based arrays were the way to go in the 21st century. Somebody 
> replying to that suggestion linked to a note by Dijkstra that's relevant to 
> this conversation: 
> 
> 
> I'd suggest everyone in this discussion should read it—it's only about 700 
> words—but to summarize:
> 
>1. The semantic Swift refers to as `..<` is the most natural range 
> convention.
>2. Relatedly, zero-based indexing is the most natural indexing convention.
> 
> If we agree with Dijkstra's logic, then the only reason to support `>..` is 
> for ranges where start > end—that is, when we're constructing a reversed 
> range. But if we decide to support striding backwards by using a forward 
> range and a negative stride, then that covers the reverse use case. Thus, we 
> would need neither additional range operators, nor reversed ranges.
> 
> As for the `range.striding(by:)` vs `stride(over:by:)` question, my concerns 
> there are, to be honest, mainly aesthetic. The need for parentheses around 
> the range operator is more or less unavoidable, but I think they make the 
> construct very ugly. However, I also think that the `stride(over:by:)` syntax 
> (or, for that matter `stride(from:to:by:)`) look more constructor-y (they are 
> only *not* constructors now because of the overloading), and I think it opens 
> us up to parallel constructs like the `induce(from:while:by:)` function I've 
> been working on.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Thorsten Seitz via swift-evolution


> Am 06.04.2016 um 23:26 schrieb Stephen Canon via swift-evolution 
> :
> 
> 
>> On Apr 6, 2016, at 2:25 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>>> on Wed Apr 06 2016, Erica Sadun  wrote:
>>> 
>>>   On Apr 6, 2016, at 3:05 PM, Dave Abrahams via swift-evolution
>>>wrote:
>>> 
>>>   on Wed Apr 06 2016, Xiaodi Wu  wrote:
>>> 
>>>   On Wed, Apr 6, 2016 at 3:28 PM, Dave Abrahams via swift-evolution
>>>wrote:
>>> 
>>>   You if you need to represent `<..` intervals in scientific computing,
>>>   that's a pretty compelling argument for supporting them.
>>> 
>>>   I'd like to be able to represent any of those as
>>>   Intervals-which-are-now-Ranges. It makes sense to do so 
>>> because
>>>   the
>>>   things I want to do with them, such as clamping and testing if
>>>   some
>>>   value is contained, are exactly what Intervals-now-Ranges
>>>   provide.
>>>   Looking around, it seems many other languages provide only 
>>> what
>>>   Swift
>>>   currently does, but Perl does provide `..`, `..^`, `^..`, and
>>>   `^..^`
>>>   (which, brought over to Swift, would be `...`, `..<`, `<..`, 
>>> and
>>>   `<.<`).
>>> 
>>>   Do we need fully-open ranges too?
>>> 
>>>   I haven't encountered a need for open ranges, but I would expect that
>>>   other applications in scientific computing could make use of them.
>>>   I rather like Pyry's suggestions below. 
>>> 
>>>   Below?
>>> 
>>> Logically in time below.
>> 
>> Oh! In my application, time flows downward.
>> 
>>> 
>>> I believe the following is a valid conversion of the Xiaodi Wu below into 
>>> the
>>> Dave A domain.
>>> 
>>>   On Apr 6, 2016, at 2:29 PM, Pyry Jahkola via swift-evolution
>>>wrote:
>>> 
>>>   I think a sensible specification would be that with a positive step size,
>>>   the count starts from the lower bound, and with a negative one, it starts
>>>   from the upper bound (inclusive or exclusive). Thus, the following 
>>> examples
>>>   should cover all the corner cases:
>>> 
>>>   (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]
>> 
>> These all look reasonable to me.
> 
> Agreed.

I agree as well. Makes sense.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Thorsten Seitz via swift-evolution


> Am 06.04.2016 um 23:03 schrieb Dave Abrahams via swift-evolution 
> :
> 
> 
>> on Wed Apr 06 2016, Erica Sadun  wrote:
>> 
>>On Apr 6, 2016, at 2:17 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>Guidance:
>> 
>>When using odd integer literals to produce an even number sequence,
>>prefer the `...` operator to the `..<` operator and change your ending
>>literal to an even number.
>> 
>>I don't think you can fix counterintuitive behavior with guidance. 
>> 
>>(1..<199).striding(by: -2) is the first way I'd reach for to express
>>197, 195, ..., 3, 1
>> 
>> Yes, but you can with warnings and fixits. 
>> 
>> * The compiler should issue a warning for any use of 
>> 
>> (n..> 
>> with a fixit of "replace (n..> whether n or m is known at compile time 
>> 
>> * If v cannot be known at compile time, I think the compiler should
>> always prefer ... to ..<.
>> 
>> * The compiler should not allow
>> 
>> (n..> 
>> where v is known at compile time to be a negative constant. There should 
>> also be a runtime precondition that raises a fatal error should a negative 
>> v be used with a half-open interval.
> 
> You can lessen the impact of any design choice by adding warnings and
> fixits, but I'm pretty sure it's better to make a choice that doesn't
> require them.

Absolutely! Having to add warnings and fixits just demonstrates that the design 
is confusing. 

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Thorsten Seitz via swift-evolution


> Am 06.04.2016 um 22:17 schrieb Xiaodi Wu via swift-evolution 
> :
> 
>> On Wed, Apr 6, 2016 at 1:43 PM, Dave Abrahams  wrote:
>> 
>>> on Wed Apr 06 2016, Erica Sadun  wrote:
>>> 
>>>On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>>(0..<199).striding(by: -2)
>>> 
>>>are even or odd.
>>> 
>>> (0..<199).striding(by: -2): 0..<199 == 0...198 Even
>>> (1..<199).striding(by: -2): 1..<199 == 1...198 Even
>> 
>> I understand the logic that got you there, but I find it incredibly
>> counter-intuitive that striding by 2s over a range with odd endpoints
>> should produce even numbers... I can't imagine any way I'd be convinced
>> that was a good idea.
>> 
>>> (0..<198).striding(by: -2): 1..<198 == 0...197 Odd
>>> (1..<198).striding(by: -2): 1..<198 == 1...197 Odd
> 
> One other aspect of the counterintuitiveness is that
> `(a.. essentially reversing the sequence given by `(a.. That would not be the case with the logic presented here. I worry that
> there is no obviously correct interpretation of `(a.. -c)` and wonder if any conclusion arrived at would necessarily be more
> confusing that `stride(from:to:by:)`.

Yep, that's my impression, too.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Thorsten Seitz via swift-evolution

> Am 06.04.2016 um 20:26 schrieb Erica Sadun via swift-evolution 
> :
> 
>>> On Apr 6, 2016, at 12:23 PM, Stephen Canon via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Apr 6, 2016, at 11:20 AM, Stephen Canon via swift-evolution 
  wrote:
 
 On Apr 6, 2016, at 11:16 AM, Dave Abrahams via swift-evolution 
  wrote:
 
 One question that I *do* think we should answer, is whether the elements
 of
 
(0..<199).striding(by: -2)
 
 are even or odd.
>>> 
>>> Odd.  I don’t believe that many real use cases care, but odd is more 
>>> efficient from a performance perspective.  Needs to be documented clearly, 
>>> however.
>> 
>> Sorry, I was thinking of (0…199).striding(by: -2).
>> 
>> For the (0..<199) case, Erica’s assessment seems about right, though it 
>> isn’t at all obvious how it generalizes to floating point strides.
> 
> (l.. cannot be a starting value.

Why?
The starting value could quite naturally be s = l + k*dX for the largest value 
of k in the natural numbers for which s < h, wouldn't it?

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Matthew Judge via swift-evolution


> On Apr 6, 2016, at 17:00, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Wed Apr 06 2016, Erica Sadun  wrote:
> 
>>> On Apr 6, 2016, at 2:17 PM, Xiaodi Wu  wrote:
>>> Prohibiting StrideTo with floating-point ranges altogether would be
>>> distressing. IMO, it's plenty distressing that backwards
>>> floating-point StrideTo as it currently exists might go away.
>> 
>> I wouldn't suggest doing so. I'm just saying that for a half-open interval, 
>> there is no max value
>> so it makes no sense mathematically to have a first value and a
>> negative step.
> 
> I don't agree.  It seems to me that striding downwards over a half-open
> range r should always begin with r.upperBound - s (modulo any necessary
> adjustments to avoid FP error), where -s is the stride amount.  Why is
> that mathematical nonsense?
> 
This doesn't seem intuitive to me at all.

I can think of three interpretations of '(lBound.. Another point to consider: striding is also a sensible operation over
> collections, and some ranges are collections.  The stride semantics must
> coincide in those cases.  I expect that constraint narrows down the
> reasonable semantic choices considerably.
> 
>> You're not so restricted with:
>> 
>> * positive steps
>> * closed intervals
>> 
>> -- E
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> -- 
> Dave
> 
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Howard Lovatt via swift-evolution
I like the idea that Array gains `strinding(by:)` but would also like Range
to be like an array, same interface, and hence also gain `strinding(by:)`,
hence:

calendar[(startDate ..< endDate).striding(by: .Day)]


  -- Howard.

On 7 April 2016 at 10:53, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Wed Apr 06 2016, Brent Royal-Gordon  wrote:
>
> >> I (am familiar with and) agree with Dijkstra's logic, but not with your
> >> conclusion about it.  The fact that one representation is more natural
> >> for most common computing tasks doesn't mean it's not worth supporting
> >> the other representations.
> >
> > I'm not saying that Dijkstra proves that we don't need any other range
> > operators. Rather, I'm saying that he demonstrates why supporting
> > `..<` but not `<..` is not arbitrary or capricious. Dijkstra's
> > argument *permits* us to privilege `..<` as uniquely important, but
> > doesn't *force* us to do so.
>
> I agree.  And I still think it's uniquely important ;-).
>
> > To another person just now, you said:
> >
> >> He was talking about ranges of integer indices, though, and even
> >> more-specifically about how to address arrays.  Range is a more
> >> general concept that applies to much more than indices.  Once you
> >> involve floating point (and rationals, and patterns for matching,
> >> e.g. UnicodeScalar("a")..."z"), the conclusions no longer apply.
> >
> > I actually think he was talking a little more broadly than
> > that—essentially, he was discussing ordered, discrete types. In
> > principle, the same argument applies to UnicodeScalars,
>
> Yes, but I don't know if he had such types.
>
> > but not to floating-point numbers (unless you use treat floats as a
> > discrete type using `nextafter` as the `successor()` operation, which
> > is coherent but not very useful in practice). Having said that, I *do*
> > think that `...` is in practice quite useful for many types. I'm less
> > certain that `<..` or `<.<` are.
> >
> > * * *
> >
> > By the way, another reason to have `stride` as a free function is that
> > I think some types need a "strider", an instance which performs the
> > striding.
> >
> > That was the conclusion I came to when I started experimenting with
> > striding over NSDates a week or two ago. The best design I could come
> > up with looked like this:
> >
> >   calendar.using(.Day).stride(from: startDate, to: endDate, by: 1)
>
> > The `start` and `end` parameters could be grouped together into a
> > single parameter to match `stride(over:by:)`, but you can't put the
> > calendar or the unit into the stride—without them, there is no
> > coherent way to calculate the distance between two dates.
> >
> > So if some types need a strider, and will need to have the method
> > structured as `strider.stride(something:by:)`, it seems like the free
> > function version for types which *don't* need a strider ought to be
> > `stride(something:by:)`. The `something.striding(by:)` design can't be
> > easily adapted to this situation.
>
>   calendar[startDate..
> ?
>
> --
> Dave
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Brent Royal-Gordon  wrote:

>> I (am familiar with and) agree with Dijkstra's logic, but not with your
>> conclusion about it.  The fact that one representation is more natural
>> for most common computing tasks doesn't mean it's not worth supporting
>> the other representations.
>
> I'm not saying that Dijkstra proves that we don't need any other range
> operators. Rather, I'm saying that he demonstrates why supporting
> `..<` but not `<..` is not arbitrary or capricious. Dijkstra's
> argument *permits* us to privilege `..<` as uniquely important, but
> doesn't *force* us to do so.

I agree.  And I still think it's uniquely important ;-).

> To another person just now, you said:
>
>> He was talking about ranges of integer indices, though, and even
>> more-specifically about how to address arrays.  Range is a more
>> general concept that applies to much more than indices.  Once you
>> involve floating point (and rationals, and patterns for matching,
>> e.g. UnicodeScalar("a")..."z"), the conclusions no longer apply.
>
> I actually think he was talking a little more broadly than
> that—essentially, he was discussing ordered, discrete types. In
> principle, the same argument applies to UnicodeScalars, 

Yes, but I don't know if he had such types.

> but not to floating-point numbers (unless you use treat floats as a
> discrete type using `nextafter` as the `successor()` operation, which
> is coherent but not very useful in practice). Having said that, I *do*
> think that `...` is in practice quite useful for many types. I'm less
> certain that `<..` or `<.<` are.
>
> * * *
>
> By the way, another reason to have `stride` as a free function is that
> I think some types need a "strider", an instance which performs the
> striding.
>
> That was the conclusion I came to when I started experimenting with
> striding over NSDates a week or two ago. The best design I could come
> up with looked like this:
>
>   calendar.using(.Day).stride(from: startDate, to: endDate, by: 1)

> The `start` and `end` parameters could be grouped together into a
> single parameter to match `stride(over:by:)`, but you can't put the
> calendar or the unit into the stride—without them, there is no
> coherent way to calculate the distance between two dates.
>
> So if some types need a strider, and will need to have the method
> structured as `strider.stride(something:by:)`, it seems like the free
> function version for types which *don't* need a strider ought to be
> `stride(something:by:)`. The `something.striding(by:)` design can't be
> easily adapted to this situation.

  calendar[startDate..https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Brent Royal-Gordon via swift-evolution
> I (am familiar with and) agree with Dijkstra's logic, but not with your
> conclusion about it.  The fact that one representation is more natural
> for most common computing tasks doesn't mean it's not worth supporting
> the other representations.

I'm not saying that Dijkstra proves that we don't need any other range 
operators. Rather, I'm saying that he demonstrates why supporting `..<` but not 
`<..` is not arbitrary or capricious. Dijkstra's argument *permits* us to 
privilege `..<` as uniquely important, but doesn't *force* us to do so.

To another person just now, you said:

> He was talking about ranges of integer indices, though, and even
> more-specifically about how to address arrays.  Range is a more
> general concept that applies to much more than indices.  Once you
> involve floating point (and rationals, and patterns for matching,
> e.g. UnicodeScalar("a")..."z"), the conclusions no longer apply.

I actually think he was talking a little more broadly than that—essentially, he 
was discussing ordered, discrete types. In principle, the same argument applies 
to UnicodeScalars, but not to floating-point numbers (unless you use treat 
floats as a discrete type using `nextafter` as the `successor()` operation, 
which is coherent but not very useful in practice). Having said that, I *do* 
think that `...` is in practice quite useful for many types. I'm less certain 
that `<..` or `<.<` are.

* * *

By the way, another reason to have `stride` as a free function is that I think 
some types need a "strider", an instance which performs the striding.

That was the conclusion I came to when I started experimenting with striding 
over NSDates a week or two ago. The best design I could come up with looked 
like this:

calendar.using(.Day).stride(from: startDate, to: endDate, by: 1)

The `start` and `end` parameters could be grouped together into a single 
parameter to match `stride(over:by:)`, but you can't put the calendar or the 
unit into the stride—without them, there is no coherent way to calculate the 
distance between two dates.

So if some types need a strider, and will need to have the method structured as 
`strider.stride(something:by:)`, it seems like the free function version for 
types which *don't* need a strider ought to be `stride(something:by:)`. The 
`something.striding(by:)` design can't be easily adapted to this situation.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Howard Lovatt  wrote:

> Dijkstra specifically said that in Mesa it was a bad idea to include anything
> other than `..<` the relevent quote is:
>
> "Extensive experience with Mesa has shown that the use of the other three
> conventions has been a constant source of clumsiness and mistakes, and on
> account of that experience Mesa programmers are now strongly advised not to 
> use
> the latter three available features. I mention this experimental evidence —for
> what it is worth— because some people feel uncomfortable with conclusions that
> have not been confirmed in practice."
>
> In the above quote the first convention is `..<` and the other three are 
> `<..`,
> `...`, and `<.<` respectively. Therefore he is suggesting that even `...` 
> should
> not be included.

He was talking about ranges of integer indices, though, and even
more-specifically about how to address arrays.  Range is a more
general concept that applies to much more than indices.  Once you
involve floating point (and rationals, and patterns for matching,
e.g. UnicodeScalar("a")..."z"), the conclusions no longer apply.


> Personally I would go against Dijksra's advice and include all 4 as operators,
> however if Dijkstra is followed and only `..<` remains then the 'lesser' cases
> could be covered with an init on Range:
>
> init Range(first: T, isFirstIncluded: Bool = true, last: T, isLastIncluded: 
> Bool
> = true, stride: Int = 1)
>
> On Thursday, 7 April 2016, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed Apr 06 2016, Brent Royal-Gordon  wrote:
>
> >> From a purely numerically aesthetic point of view, I'd much prefer 
> ranges
> to be
> >> openable and closable at both ends.
> >>
> >> My primary use-case has been teaching math using playgrounds but I'm 
> sure
> >> there are lots of other real-world situations more specific to common
> numerical
> >> method tasks.
> >
> > By coincidence, a Perl hacker I know commented on Twitter yesterday
> > that he thought 1-based arrays were the way to go in the 21st
> > century. Somebody replying to that suggestion linked to a note by
> > Dijkstra that's relevant to this conversation:
> > 
> >
> > I'd suggest everyone in this discussion should read it—it's only about 
> 700
> words—but to summarize:
> >
> > 1. The semantic Swift refers to as `..<` is the most natural range
> convention.
> > 2. Relatedly, zero-based indexing is the most natural indexing 
> convention.
> >
> > If we agree with Dijkstra's logic, then the only reason to support
> > `>..` is for ranges where start > end—that is, when we're constructing
> > a reversed range.
>
> I (am familiar with and) agree with Dijkstra's logic, but not with your
> conclusion about it. The fact that one representation is more natural
> for most common computing tasks doesn't mean it's not worth supporting
> the other representations.
>
> > But if we decide to support striding backwards by using a forward
> > range and a negative stride, then that covers the reverse use
> > case. Thus, we would need neither additional range operators, nor
> > reversed ranges.
> >
> > As for the `range.striding(by:)` vs `stride(over:by:)` question, my
> > concerns there are, to be honest, mainly aesthetic. The need for
> > parentheses around the range operator is more or less unavoidable, but
> > I think they make the construct very ugly. However, I also think that
> > the `stride(over:by:)` syntax (or, for that matter
> > `stride(from:to:by:)`) look more constructor-y (they are only *not*
> > constructors now because of the overloading), and I think it opens us
> > up to parallel constructs like the `induce(from:while:by:)` function
> > I've been working on.
>
> --
> Dave
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Howard Lovatt via swift-evolution
Dijkstra specifically said that in Mesa it was a bad idea to include
anything other than `..<` the relevent quote is:

"Extensive experience with Mesa has shown that the use of the other three
conventions has been a constant source of clumsiness and mistakes, and on
account of that experience Mesa programmers are now strongly advised not to
use the latter three available features. I mention this experimental
evidence —for what it is worth— because some people feel uncomfortable with
conclusions that have not been confirmed in practice."

In the above quote the first convention is `..<` and the other three are
`<..`, `...`, and `<.<` respectively. Therefore he is suggesting that even
`...` should not be included.

Personally I would go against Dijksra's advice and include all 4 as
operators, however if Dijkstra is followed and only `..<` remains then the
'lesser' cases could be covered with an init on Range:

init Range(first: T, isFirstIncluded: Bool =
true, last: T, isLastIncluded: Bool = true, stride: Int = 1)

On Thursday, 7 April 2016, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Wed Apr 06 2016, Brent Royal-Gordon  > wrote:
>
> >> From a purely numerically aesthetic point of view, I'd much prefer
> ranges to be
> >> openable and closable at both ends.
> >>
> >> My primary use-case has been teaching math using playgrounds but I'm
> sure
> >> there are lots of other real-world situations more specific to common
> numerical
> >> method tasks.
> >
> > By coincidence, a Perl hacker I know commented on Twitter yesterday
> > that he thought 1-based arrays were the way to go in the 21st
> > century. Somebody replying to that suggestion linked to a note by
> > Dijkstra that's relevant to this conversation:
> > 
> >
> > I'd suggest everyone in this discussion should read it—it's only about
> 700 words—but to summarize:
> >
> >   1. The semantic Swift refers to as `..<` is the most natural range
> convention.
> >   2. Relatedly, zero-based indexing is the most natural indexing
> convention.
> >
> > If we agree with Dijkstra's logic, then the only reason to support
> > `>..` is for ranges where start > end—that is, when we're constructing
> > a reversed range.
>
> I (am familiar with and) agree with Dijkstra's logic, but not with your
> conclusion about it.  The fact that one representation is more natural
> for most common computing tasks doesn't mean it's not worth supporting
> the other representations.
>
> > But if we decide to support striding backwards by using a forward
> > range and a negative stride, then that covers the reverse use
> > case. Thus, we would need neither additional range operators, nor
> > reversed ranges.
> >
> > As for the `range.striding(by:)` vs `stride(over:by:)` question, my
> > concerns there are, to be honest, mainly aesthetic. The need for
> > parentheses around the range operator is more or less unavoidable, but
> > I think they make the construct very ugly. However, I also think that
> > the `stride(over:by:)` syntax (or, for that matter
> > `stride(from:to:by:)`) look more constructor-y (they are only *not*
> > constructors now because of the overloading), and I think it opens us
> > up to parallel constructs like the `induce(from:while:by:)` function
> > I've been working on.
>
> --
> Dave
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Brent Royal-Gordon  wrote:

>> From a purely numerically aesthetic point of view, I'd much prefer ranges to 
>> be 
>> openable and closable at both ends. 
>> 
>> My primary use-case has been teaching math using playgrounds but I'm sure 
>> there are lots of other real-world situations more specific to common 
>> numerical
>> method tasks.
>
> By coincidence, a Perl hacker I know commented on Twitter yesterday
> that he thought 1-based arrays were the way to go in the 21st
> century. Somebody replying to that suggestion linked to a note by
> Dijkstra that's relevant to this conversation:
> 
>
> I'd suggest everyone in this discussion should read it—it's only about 700 
> words—but to summarize:
>
>   1. The semantic Swift refers to as `..<` is the most natural range 
> convention.
>   2. Relatedly, zero-based indexing is the most natural indexing 
> convention.
>
> If we agree with Dijkstra's logic, then the only reason to support
> `>..` is for ranges where start > end—that is, when we're constructing
> a reversed range. 

I (am familiar with and) agree with Dijkstra's logic, but not with your
conclusion about it.  The fact that one representation is more natural
for most common computing tasks doesn't mean it's not worth supporting
the other representations.

> But if we decide to support striding backwards by using a forward
> range and a negative stride, then that covers the reverse use
> case. Thus, we would need neither additional range operators, nor
> reversed ranges.
>
> As for the `range.striding(by:)` vs `stride(over:by:)` question, my
> concerns there are, to be honest, mainly aesthetic. The need for
> parentheses around the range operator is more or less unavoidable, but
> I think they make the construct very ugly. However, I also think that
> the `stride(over:by:)` syntax (or, for that matter
> `stride(from:to:by:)`) look more constructor-y (they are only *not*
> constructors now because of the overloading), and I think it opens us
> up to parallel constructs like the `induce(from:while:by:)` function
> I've been working on.

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Ted F.A. van Gaalen via swift-evolution
Hi Milos

Yes,  (v1…v2).by(v3)  it can determine the going of either in  + or - direction,
but only at run time! because the contents of v1, v2, v3 are of course unknown 
at compile time. 
Ergo: it cannot expected be an absolute value.

however, I suggested (coded) that here on 4.3.2016…  Works in Playground Xcode 
7.3
look in the struct its “init”   where the direction is determined
by wether “from” or “to” is bigger” 
implemented like this  (and also with a floating point number tolerance)
(The struct should be numerical generic, but I didn’t manage to change it to 
generic,) 
Anyway, should be compilerized/hand coded in asm perhaps (I can’t do that)

TedvG

public struct StriderGenerator : GeneratorType
{
private let low: Double
private let high: Double
private var step : Double
private var tol  : Double

private var iterator  = 0

private let moveForward: Bool

private var done  = false


public init(from: Double, to: Double, by: Double, tolerance: Double)
{
step = by
if from < to
{
low  = from
high = to
moveForward = true
}
else
{
low  = to
high = from
moveForward = false
}
self.tol   = tolerance * 0.5  // center it.
}

/// return next value or nil, if no next
/// element exists.

public mutating func next() -> Double?
{
let current:Double
if done
{
return nil
}

if moveForward
{
current = low + Double(iterator) * step
}
else
{
current = high - Double(iterator) * step
}
iterator += 1


// done if exceeding low or high limits + tolerance

done = current > high   + tol  ||
   current < low- tol

if done
{
return nil
}
else
{
return current
}
}
}

public struct Strider : SequenceType   // Aragorn
{
private let start:  Double
private let end:Double
private let step:   Double
private let tol:Double

init(from: Double, to: Double, by: Double, tolerance : Double)
{
_precondition(by > 0.0 ,
"Init of struct Strider: 'by:...' value must be > 0.0.")
_precondition(abs(by) > tolerance,
"Init of struct Strider: 'by:...' value must be > tolerance.")
_precondition(tolerance >= 0.0,
"Init of struct Strider: tolerance:... value must be >= 0.0")

start = from
end   = to;
step  = by
tol   = tolerance
}

/// Return a *generator* over the elements of this *sequence*.

public func generate() -> StriderGenerator
{
return StriderGenerator(from: start, to: end, by: step, tolerance:  tol)
}
}

public extension Double
{

public func strider(to to: Double, by: Double, tolerance: Double ) -> 
Strider
{
return Strider( from: self, to: to, by: by, tolerance: tolerance)
}
}

print("Testing the new .strider extension")

let testvalues =
[
// fr: to: by:   tolerance:
[ 0.0, 5.0,1.0,0.0 ],
[-3.0, 4.0,0.12,   0.1 ],
[ 2.0,-1.0,0.34,   0.1  ],
[ 0.001,  -0.002,  0.0001, 0.1 ]
]

for parm in testvalues
{

print("==Stride from: \(parm[0]) to: \(parm[1]) by: \(parm[2]) 
tolerance: \(parm[3])\n")

for val in parm[0].strider(to: parm[1], by: parm[2], tolerance: parm[3])
{
print("\(val) ", terminator:"")
}
print("\n\n")
}




TedvG



> On 06.04.2016, at 23:15, Milos Rankovic  wrote:
> 
> Hi Ted,
> 
>> that would imply the ‘by”value should/must always be an absolute value?
> 
> 
> In a way: Instead of `Strideable.Stride` I would suggest 
> `Strideable.Distance`.
> 
> At any rate, leaving the sign to be direction indicator makes it forever 
> necessary for everyone to make this counterintuitive metal gymnastics, since 
> most of the time in life we do not walk backwards, even when we are returning 
> back whence we came from!
> 
> What do you think?
> 
> milos
> 
> 
>> On 6 Apr 2016, at 21:34, Ted F.A. van Gaalen > > wrote:
>> 
>> Hello Milos,
>> Good question
>> was thinking about this too.
>> that would imply the ‘by”value should/must always be an absolute value?
>> however (if it is a var) it cannot be guaranteed to be + or - 
>> that’s why I thought to leave it as is.
>> ?
>> TedvG
>> 
>>> On 06.04.2016, at 22:18, Milos Rankovic >> > wrote:
>>> 
>>> 
 On 6 Apr 2016, at 21:08, Ted F.A. van Gaalen via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 v1 >  v2:   is allowed and correctly evaluated.  e.g. 
 (8.0…-3.14159).by(-0.0001) 
>>> 
>>> If the range does not assume `st

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Erica Sadun  wrote:

> On Apr 6, 2016, at 3:05 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed Apr 06 2016, Xiaodi Wu  wrote:
>
> On Wed, Apr 6, 2016 at 3:28 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> You if you need to represent `<..` intervals in scientific computing,
> that's a pretty compelling argument for supporting them.
>
> I'd like to be able to represent any of those as
> Intervals-which-are-now-Ranges. It makes sense to do so 
> because
> the
> things I want to do with them, such as clamping and testing if
> some
> value is contained, are exactly what Intervals-now-Ranges
> provide.
> Looking around, it seems many other languages provide only 
> what
> Swift
> currently does, but Perl does provide `..`, `..^`, `^..`, and
> `^..^`
> (which, brought over to Swift, would be `...`, `..<`, `<..`, 
> and
> `<.<`).
>
> Do we need fully-open ranges too?
>
> I haven't encountered a need for open ranges, but I would expect that
> other applications in scientific computing could make use of them.
> I rather like Pyry's suggestions below. 
>
> Below?
>
> Logically in time below.

Oh! In my application, time flows downward.

>
> I believe the following is a valid conversion of the Xiaodi Wu below into the
> Dave A domain.
>
> On Apr 6, 2016, at 2:29 PM, Pyry Jahkola via swift-evolution
>  wrote:
>
> I think a sensible specification would be that with a positive step size,
> the count starts from the lower bound, and with a negative one, it starts
> from the upper bound (inclusive or exclusive). Thus, the following 
> examples
> should cover all the corner cases:
>
> (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]

These all look reasonable to me.

> Lastly, if you want the positive stride reversed, you'd do just that:
>
> (0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]

Also reasonable.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Brent Royal-Gordon via swift-evolution
> From a purely numerically aesthetic point of view, I'd much prefer ranges to 
> be 
> openable and closable at both ends. 
> 
> My primary use-case has been teaching math using playgrounds but I'm sure 
> there are lots of other real-world situations more specific to common 
> numerical
> method tasks.

By coincidence, a Perl hacker I know commented on Twitter yesterday that he 
thought 1-based arrays were the way to go in the 21st century. Somebody 
replying to that suggestion linked to a note by Dijkstra that's relevant to 
this conversation: 


I'd suggest everyone in this discussion should read it—it's only about 700 
words—but to summarize:

1. The semantic Swift refers to as `..<` is the most natural range 
convention.
2. Relatedly, zero-based indexing is the most natural indexing 
convention.

If we agree with Dijkstra's logic, then the only reason to support `>..` is for 
ranges where start > end—that is, when we're constructing a reversed range. But 
if we decide to support striding backwards by using a forward range and a 
negative stride, then that covers the reverse use case. Thus, we would need 
neither additional range operators, nor reversed ranges.

As for the `range.striding(by:)` vs `stride(over:by:)` question, my concerns 
there are, to be honest, mainly aesthetic. The need for parentheses around the 
range operator is more or less unavoidable, but I think they make the construct 
very ugly. However, I also think that the `stride(over:by:)` syntax (or, for 
that matter `stride(from:to:by:)`) look more constructor-y (they are only *not* 
constructors now because of the overloading), and I think it opens us up to 
parallel constructs like the `induce(from:while:by:)` function I've been 
working on.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Erica Sadun  wrote:

> On Apr 6, 2016, at 3:25 PM, Dave Abrahams  wrote:
>
> These all look reasonable to me.
>
> Lastly, if you want the positive stride reversed, you'd do just that:
>
> (0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]
>
> Also reasonable.
>
> -- 
> Dave
>
> Unless there's a compelling reason to fight here, it looks like the
> opinion against where I'm standing is pretty overwhelming at least in
> this subgroup. To simplify things going forward (and to avoid compiler
> warnings, which as Dave A points out is probably an indication of bad
> design more than bad users), I'm willing to adopt in as well.

Thanks.  In that case, I suggest that we entertain two separate
proposals:

1. add the .striding(by: n) method.
2. add the other range operators.

Though they both have obvious benefits, I expect #1 is a much easier
sell than #2, which is one good reason to separate them.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 3:25 PM, Dave Abrahams  wrote:
> 
> These all look reasonable to me.
> 
>>Lastly, if you want the positive stride reversed, you'd do just that:
>> 
>>(0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]
> 
> Also reasonable.
> 
> -- 
> Dave

Unless there's a compelling reason to fight here, it looks like the opinion 
against
where I'm standing is pretty overwhelming at least in this subgroup. To simplify
things going forward (and to avoid compiler warnings, which as Dave A points out
is probably an indication of bad design more than bad users), I'm willing to 
adopt
in as well.

-- E

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Stephen Canon via swift-evolution

> On Apr 6, 2016, at 2:25 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Wed Apr 06 2016, Erica Sadun  wrote:
> 
>>On Apr 6, 2016, at 3:05 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed Apr 06 2016, Xiaodi Wu  wrote:
>> 
>>On Wed, Apr 6, 2016 at 3:28 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>You if you need to represent `<..` intervals in scientific computing,
>>that's a pretty compelling argument for supporting them.
>> 
>>I'd like to be able to represent any of those as
>>Intervals-which-are-now-Ranges. It makes sense to do so 
>> because
>>the
>>things I want to do with them, such as clamping and testing if
>>some
>>value is contained, are exactly what Intervals-now-Ranges
>>provide.
>>Looking around, it seems many other languages provide only 
>> what
>>Swift
>>currently does, but Perl does provide `..`, `..^`, `^..`, and
>>`^..^`
>>(which, brought over to Swift, would be `...`, `..<`, `<..`, 
>> and
>>`<.<`).
>> 
>>Do we need fully-open ranges too?
>> 
>>I haven't encountered a need for open ranges, but I would expect that
>>other applications in scientific computing could make use of them.
>>I rather like Pyry's suggestions below. 
>> 
>>Below?
>> 
>> Logically in time below.
> 
> Oh! In my application, time flows downward.
> 
>> 
>> I believe the following is a valid conversion of the Xiaodi Wu below into the
>> Dave A domain.
>> 
>>On Apr 6, 2016, at 2:29 PM, Pyry Jahkola via swift-evolution
>> wrote:
>> 
>>I think a sensible specification would be that with a positive step size,
>>the count starts from the lower bound, and with a negative one, it starts
>>from the upper bound (inclusive or exclusive). Thus, the following 
>> examples
>>should cover all the corner cases:
>> 
>>(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]
> 
> These all look reasonable to me.

Agreed.

– Steve

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Milos Rankovic via swift-evolution
Hi Ted,

> that would imply the ‘by”value should/must always be an absolute value?


In a way: Instead of `Strideable.Stride` I would suggest `Strideable.Distance`.

At any rate, leaving the sign to be direction indicator makes it forever 
necessary for everyone to make this counterintuitive metal gymnastics, since 
most of the time in life we do not walk backwards, even when we are returning 
back whence we came from!

What do you think?

milos


> On 6 Apr 2016, at 21:34, Ted F.A. van Gaalen  wrote:
> 
> Hello Milos,
> Good question
> was thinking about this too.
> that would imply the ‘by”value should/must always be an absolute value?
> however (if it is a var) it cannot be guaranteed to be + or - 
> that’s why I thought to leave it as is.
> ?
> TedvG
> 
>> On 06.04.2016, at 22:18, Milos Rankovic > > wrote:
>> 
>> 
>>> On 6 Apr 2016, at 21:08, Ted F.A. van Gaalen via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> v1 >  v2:   is allowed and correctly evaluated.  e.g. 
>>> (8.0…-3.14159).by(-0.0001) 
>> 
>> If the range does not assume `start >= end`, is it still necessary to also 
>> indicate the traversal direction with the sign of the step (`-0.0001`)?
>> 
>> milos
> 

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Xiaodi Wu via swift-evolution
On Wed, Apr 6, 2016 at 4:05 PM, Dave Abrahams  wrote:
>
> on Wed Apr 06 2016, Xiaodi Wu  wrote:
>
>> On Wed, Apr 6, 2016 at 3:28 PM, Dave Abrahams via swift-evolution
>>  wrote:
>>> You if you need to represent `<..` intervals in scientific computing,
>>> that's a pretty compelling argument for supporting them.
>>>
 I'd like to be able to represent any of those as
 Intervals-which-are-now-Ranges. It makes sense to do so because the
 things I want to do with them, such as clamping and testing if some
 value is contained, are exactly what Intervals-now-Ranges provide.
 Looking around, it seems many other languages provide only what Swift
 currently does, but Perl does provide `..`, `..^`, `^..`, and `^..^`
 (which, brought over to Swift, would be `...`, `..<`, `<..`, and
 `<.<`).
>>>
>>> Do we need fully-open ranges too?
>>
>> I haven't encountered a need for open ranges, but I would expect that
>> other applications in scientific computing could make use of them.
>> I rather like Pyry's suggestions below.
>
> Below?

Sorry, chronologically, above; in terms of relative positions in the
thread, I think, below, since Pyry's suggests followed on from the
time I started writing. Ha, and Erica (above/below) just filled in
what I meant to say.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Erica Sadun  wrote:

> On Apr 6, 2016, at 2:17 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> Guidance:
>
> When using odd integer literals to produce an even number sequence,
> prefer the `...` operator to the `..<` operator and change your ending
> literal to an even number.
>
> I don't think you can fix counterintuitive behavior with guidance. 
>
> (1..<199).striding(by: -2) is the first way I'd reach for to express
> 197, 195, ..., 3, 1
>
> Yes, but you can with warnings and fixits. 
>
> * The compiler should issue a warning for any use of 
>
> (n..
> with a fixit of "replace (n.. whether n or m is known at compile time 
>
> * If v cannot be known at compile time, I think the compiler should
> always prefer ... to ..<.
>
> * The compiler should not allow
>
> (n..
> where v is known at compile time to be a negative constant. There should 
> also be a runtime precondition that raises a fatal error should a negative 
> v be used with a half-open interval.

You can lessen the impact of any design choice by adding warnings and
fixits, but I'm pretty sure it's better to make a choice that doesn't
require them.

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 3:05 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Wed Apr 06 2016, Xiaodi Wu  > wrote:
> 
>> On Wed, Apr 6, 2016 at 3:28 PM, Dave Abrahams via swift-evolution
>>  wrote:
>>> You if you need to represent `<..` intervals in scientific computing,
>>> that's a pretty compelling argument for supporting them.
>>> 
 I'd like to be able to represent any of those as
 Intervals-which-are-now-Ranges. It makes sense to do so because the
 things I want to do with them, such as clamping and testing if some
 value is contained, are exactly what Intervals-now-Ranges provide.
 Looking around, it seems many other languages provide only what Swift
 currently does, but Perl does provide `..`, `..^`, `^..`, and `^..^`
 (which, brought over to Swift, would be `...`, `..<`, `<..`, and
 `<.<`).
>>> 
>>> Do we need fully-open ranges too?
>> 
>> I haven't encountered a need for open ranges, but I would expect that
>> other applications in scientific computing could make use of them.
>> I rather like Pyry's suggestions below. 
> 
> Below?

Logically in time below.

I believe the following is a valid conversion of the Xiaodi Wu below into the 
Dave A domain.

> On Apr 6, 2016, at 2:29 PM, Pyry Jahkola via swift-evolution 
>  wrote:
> 
> I think a sensible specification would be that with a positive step size, the 
> count starts from the lower bound, and with a negative one, it starts from 
> the upper bound (inclusive or exclusive). Thus, the following examples should 
> cover all the corner cases:
> 
> (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]
> 
> Lastly, if you want the positive stride reversed, you'd do just that:
> 
> (0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]
> 
> — Pyry

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Xiaodi Wu  wrote:

> On Wed, Apr 6, 2016 at 3:28 PM, Dave Abrahams via swift-evolution
>  wrote:
>> You if you need to represent `<..` intervals in scientific computing,
>> that's a pretty compelling argument for supporting them.
>>
>>> I'd like to be able to represent any of those as
>>> Intervals-which-are-now-Ranges. It makes sense to do so because the
>>> things I want to do with them, such as clamping and testing if some
>>> value is contained, are exactly what Intervals-now-Ranges provide.
>>> Looking around, it seems many other languages provide only what Swift
>>> currently does, but Perl does provide `..`, `..^`, `^..`, and `^..^`
>>> (which, brought over to Swift, would be `...`, `..<`, `<..`, and
>>> `<.<`).
>>
>> Do we need fully-open ranges too?
>
> I haven't encountered a need for open ranges, but I would expect that
> other applications in scientific computing could make use of them.
> I rather like Pyry's suggestions below. 

Below?

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Xiaodi Wu via swift-evolution
On Wed, Apr 6, 2016 at 3:28 PM, Dave Abrahams via swift-evolution
 wrote:
> You if you need to represent `<..` intervals in scientific computing,
> that's a pretty compelling argument for supporting them.
>
>> I'd like to be able to represent any of those as
>> Intervals-which-are-now-Ranges. It makes sense to do so because the
>> things I want to do with them, such as clamping and testing if some
>> value is contained, are exactly what Intervals-now-Ranges provide.
>> Looking around, it seems many other languages provide only what Swift
>> currently does, but Perl does provide `..`, `..^`, `^..`, and `^..^`
>> (which, brought over to Swift, would be `...`, `..<`, `<..`, and
>> `<.<`).
>
> Do we need fully-open ranges too?

I haven't encountered a need for open ranges, but I would expect that
other applications in scientific computing could make use of them.
I rather like Pyry's suggestions below. These would represent an
expansive fleshing out of ranges. They really start pulling their
weight for floating point bounds; of course, I'd wager that ... and
..< would still be the most used by far.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Erica Sadun  wrote:

>> On Apr 6, 2016, at 2:17 PM, Xiaodi Wu  wrote:
>> Prohibiting StrideTo with floating-point ranges altogether would be
>> distressing. IMO, it's plenty distressing that backwards
>> floating-point StrideTo as it currently exists might go away.
>
> I wouldn't suggest doing so. I'm just saying that for a half-open interval, 
> there is no max value
> so it makes no sense mathematically to have a first value and a
> negative step. 

I don't agree.  It seems to me that striding downwards over a half-open
range r should always begin with r.upperBound - s (modulo any necessary
adjustments to avoid FP error), where -s is the stride amount.  Why is
that mathematical nonsense?

Another point to consider: striding is also a sensible operation over
collections, and some ranges are collections.  The stride semantics must
coincide in those cases.  I expect that constraint narrows down the
reasonable semantic choices considerably.

> You're not so restricted with:
>
> * positive steps
> * closed intervals
>
> -- E
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Ted F.A. van Gaalen via swift-evolution
G Typos… Sorry, here it is again: vital  correctionslook at<< 
<

Hi Erica, Dave

Based on what I’ve (not all) read under this topic: 

I’d suggest a more complete approach:

Ranges should support:  (as yet not implemented) 

- All numerical data types (Double, Float, Int, Money***, Decimal*** ) 
- An arbitrary increment or decrement value.
- Working in the complete  - + numerical range
- Allow traversing in both   - + directions.



The basics:

(v1…v2).by(v3) // this still is readable. and can be optimized by the 
compiler (predictable sequence)

Rules:

v1, v2, v3  are any numerical type scalar type  
v1, v2, v3  must have the same numerical type.
v1 >  v2:   is allowed and correctly evaluated.  e.g. 
(8.0…-3.14159).by(-0.0001) 


The  ..<  half open operator is no longer allowed.   write e.g.   
0...ar.count - 1

"by(…)”  is obligatory with floating point range.

   the default “by(…)” value of 1 makes sense only with integer ranges.


valid examples:
(5…9)// 5 6 7 8 9 Integer range without “by” 
defaults to 1 as increment value.
(1...10).by(2) // 1 3 5 7 9.
(2...10).by(2) // 2 4 6 8 10.
(4…-4).by(-2) // 4  2 0 -2 -4 .// runs backwards
  <<<
(30..-10).by(-2)// 30 28 26 24 22 ….. -10.
(10...0).by(-3)  // 10 7 4 1. 

(12…-10) // is valid, but returns empty because default 
increment value = 1

(12.0…-12.0).by(-1.5)   // 12.0  10.5  9.0….  // of course with 
float imprecision
   
   

   invalid examples:

   (23.0..<60.5).by(0.5) // half open ranges are no  longer allowed ** 
  (23.0…60.5) // “ by"  is obligatory with floats.
  (14...8).by(0.5)//  v1 v2 and v3 don’t have the same 
numerical type 


Half open ranges make no real sense (are not really useful) with floating point 
values.
and no sense at all with e.g (12..<-1)  afaics 


At least for float iterations the increment value should not each time be 
accumulated like
v1 += v3;  v1 += v3;  v1 += v3;  ….   // causes float 
number drift.
but be freshly multiplied with each iteration, e.g. by using an internal 
iteration counter
like so:

v = v1 + v3 * i++; v = v1 + v3 * i++;  v = v1 + v3 * i++;  v = v1 + v3 
* i++; <<<

for reasons of precision.

If one has worked with floating point data more often
awareness of its precision limitations become a second nature conscience. 
E.g. it is perfectly acceptable and known (also in classical for-loops) that
(0.0…1.0).by(0.1) is not guaranteed to reach the humanly expected value of 1.0.
This is normal. Due to the nature of what mostly is done in the
floating point numbers domain, this does not often cause a problem
(e.g like working with a slide ruler) 
if it is important to reach the “expected end” then one could
-add an epsilon value like so (v1…v2 + 0.1) 
-generate the desired float sequence within an integer loop.


The above “range” (imho) improvement makes the 
stride.. function/keyword completely unnecessary.

Due to its ability to process reversed ranges as is, 
the .reverse() is optional (no longer necessary in most cases,
allowing the compiler to optimize without having to process 
it like a collection.


Now that we have a fully functional range, which can do all things desired, one 
can
then of course, pass this range without any change  to a collection based for … 
 e.g.

for v in (v1…v2).by(v3)   // optionally add other collection 
operators/filters/sorts here

(or in any other construct you might see fit)
   

This seems to be a reasonable alternative for

- the classical for ;; loop
-the collection-free for-loop  
 for v from v1 to v2 by v3

As you know, the latter is what I have been suggesting, 
but seemingly does not find much support,
(because I received very little reactions) 
making it doubtful if I will ever make a proposal for this for loop.
Anyone out there should I stil do that? 

When one does not further extend the range
with filters like sort etc. the compiler can still optimize 
a collection-in-between out of the way.
(Thank you Taras, für das Mitdenken. :o)


**   note that a half open range would in most cases be unnecessary 
  if  collection indexes started with 1 instead of 0, e.g. someArray[1…10] 
 (but it’s too late to change that.) 
 “the color of the first apple?”vs
 “the color of the zeroth (0) ???  apple?”? Silly isn’t? 

*** possible future numerical “native” types 


It could be that (at least) partly something similar has already been suggested.
but so much is here of this topic that i can’t see the wood for the trees, so 
to speak.


Your (all) opinions are appreciated. 

kind regards, mit freundlic

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Shawn Erickson via swift-evolution
On Wed, Apr 6, 2016 at 1:29 PM Pyry Jahkola via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On 06 Apr 2016, at 23:17, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I don't think you can fix counterintuitive behavior with guidance.
>
> (1..<199).striding(by: -2) is the first way I'd reach for to express
> 197, 195, ..., 3, 1
>
>
> I think a sensible specification would be that with a positive step size,
> the count starts from the lower bound, and with a negative one, it starts
> from the upper bound (inclusive or exclusive). Thus, the following examples
> should cover all the corner cases:
>
> (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]
>
> Lastly, if you want the positive stride reversed, you'd do just that:
>
> (0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]
>

I have always desired for a complete set of range variants like you
outlined above. I don't have current examples warranting a complete set but
I could easily see having to work on a data set that may be best done by
having a complete set of range variants so you don't need to transform the
data set to get it to work with the language you happen to be using. It
also better supports floating point ranges which may not have easy ways to
transform the data.

I also like the suggestion of how striding and reverse should work.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 2:35 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> Yes, but you can with warnings and fixits. 
> 
> * The compiler should issue a warning for any use of 
> 
> (n.. 
> with a fixit of "replace  (n.. whether n or m is known at compile time 
> 
> * If v cannot be known at compile time, I think the compiler should
> always prefer ... to ..<.
> 
> * The compiler should not allow
> 
> (n.. 
> where v is known at compile time to be a negative constant. There should 
> also be a runtime precondition that raises a fatal error should a negative 
> v be used with a half-open interval.
> 
> -- E

Following up to myself, this can easily be expanded to the other cases just
brought up by Xiaodi Wu

-- E


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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 2:28 PM, Dave Abrahams via swift-evolution 
>  wrote:
> You if you need to represent `<..` intervals in scientific computing,
> that's a pretty compelling argument for supporting them.

>From a purely numerically aesthetic point of view, I'd much prefer ranges to 
>be 
openable and closable at both ends. 

My primary use-case has been teaching math using playgrounds but I'm sure 
there are lots of other real-world situations more specific to common numerical
method tasks.

-- E



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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 2:17 PM, Dave Abrahams via swift-evolution 
>  wrote:
>> Guidance:
>> 
>> When using odd integer literals to produce an even number sequence,
>> prefer the `...` operator to the `..<` operator and change your ending
>> literal to an even number.
> 
> I don't think you can fix counterintuitive behavior with guidance.  
> 
> (1..<199).striding(by: -2) is the first way I'd reach for to express
> 197, 195, ..., 3, 1

Yes, but you can with warnings and fixits. 

* The compiler should issue a warning for any use of 

(n..___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Ted F.A. van Gaalen via swift-evolution
Hello Milos,
Good question
was thinking about this too.
that would imply the ‘by”value should/must always be an absolute value?
however (if it is a var) it cannot be guaranteed to be + or - 
that’s why I thought to leave it as is.
?
TedvG

> On 06.04.2016, at 22:18, Milos Rankovic  wrote:
> 
> 
>> On 6 Apr 2016, at 21:08, Ted F.A. van Gaalen via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> v1 >  v2:   is allowed and correctly evaluated.  e.g. 
>> (8.0…-3.14159).by(-0.0001) 
> 
> If the range does not assume `start >= end`, is it still necessary to also 
> indicate the traversal direction with the sign of the step (`-0.0001`)?
> 
> milos

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Xiaodi Wu  wrote:

> On Wed, Apr 6, 2016 at 1:16 PM, Dave Abrahams  wrote:
>>
>> on Wed Apr 06 2016, Xiaodi Wu  wrote:
>>
>>> I think a lightbulb just went on for me:
>>>
>
>>> You're talking about expressing something in the vein of 
>>> `(0..<200).striding(by:
>>> -2)`, which has I'm sure many use cases, and which isn't straightforward to
>>> express with the current free function--I hadn't considered that.
>>>
>>> Meanwhile, I was trying to talk about something like `stride(from: 200, to: 
>>> 0,
>>> by: -2)`, which is easily expressed today but isn't straightforward at all 
>>> to
>>> preserve with only ranges. Clearly, given that this is what's on offer
>>> currently, someone who designed the language thinks (or thought) it's of 
>>> some
>>> use.
>>
>> That someone was me, and I explained that it wasn't an extremely
>> deeply-considered decision.
>
> Fair enough. Though your decision may not have been deeply considered,
> I wouldn't say it was an ill-considered one given that there wasn't
> (to my knowledge) any great clamor against it subsequently.
>
>>> In the absence of information as to which is more in demand, couldn't
>>> we have both?
>>
>> That's not how we make decisions about what should be in the language or
>> standard library.  We need to make choices based on (at least educated
>> guesses about) what people need, or we'll end up with a sprawling mess.
>
> Well, to elicit the kind of feedback that would help determine user
> needs, I would suggest that (when the eventually reconsidered syntax
> is proposed) this change should be highlighted explicitly as a feature
> removal. IMO, it wouldn't be otherwise immediately apparent from a
> quick glance that revising `stride(from: 0, to: 10, by: 1)` to
> `(0..<10).striding(by: 1)` necessarily entails deletion of backwards
> strides from upper bound to-and-not-through lower bound.
>
>>> If it must be a method on a range,
>>
>> It's not that it must be, but having such a method tends to reduce API
>> surface area.  We prefer methods to free functions.
>>
>>> then I would advocate for having what seems to be an utterly
>>> reasonable set of options for striding backwards:
>>>
>>> ```
>>> (0...200).striding(by: -2) // [a, b]
>>> (0..<200).striding(by: -2) // [a, b)
>>> (0<..200).striding(by: -2) // (a, b]
>>> ```
>>
>> And I'm trying to say that without a more compelling reason to introduce
>> `<..`, I don't want to do it.  I'd like to know that `<..` is useful
>> outside the domain of striding, for example.  Use-cases, anyone?
>
> Well, my use case (an actual one) is supremely mundane. I'm doing some
> scientific computing and I need to deal with numeric intervals. Some
> of them are closed, some of them are open at one end, and some at the
> other. 

You if you need to represent `<..` intervals in scientific computing,
that's a pretty compelling argument for supporting them.

> I'd like to be able to represent any of those as
> Intervals-which-are-now-Ranges. It makes sense to do so because the
> things I want to do with them, such as clamping and testing if some
> value is contained, are exactly what Intervals-now-Ranges provide.
> Looking around, it seems many other languages provide only what Swift
> currently does, but Perl does provide `..`, `..^`, `^..`, and `^..^`
> (which, brought over to Swift, would be `...`, `..<`, `<..`, and
> `<.<`).

Do we need fully-open ranges too?

>> Reasons we might not need it: the cases where it's important are much
>> more likely to be notionally continuous domains (e.g. floats), since you
>> can always write
>>
>> ((0+1)...200).striding(by: -2)
>>
>> and if you need the floating version there's always
>>
>>(0.0...200.0).striding(by: -2).lazy.filter { $0 != 0.0 }
>>
>> which probably optimizes down to the same code.
>>
>> One question that I *do* think we should answer, is whether the elements
>> of
>>
>> (0..<199).striding(by: -2)
>>
>> are even or odd.
>>
>>> On Wed, Apr 6, 2016 at 12:10 PM Dave Abrahams via swift-evolution
>>>  wrote:
>>>
>>> on Wed Apr 06 2016, Brent Royal-Gordon  
>>> wrote:
>>>
>>> >> For example, there are all kinds of other ways to slice this:
>>> >>
>>> >> stride(over: 0..<200, by: -2)
>>> >
>>> > This seems like a particularly good solution. The way I understand it
>>> > at least, it would allow ranges to always be ordered, with the only
>>> > difference being whether it went start-to-end or end-to-start,
>>> > determined by the stride's sign.
>>>
>>> This is no different in principle from
>>>
>>> (0..<200).striding(by: -2)
>>>
>>> Again, I wasn't trying to suggest any of the solutions listed there.
>>> The point I was making was that we don't have enough information to
>>> design more than
>>>
>>> (0..<200).striding(by: -2)
>>>
>>> > It would also avoid the need for additional range operators. The main
>>> > reason you would need `>..` is so you could say
>>> > `array.endIndex>

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 2:17 PM, Xiaodi Wu  wrote:
> Prohibiting StrideTo with floating-point ranges altogether would be
> distressing. IMO, it's plenty distressing that backwards
> floating-point StrideTo as it currently exists might go away.

I wouldn't suggest doing so. I'm just saying that for a half-open interval, 
there is no max value
so it makes no sense mathematically to have a first value and a negative step. 
You're not so restricted 
with:

* positive steps
* closed intervals

-- E

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Pyry Jahkola via swift-evolution

> On 06 Apr 2016, at 23:17, Dave Abrahams via swift-evolution 
>  wrote:
> 
> I don't think you can fix counterintuitive behavior with guidance.  
> 
> (1..<199).striding(by: -2) is the first way I'd reach for to express
> 197, 195, ..., 3, 1

I think a sensible specification would be that with a positive step size, the 
count starts from the lower bound, and with a negative one, it starts from the 
upper bound (inclusive or exclusive). Thus, the following examples should cover 
all the corner cases:

(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]

Lastly, if you want the positive stride reversed, you'd do just that:

(0 ... 9).striding(by: 2).reverse() == [8, 6, 4, 2, 0]

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Milos Rankovic via swift-evolution
Apologies, I inverted the operator there! This is, of course what I meant:

> On 6 Apr 2016, at 21:08, Ted F.A. van Gaalen via swift-evolution 
>  wrote:
> 
> v1 >  v2:   is allowed and correctly evaluated.  e.g. 
> (8.0…-3.14159).by(-0.0001) 

If the range does not assume `start <= end`, is it still necessary to also 
indicate the traversal direction with the sign of the step (`-0.0001`)?

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Erica Sadun  wrote:

>> On Apr 6, 2016, at 12:43 PM, Dave Abrahams  wrote:
>> 
>> 
>> on Wed Apr 06 2016, Erica Sadun  wrote:
>> 
>
>>>On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>>(0..<199).striding(by: -2)
>>> 
>>>are even or odd.
>>> 
>>> (0..<199).striding(by: -2): 0..<199 == 0...198 Even
>>> (1..<199).striding(by: -2): 1..<199 == 1...198 Even
>> 
>> I understand the logic that got you there, but I find it incredibly
>> counter-intuitive that striding by 2s over a range with odd endpoints
>> should produce even numbers... I can't imagine any way I'd be convinced
>> that was a good idea.
>
> Guidance:
>
> When using odd integer literals to produce an even number sequence,
> prefer the `...` operator to the `..<` operator and change your ending
> literal to an even number.

I don't think you can fix counterintuitive behavior with guidance.  

(1..<199).striding(by: -2) is the first way I'd reach for to express
197, 195, ..., 3, 1

>
>
> -- E
>
>> 
>>> (0..<198).striding(by: -2): 1..<198 == 0...197 Odd
>>> (1..<198).striding(by: -2): 1..<198 == 1...197 Odd
>>> 
>>> -- E
>>> 
>> 
>> -- 
>> Dave
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Milos Rankovic via swift-evolution

> On 6 Apr 2016, at 21:08, Ted F.A. van Gaalen via swift-evolution 
>  wrote:
> 
> v1 >  v2:   is allowed and correctly evaluated.  e.g. 
> (8.0…-3.14159).by(-0.0001) 

If the range does not assume `start >= end`, is it still necessary to also 
indicate the traversal direction with the sign of the step (`-0.0001`)?

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Xiaodi Wu via swift-evolution
On Wed, Apr 6, 2016 at 1:43 PM, Dave Abrahams  wrote:
>
> on Wed Apr 06 2016, Erica Sadun  wrote:
>
>> On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution
>>  wrote:
>> (0..<199).striding(by: -2)
>>
>> are even or odd.
>>
>> (0..<199).striding(by: -2): 0..<199 == 0...198 Even
>> (1..<199).striding(by: -2): 1..<199 == 1...198 Even
>
> I understand the logic that got you there, but I find it incredibly
> counter-intuitive that striding by 2s over a range with odd endpoints
> should produce even numbers... I can't imagine any way I'd be convinced
> that was a good idea.
>
>> (0..<198).striding(by: -2): 1..<198 == 0...197 Odd
>> (1..<198).striding(by: -2): 1..<198 == 1...197 Odd
>>

One other aspect of the counterintuitiveness is that
`(a..https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Xiaodi Wu via swift-evolution
On Wed, Apr 6, 2016 at 1:16 PM, Dave Abrahams  wrote:
>
> on Wed Apr 06 2016, Xiaodi Wu  wrote:
>
>> I think a lightbulb just went on for me:
>>
>> You're talking about expressing something in the vein of 
>> `(0..<200).striding(by:
>> -2)`, which has I'm sure many use cases, and which isn't straightforward to
>> express with the current free function--I hadn't considered that.
>>
>> Meanwhile, I was trying to talk about something like `stride(from: 200, to: 
>> 0,
>> by: -2)`, which is easily expressed today but isn't straightforward at all to
>> preserve with only ranges. Clearly, given that this is what's on offer
>> currently, someone who designed the language thinks (or thought) it's of some
>> use.
>
> That someone was me, and I explained that it wasn't an extremely
> deeply-considered decision.

Fair enough. Though your decision may not have been deeply considered,
I wouldn't say it was an ill-considered one given that there wasn't
(to my knowledge) any great clamor against it subsequently.


>> In the absence of information as to which is more in demand, couldn't
>> we have both?
>
> That's not how we make decisions about what should be in the language or
> standard library.  We need to make choices based on (at least educated
> guesses about) what people need, or we'll end up with a sprawling mess.

Well, to elicit the kind of feedback that would help determine user
needs, I would suggest that (when the eventually reconsidered syntax
is proposed) this change should be highlighted explicitly as a feature
removal. IMO, it wouldn't be otherwise immediately apparent from a
quick glance that revising `stride(from: 0, to: 10, by: 1)` to
`(0..<10).striding(by: 1)` necessarily entails deletion of backwards
strides from upper bound to-and-not-through lower bound.


>> If it must be a method on a range,
>
> It's not that it must be, but having such a method tends to reduce API
> surface area.  We prefer methods to free functions.
>
>> then I would advocate for having what seems to be an utterly
>> reasonable set of options for striding backwards:
>>
>> ```
>> (0...200).striding(by: -2) // [a, b]
>> (0..<200).striding(by: -2) // [a, b)
>> (0<..200).striding(by: -2) // (a, b]
>> ```
>
> And I'm trying to say that without a more compelling reason to introduce
> `<..`, I don't want to do it.  I'd like to know that `<..` is useful
> outside the domain of striding, for example.  Use-cases, anyone?

Well, my use case (an actual one) is supremely mundane. I'm doing some
scientific computing and I need to deal with numeric intervals. Some
of them are closed, some of them are open at one end, and some at the
other. I'd like to be able to represent any of those as
Intervals-which-are-now-Ranges. It makes sense to do so because the
things I want to do with them, such as clamping and testing if some
value is contained, are exactly what Intervals-now-Ranges provide.
Looking around, it seems many other languages provide only what Swift
currently does, but Perl does provide `..`, `..^`, `^..`, and `^..^`
(which, brought over to Swift, would be `...`, `..<`, `<..`, and
`<.<`).


> Reasons we might not need it: the cases where it's important are much
> more likely to be notionally continuous domains (e.g. floats), since you
> can always write
>
> ((0+1)...200).striding(by: -2)
>
> and if you need the floating version there's always
>
>(0.0...200.0).striding(by: -2).lazy.filter { $0 != 0.0 }
>
> which probably optimizes down to the same code.
>
> One question that I *do* think we should answer, is whether the elements
> of
>
> (0..<199).striding(by: -2)
>
> are even or odd.
>
>> On Wed, Apr 6, 2016 at 12:10 PM Dave Abrahams via swift-evolution
>>  wrote:
>>
>> on Wed Apr 06 2016, Brent Royal-Gordon  wrote:
>>
>> >> For example, there are all kinds of other ways to slice this:
>> >>
>> >> stride(over: 0..<200, by: -2)
>> >
>> > This seems like a particularly good solution. The way I understand it
>> > at least, it would allow ranges to always be ordered, with the only
>> > difference being whether it went start-to-end or end-to-start,
>> > determined by the stride's sign.
>>
>> This is no different in principle from
>>
>> (0..<200).striding(by: -2)
>>
>> Again, I wasn't trying to suggest any of the solutions listed there.
>> The point I was making was that we don't have enough information to
>> design more than
>>
>> (0..<200).striding(by: -2)
>>
>> > It would also avoid the need for additional range operators. The main
>> > reason you would need `>..` is so you could say
>> > `array.endIndex>..array.startIndex`, but by using the sign to decide
>> > which direction to stride over the range, you instead stride over
>> > `array.startIndex..> > have.
>> >
>> > Unfortunately, moving away from `stride(from:to/through:by:)` would
>> > kind of mess up an idea I've been developing for providing an
>> > "induction sequence" t

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Ted F.A. van Gaalen via swift-evolution
Hi Erica, Dave

Based on what I’ve (not all) read under this topic: 

I’d suggest a more complete approach:

Ranges should support:  (as yet not implemented) 

- All numerical data types (Double, Float, Int, Money***, Decimal*** ) 
- An arbitrary increment or decrement value.
- Working in the complete  - + numerical range
- Allow traversing in both   - + directions.



The basics:

(v1…v2).by(v3) // this still is readable. and can be optimized by the 
compiler (predictable sequence)

Rules:

v1, v2, v3  are any numerical type scalar type  
v1, v2, v3  must have the same numerical type.
v1 >  v2:   is allowed and correctly evaluated.  e.g. 
(8.0…-3.14159).by(-0.0001) 


The  ..<  half open operator is no longer allowed.   write e.g.   
0...ar.count - 1

"by(…)”  is obligatory with floating point range.

   the default “by(…)” value of 1 makes sense only with integer ranges.


valid examples:
(5…9)// 5 6 7 8 9 Integer range without “by” 
defaults to 1 as increment value.
(1...10).by(2) // 1 3 5 7 9.
(2...10).by(2) // 2 4 6 8 10.
(4…-4).by(2) // 4  2 0 -2 -4 .// runs backwards
(30..-10).by(-2)// 30 28 26 24 22 ….. -10.
(10...0).by(-3)  // 10 7 4 1. 

(12…-10) // is valid, but returns empty because default 
increment value = 1

(12.0…-12.0).by(-1.5)   // 12.0  10.5  9.0….  // of course with 
float imprecision
   
   

   invalid examples:

   (23.0..<60.5).by(0.5) // half open ranges are no  longer allowed ** 
  (23.0…60.5) // “ by"  is obligatory with floats.
  (14...8).by(0.5)//  v1 v2 and v3 don’t have the same 
numerical type 


Half open ranges make no real sense (are not really useful) with floating point 
values.
and no sense at all with e.g (12..<-1)  afaics 


At least for float iterations the increment value should not each time be 
accumulated like
v1 += v3;  v1 += v3;  v1 += v3;  ….   // causes float 
number drift.
but be freshly multiplied with each iteration, e.g. by using an internal 
iteration counter
like so:

v1 = v3 * i++;   v1 = v3 * i++;   v1 = v3 * i++;….

for reasons of precision.

If one has worked with floating point data more often
awareness of its precision limitations become a second nature conscience. 
E.g. it is perfectly acceptable and known (also in classical for-loops) that
(0.0…1.0).by(0.1) is not guaranteed to reach the humanly expected value of 1.0.
This is normal. Due to the nature of what mostly is done in the
floating point numbers domain, this does not often cause a problem
(e.g like working with a slide ruler) 
if it is important to reach the “expected end” then one could
-add an epsilon value like so (v1…v2 + 0.1) 
-generate the desired float sequence within an integer loop.


The above “range” (imho) improvement makes the 
stride.. function/keyword completely unnecessary.

Due to its ability to process reversed ranges as is, 
the .reverse() is optional (no longer necessary in most cases,
allowing the compiler to optimize without having to process 
it like a collection.


Now that we have a fully functional range, which can do all things desired, one 
can
then of course, pass this range without any change  to a collection based for … 
 e.g.

for v in (v1…v2).by(v3)   // optionally add other collection 
operators/filters/sorts here

(or in any other construct you might see fit)
   

This seems to be a reasonable alternative for

- the classical for ;; loop
-the collection-free for-loop  
 for v from v1 to v2 by v3

As you know, the latter is what I have been suggesting, 
but seemingly does not find much support,
(because I received very little reactions) 
making it doubtful if I will ever make a proposal for this for loop.
Anyone out there should I stil do that? 

When one does not further extend the range
with filters like sort etc. the compiler can still optimize 
a collection-in-between out of the way.
(Thank you Taras, für das Mitdenken. :o)


**   note that a half open range would in most cases be unnecessary 
  if  collection indexes started with 1 instead of 0, e.g. someArray[1…10] 
 (but it’s too late to change that.) 
 “the color of the first apple?”vs
 “the color of the zeroth (0) ???  apple?”? Silly isn’t? 

*** possible future numerical “native” types 


It could be that (at least) partly something similar has already been suggested.
but so much is here of this topic that i can’t see the wood for the trees, so 
to speak.


Your (all) opinions are appreciated. 

kind regards, mit freundlichen Grüssen, Met vriendelijke groeten, 
Sigh, why do we Dutch always have to speak the languages of the bigger 
countries :o) 
TedvG

> on Wed Apr 06 2016, Erica Sadun  

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 12:43 PM, Dave Abrahams  wrote:
> 
> 
> on Wed Apr 06 2016, Erica Sadun  wrote:
> 
>>On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution
>> wrote:
>>(0..<199).striding(by: -2)
>> 
>>are even or odd.
>> 
>> (0..<199).striding(by: -2): 0..<199 == 0...198 Even
>> (1..<199).striding(by: -2): 1..<199 == 1...198 Even
> 
> I understand the logic that got you there, but I find it incredibly
> counter-intuitive that striding by 2s over a range with odd endpoints
> should produce even numbers... I can't imagine any way I'd be convinced
> that was a good idea.

Guidance:

When using odd integer literals to produce an even number sequence,
prefer the `...` operator to the `..<` operator and change your ending
literal to an even number.

-- E


> 
>> (0..<198).striding(by: -2): 1..<198 == 0...197 Odd
>> (1..<198).striding(by: -2): 1..<198 == 1...197 Odd
>> 
>> -- E
>> 
> 
> -- 
> Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Erica Sadun  wrote:

> On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution
>  wrote:
> (0..<199).striding(by: -2)
>
> are even or odd.
>
> (0..<199).striding(by: -2): 0..<199 == 0...198 Even
> (1..<199).striding(by: -2): 1..<199 == 1...198 Even

I understand the logic that got you there, but I find it incredibly
counter-intuitive that striding by 2s over a range with odd endpoints
should produce even numbers... I can't imagine any way I'd be convinced
that was a good idea.

> (0..<198).striding(by: -2): 1..<198 == 0...197 Odd
> (1..<198).striding(by: -2): 1..<198 == 1...197 Odd
>
> -- E
>

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 12:30 PM, Dave Abrahams via swift-evolution 
>  wrote:
> on Wed Apr 06 2016, Stephen Canon  wrote:
>> For the (0..<199) case, Erica’s assessment 
> 
> which is...?

https://gist.github.com/erica/786ab9703f699db1301be65510e7da03 


-- E

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Milos Rankovic via swift-evolution

> On 6 Apr 2016, at 19:16, Dave Abrahams via swift-evolution 
>  wrote:
> 
> We prefer methods to free functions.

However, `(from:to:by)` need not be a free function, it could be a sequence 
initialiser:

Walk(from: 200, to: 0, by: 2)

or:

Steps(from: 200, to: 0, by: 2)

or something along those lines...

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Stephen Canon  wrote:

> On Apr 6, 2016, at 11:20 AM, Stephen Canon via swift-evolution
>  wrote:
>
> On Apr 6, 2016, at 11:16 AM, Dave Abrahams via swift-evolution
>  wrote:
>
> One question that I *do* think we should answer, is whether the 
> elements
> of
>
> (0..<199).striding(by: -2)
>
> are even or odd.
>
> Odd. I don’t believe that many real use cases care, but odd is more
> efficient from a performance perspective. Needs to be documented clearly,
> however.
>
> Sorry, I was thinking of (0…199).striding(by: -2).
>
> For the (0..<199) case, Erica’s assessment 

which is...?

> seems about right, though it isn’t at all obvious how it generalizes
> to floating point strides.
>
> – Steve
>

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Milos Rankovic  wrote:

> On 6 Apr 2016, at 18:57, Xiaodi Wu via swift-evolution
>  wrote:
>
> Meanwhile, I was trying to talk about something like `stride(from: 200, 
> to:
> 0, by: -2)`, which is easily expressed today but isn't straightforward at
> all to preserve with only ranges.
>
> Precisely because the free function is also range-free, the sign of the step
> need not repeat the direction intent which is already indicated with `from: 
> 200,
> to: 0`. In other words, I think this is much more intuitive:
>
> `stride(from: 200, to: 0, by: 2)`

But it leaves the “does it include 0?” question less clear than
something involving 0..<200 would.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Stephen Canon via swift-evolution

> On Apr 6, 2016, at 11:26 AM, Erica Sadun  wrote:
> 
>> 
>> On Apr 6, 2016, at 12:23 PM, Stephen Canon via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Apr 6, 2016, at 11:20 AM, Stephen Canon via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Apr 6, 2016, at 11:16 AM, Dave Abrahams via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 One question that I *do* think we should answer, is whether the elements
 of
 
(0..<199).striding(by: -2)
 
 are even or odd.
>>> 
>>> Odd.  I don’t believe that many real use cases care, but odd is more 
>>> efficient from a performance perspective.  Needs to be documented clearly, 
>>> however.
>> 
>> Sorry, I was thinking of (0…199).striding(by: -2).
>> 
>> For the (0..<199) case, Erica’s assessment seems about right, though it 
>> isn’t at all obvious how it generalizes to floating point strides.
> 
> (l.. cannot be a starting value.

I’m OK with this.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 12:23 PM, Stephen Canon via swift-evolution 
>  wrote:
> 
> 
>> On Apr 6, 2016, at 11:20 AM, Stephen Canon via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Apr 6, 2016, at 11:16 AM, Dave Abrahams via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> One question that I *do* think we should answer, is whether the elements
>>> of
>>> 
>>>(0..<199).striding(by: -2)
>>> 
>>> are even or odd.
>> 
>> Odd.  I don’t believe that many real use cases care, but odd is more 
>> efficient from a performance perspective.  Needs to be documented clearly, 
>> however.
> 
> Sorry, I was thinking of (0…199).striding(by: -2).
> 
> For the (0..<199) case, Erica’s assessment seems about right, though it isn’t 
> at all obvious how it generalizes to floating point strides.

(l..___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Stephen Canon via swift-evolution

> On Apr 6, 2016, at 11:20 AM, Stephen Canon via swift-evolution 
>  wrote:
> 
>> On Apr 6, 2016, at 11:16 AM, Dave Abrahams via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> One question that I *do* think we should answer, is whether the elements
>> of
>> 
>>(0..<199).striding(by: -2)
>> 
>> are even or odd.
> 
> Odd.  I don’t believe that many real use cases care, but odd is more 
> efficient from a performance perspective.  Needs to be documented clearly, 
> however.

Sorry, I was thinking of (0…199).striding(by: -2).

For the (0..<199) case, Erica’s assessment seems about right, though it isn’t 
at all obvious how it generalizes to floating point strides.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 12:16 PM, Dave Abrahams via swift-evolution 
>  wrote:
>(0..<199).striding(by: -2)
> 
> are even or odd.

(0..<199).striding(by: -2): 0..<199 == 0...198 Even
(1..<199).striding(by: -2): 1..<199 == 1...198 Even
(0..<198).striding(by: -2): 1..<198 == 0...197 Odd
(1..<198).striding(by: -2): 1..<198 == 1...197 Odd

-- E

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Stephen Canon via swift-evolution
> On Apr 6, 2016, at 11:16 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> One question that I *do* think we should answer, is whether the elements
> of
> 
>(0..<199).striding(by: -2)
> 
> are even or odd.

Odd.  I don’t believe that many real use cases care, but odd is more efficient 
from a performance perspective.  Needs to be documented clearly, however.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Xiaodi Wu  wrote:

> I think a lightbulb just went on for me:
>
> You're talking about expressing something in the vein of 
> `(0..<200).striding(by:
> -2)`, which has I'm sure many use cases, and which isn't straightforward to
> express with the current free function--I hadn't considered that.
>
> Meanwhile, I was trying to talk about something like `stride(from: 200, to: 0,
> by: -2)`, which is easily expressed today but isn't straightforward at all to
> preserve with only ranges. Clearly, given that this is what's on offer
> currently, someone who designed the language thinks (or thought) it's of some
> use.

That someone was me, and I explained that it wasn't an extremely
deeply-considered decision.

> In the absence of information as to which is more in demand, couldn't
> we have both? 

That's not how we make decisions about what should be in the language or
standard library.  We need to make choices based on (at least educated
guesses about) what people need, or we'll end up with a sprawling mess.

> If it must be a method on a range, 

It's not that it must be, but having such a method tends to reduce API
surface area.  We prefer methods to free functions.

> then I would advocate for having what seems to be an utterly
> reasonable set of options for striding backwards:
>
> ```
> (0...200).striding(by: -2) // [a, b]
> (0..<200).striding(by: -2) // [a, b)
> (0<..200).striding(by: -2) // (a, b]
> ```

And I'm trying to say that without a more compelling reason to introduce
`<..`, I don't want to do it.  I'd like to know that `<..` is useful
outside the domain of striding, for example.  Use-cases, anyone?

Reasons we might not need it: the cases where it's important are much
more likely to be notionally continuous domains (e.g. floats), since you
can always write

((0+1)...200).striding(by: -2)

and if you need the floating version there's always

   (0.0...200.0).striding(by: -2).lazy.filter { $0 != 0.0 }

which probably optimizes down to the same code.

One question that I *do* think we should answer, is whether the elements
of

(0..<199).striding(by: -2)

are even or odd.

> On Wed, Apr 6, 2016 at 12:10 PM Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed Apr 06 2016, Brent Royal-Gordon  wrote:
>
> >> For example, there are all kinds of other ways to slice this:
> >>
> >> stride(over: 0..<200, by: -2)
> >
> > This seems like a particularly good solution. The way I understand it
> > at least, it would allow ranges to always be ordered, with the only
> > difference being whether it went start-to-end or end-to-start,
> > determined by the stride's sign.
>
> This is no different in principle from
>
> (0..<200).striding(by: -2)
>
> Again, I wasn't trying to suggest any of the solutions listed there.
> The point I was making was that we don't have enough information to
> design more than
>
> (0..<200).striding(by: -2)
>
> > It would also avoid the need for additional range operators. The main
> > reason you would need `>..` is so you could say
> > `array.endIndex>..array.startIndex`, but by using the sign to decide
> > which direction to stride over the range, you instead stride over
> > `array.startIndex.. > have.
> >
> > Unfortunately, moving away from `stride(from:to/through:by:)` would
> > kind of mess up an idea I've been developing for providing an
> > "induction sequence" to replace the more complicated C-style for use
> > cases, but I suppose that's the way it goes...
> >
> > (Link to that:
> https://gist.github.com/brentdax/b24dd89a770d9fe376984498d3185187)
>
> --
> Dave
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Milos Rankovic via swift-evolution

> On 6 Apr 2016, at 18:57, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Meanwhile, I was trying to talk about something like `stride(from: 200, to: 
> 0, by: -2)`, which is easily expressed today but isn't straightforward at all 
> to preserve with only ranges.

Precisely because the free function is also range-free, the sign of the step 
need not repeat the direction intent which is already indicated with `from: 
200, to: 0`. In other words, I think this is much more intuitive:

 `stride(from: 200, to: 0, by: 2)`

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Stephen Canon via swift-evolution

> On Apr 6, 2016, at 10:10 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Wed Apr 06 2016, Brent Royal-Gordon  wrote:
> 
>>> For example, there are all kinds of other ways to slice this:
>>> 
>>>   stride(over: 0..<200, by: -2)
>> 
>> This seems like a particularly good solution. The way I understand it
>> at least, it would allow ranges to always be ordered, with the only
>> difference being whether it went start-to-end or end-to-start,
>> determined by the stride's sign.
> 
> This is no different in principle from
> 
> (0..<200).striding(by: -2)
> 
> Again, I wasn't trying to suggest any of the solutions listed there.
> The point I was making was that we don't have enough information to
> design more than
> 
>(0..<200).striding(by: -2)

Of the suggestions I’ve seen floated, this is my favorite by a huge margin.

- It preserves the ordering of range endpoints.
- It supports the right kind of half-open intervals—[a,b)—for zero-based 
indexing.
- It avoids making reverse iteration significantly more complex.

– Steve
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Erica Sadun via swift-evolution

> On Apr 6, 2016, at 11:10 AM, Dave Abrahams  wrote:
> Again, I wasn't trying to suggest any of the solutions listed there.
> The point I was making was that we don't have enough information to
> design more than
> 
>(0..<200).striding(by: -2)

I like this a lot but I assure you there will be some pushback about 
readability of intent.

-- "Cassandra"___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Xiaodi Wu via swift-evolution
I think a lightbulb just went on for me:

You're talking about expressing something in the vein of
`(0..<200).striding(by: -2)`, which has I'm sure many use cases, and which
isn't straightforward to express with the current free function--I hadn't
considered that.

Meanwhile, I was trying to talk about something like `stride(from: 200, to:
0, by: -2)`, which is easily expressed today but isn't straightforward at
all to preserve with only ranges. Clearly, given that this is what's on
offer currently, someone who designed the language thinks (or thought) it's
of some use.

In the absence of information as to which is more in demand, couldn't we
have both? If it must be a method on a range, then I would advocate for
having what seems to be an utterly reasonable set of options for striding
backwards:

```
(0...200).striding(by: -2) // [a, b]
(0..<200).striding(by: -2) // [a, b)
(0<..200).striding(by: -2) // (a, b]
```
On Wed, Apr 6, 2016 at 12:10 PM Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Wed Apr 06 2016, Brent Royal-Gordon  wrote:
>
> >> For example, there are all kinds of other ways to slice this:
> >>
> >>stride(over: 0..<200, by: -2)
> >
> > This seems like a particularly good solution. The way I understand it
> > at least, it would allow ranges to always be ordered, with the only
> > difference being whether it went start-to-end or end-to-start,
> > determined by the stride's sign.
>
> This is no different in principle from
>
>  (0..<200).striding(by: -2)
>
> Again, I wasn't trying to suggest any of the solutions listed there.
> The point I was making was that we don't have enough information to
> design more than
>
> (0..<200).striding(by: -2)
>
> > It would also avoid the need for additional range operators. The main
> > reason you would need `>..` is so you could say
> > `array.endIndex>..array.startIndex`, but by using the sign to decide
> > which direction to stride over the range, you instead stride over
> > `array.startIndex.. > have.
> >
> > Unfortunately, moving away from `stride(from:to/through:by:)` would
> > kind of mess up an idea I've been developing for providing an
> > "induction sequence" to replace the more complicated C-style for use
> > cases, but I suppose that's the way it goes...
> >
> > (Link to that:
> https://gist.github.com/brentdax/b24dd89a770d9fe376984498d3185187)
>
> --
> Dave
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Wed Apr 06 2016, Brent Royal-Gordon  wrote:

>> For example, there are all kinds of other ways to slice this:
>> 
>>stride(over: 0..<200, by: -2)
>
> This seems like a particularly good solution. The way I understand it
> at least, it would allow ranges to always be ordered, with the only
> difference being whether it went start-to-end or end-to-start,
> determined by the stride's sign.

This is no different in principle from

 (0..<200).striding(by: -2)

Again, I wasn't trying to suggest any of the solutions listed there.
The point I was making was that we don't have enough information to
design more than

(0..<200).striding(by: -2)

> It would also avoid the need for additional range operators. The main
> reason you would need `>..` is so you could say
> `array.endIndex>..array.startIndex`, but by using the sign to decide
> which direction to stride over the range, you instead stride over
> `array.startIndex.. have.
>
> Unfortunately, moving away from `stride(from:to/through:by:)` would
> kind of mess up an idea I've been developing for providing an
> "induction sequence" to replace the more complicated C-style for use
> cases, but I suppose that's the way it goes...
>
> (Link to that: 
> https://gist.github.com/brentdax/b24dd89a770d9fe376984498d3185187)

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Brent Royal-Gordon via swift-evolution
> For example, there are all kinds of other ways to slice this:
> 
>stride(over: 0..<200, by: -2)

This seems like a particularly good solution. The way I understand it at least, 
it would allow ranges to always be ordered, with the only difference being 
whether it went start-to-end or end-to-start, determined by the stride's sign.

It would also avoid the need for additional range operators. The main reason 
you would need `>..` is so you could say `array.endIndex>..array.startIndex`, 
but by using the sign to decide which direction to stride over the range, you 
instead stride over `array.startIndex..https://gist.github.com/brentdax/b24dd89a770d9fe376984498d3185187)

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Tue Apr 05 2016, Xiaodi Wu  wrote:

> On Tue, Apr 5, 2016 at 4:28 PM, Dave Abrahams via swift-evolution
>  wrote:
>>
>> on Tue Apr 05 2016, Xiaodi Wu  wrote:
>>
>>> Right. I would argue that `(a+s...b).striding(by: s).reversed` is a great 
>>> deal
>>> less readable than `stride(from: b, to: a, by: -s)`. And since the latter 
>>> is the
>>> status quo, I would say that it's a point against restricting strides to the
>>> proposed syntax.
>>
>> Yes, those are all points.  But it totally avoids the question of
>> whether the case of striding over an inverted half-open range by a
>> negative step is an important enough case to be worth complicating the
>> library to make it readable.
>
> At the risk of tedious pedantry--
>
> Given that this discussion was spawned from one about Swift's for
> loop, it would be remiss not to circle back and point out that what's
> at issue isn't a matter of complicating an existing implementation to
> support stride to (or, striding over an inverted half-open range) with
> negative stride size, but rather whether a proposed simplification
> ought to be implemented that removes this already supported use case.
> IMO, the existing implementation is not overly inelegant, and deep in
> the logic of StrideToIterator is an if statement (using a ternary
> operator in the expression, no less!) to account for negative stride
> size--so I can only conclude that its being supported isn't merely a
> happy byproduct of the current implementation but very much an
> explicitly planned-for feature.

I fully agree that negative strides ought to be supported, e.g. 

  r.striding(by: -d)

>> If it is important enough, I am much more inclined to support
>>
>> (a<..b).striding(by: s).reversed
>>
>> or
>>
>> (a<..b).striding(by: -s)  // i.e., negative strides automatically reverse
>>
>> simply because it makes a presumably-useful concept available (inverse
>> half-open range), re-uses existing syntax, and doesn't bring up these
>> naming questions.
>>
>> Frankly,
>>
>> (a+s...b).striding(by: -s)
>>
>> isn't all that bad.
>>
>>> On Tue, Apr 5, 2016 at 3:57 PM Dave Abrahams via swift-evolution
>>>  wrote:
>>>
>>> on Tue Apr 05 2016, Xiaodi Wu
>>>  wrote:
>>>
>>> > Certainly, for integer literals and strides of -1.
>>> >
>>> > I meant more generally that removal of stride(...) will eliminate the
>>> > possibility of striding to but not through arbitrary half-open 
>>> intervals
>>> (a, b],
>>> > where a < b, by a negative increment, because there is no such thing 
>>> as
>>> `a>..b`
>>> > to express such an interval as a Swift range.
>>> > Of course, all such cases can be handled by adjusting the endpoint and
>>> using a
>>> > closed range instead
>>> >
>>>
>>> Indeed, if b - a is a multiple of s,
>>>
>>> (a+s...b).striding(by: s).reversed
>>>
>>> works.
>>>
>>> The question is whether this case is important enough to create a
>>> special family of functions for, and then deal with the naming issues
>>> raised by
>>> 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0051-stride-semantics.md
>>>
>>> ?
>>>
>>> > On Tue, Apr 5, 2016 at 2:54 PM Dave Abrahams
>>> >  wrote:
>>> >
>>> > on Tue Apr 05 2016, Xiaodi Wu  wrote:
>>> >
>>> > > On Mon, Apr 4, 2016 at 1:22 PM, Dave Abrahams
>>> >  wrote:
>>> > >>
>>> > >> on Sat Apr 02 2016, Xiaodi Wu  wrote:
>>> > >>
>>> > >>> [snip]
>>> > >>>
>>> > >>> Not included:
>>> > >>> 1. I know Ranges are in flux, so I've held off on extending Range 
>>> with
>>> > >>> a striding(by:) method in this proof-of-concept.
>>> > >>
>>> > >> They're not in flux, except for not having been reviewed yet; they 
>>> are
>>> > >> settled in the swift-3-indexing-model branch.
>>> > >
>>> > > Did not know that. Will have to study what's there in more detail.
>>> > >
>>> > >>> 2. No attempt at the suggested stride(from:to:steps:) quite yet.
>>> > >>
>>> > >> #1 and #2 are mutually exclusive; we prefer #1 as it removes 
>>> questions
>>> > >> about the meaning of "to" or "through."
>>> > >
>>> > > I wasn't aware that was the thinking. Limiting strides to
>>> > > `striding(by:)` removes the ability to express `stride(from: 0, to:
>>> > > -10, by: -1)`
>>> >
>>> > IMO this:
>>> >
>>> > (-9...0).reverse()
>>> >
>>> > is better than
>>> >
>>> > stride(from: 0, to: -10, by: -1)
>>> >
>>> > What do you think?
>>> >
>>> > --
>>> > Dave
>>> >
>>> > ___
>>> > swift-evolution mailing list
>>> > swift-evolution@swift.org
>>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>> --
>>> Dave
>>>
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https:/

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Tue Apr 05 2016, Xiaodi Wu  wrote:

> I think my opinion is largely the same. A range is not a stride, 

I don't think anyone on this thread has suggested they could be
considered the same... until just now.

> and sometimes we have use for striding backwards, a use case that
> shouldn't be penalized. +1 to the free function.
>
> I wouldn't mind, orthogonally, a way to express (a, b] as a range. It
> just seems like that should be of use, somewhere.

But that's not a strong enough reason to add it to the standard library.

> Finally, orthogonal to all of the above, I'm super eager to end error
> accumulation in floating point strides.

Looking forward to those results, too!

> On Tue, Apr 5, 2016 at 6:52 PM Erica Sadun via swift-evolution
>  wrote:
>
> On Apr 5, 2016, at 5:22 PM, Dave Abrahams via swift-evolution
>  wrote:
> I don't think that's obvious at all, because 0 ≮ 10
>
> Points brought up elsewhere:
>
> * A range does not have direction, it is is an area of variation between
> lower and upper limits.
> * A range does not go from a larger amount to a smaller amount because it 
> is
> not a sequence
> * Much of this problem goes away with striding (as Dave pointed out 
> several
> times, sorry Dave)
>
> After consideration, I have been persuaded to the opinion that
>
> stride(from: 0, to: -10, by: -1)
>
> and 
>
> (-9...0).reverse()
>
> both represent the numbers -9, -8,...,0 better than any alternatives I 
> have
> offered. I still
> prefer the stride version for intent and clarity.
>
> That said, I also prefer my revised SE-0051 semantics for better
> representing what strides will
> attempt to do.
>
> -- Erica
>
> p.s. Thanks all for the patient explanations
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Dave Abrahams via swift-evolution

on Tue Apr 05 2016, Erica Sadun  wrote:

> On Apr 5, 2016, at 5:22 PM, Dave Abrahams via swift-evolution
>  wrote:
> I don't think that's obvious at all, because 0 ≮ 10
>
> Points brought up elsewhere:

Sorry, I've tried, but I'm afraid I don't understand any of this:

> * A range does not have direction, it is is an area of variation between lower
> and upper limits.

I don't know what you mean by “does not have direction.”  We're talking
about a concept whose Bound must be Comparable, so there's an implied
ordering of bounds: the lower bound precedes (or is coincident with) the
upper bound.  This ordering is also strongly implied by the form of the
..< operator.

> * A range does not go from a larger amount to a smaller amount because it is 
> not
>   a sequence

Ranges with Integer strides *are* sequences.  Are you saying that
there's no good reason to expect any particular traversal order?

> 
> * Much of this problem goes away with striding (as Dave pointed out
> several times, sorry Dave)

What problem goes away with striding, and how?  I pointed this out?

> After consideration, I have been persuaded to the opinion that
>
> stride(from: 0, to: -10, by: -1)
>
> and 
>
> (-9...0).reverse()
>
> both represent the numbers -9, -8,...,0 better than any alternatives I
> have offered. I still prefer the stride version for intent and
> clarity.

I agree it's clearer.  The only question I have about this is whether
it's worth the complexity, since the choice isn't between the first and
the second, but between *both* and the second.

> That said, I also prefer my revised SE-0051 semantics for better
> representing what strides will attempt to do.


My biggest problem with that proposal is that it isn't clear that these
three distinctions map onto important use-cases.  The only reason we
ended up with stride(to:...) and stride(through:...) in the first place
was that we have closed and open ranges.  In other words, the two
original distinctions were not driven by use-cases.  Now SE-0051 is
talking about expanding them to three distinctions in the name of
clarity, still without use-cases to motivate them.  I'd rather roll
these features back while we still can, as long as there's another
reasonable way to express them, until we find out what kinds of things
people actually want to write that are difficult to express.

For example, there are all kinds of other ways to slice this:

stride(over: 0..<200, by: -2)

stride(100, stepsOver: 0..<200)

(0..<200).divided(into: 100)

(0..<200).stepping(100).times

(0..<200) / 100

I'm not suggesting any of these, in particular.  I'm just saying, we
don't really even have a good idea of what will suit peoples' real-world
needs.

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-06 Thread Howard Lovatt via swift-evolution
I think people are reading a ..< b as the mathematical notation [a, b)
which means {}, null, or empty, not error, if b < a and {a} if b = a.

If Range was changed to be an Array like collection indexed from 0 to count
and stride was how the indexed counted and was an Int > 0 then the
following would make sense in terms of interval mathematics as described
above (note how stride refers to how the index counts *not* how the values
count):

(0 ... -1) == []
(0 ..< 0) == []

(0 ... 0) == [0]
(0 ..< 2) == [0, 1]

(0 ... 2) == [0, 1, 2]

(0 ..< 4).strided(by: 2) == [0, 1, 2, 3].strided(by: 2) == [0, 2]

(0 ... 4).strided(by: 2) == [0, 1, 2, 3, 4].strided(by: 2) == [0, 2, 4]

(0 ..< 2).reversed == [0, 1].reversed == [1, 0]

(0 ..< 4).strided(by: 2).reversed == [0, 1, 2, 3].strided(by: 2).reversed
== [0, 2].reversed == [2, 0]

(-2 ..< 2).strided(by: 2).reversed == [-2, -1, 0, 1].strided(by:
2).reversed == [-2, 0].reversed == [0, -2]

(-2 ..< 2).reversed.strided(by: 2) == [-2, -1, 0, 1].reversed.strided(by:
2) == [1, 0, -1, -2].strided(by: 2) == [1, -1]


Then provide a very general init for Range to cope with difficult cases:

init(first: T, isFirstIncluded: Bool = true, last: T, isLastIncluded: Bool
= true, stride: Int = 1)

Range(first: 0, last: 0, stride: 0) // ERROR, stride must be > 0
Range(first: 0, last: 0) == [0]

Range(first: 0, isFirstIncluded: false, last: 0) == [] // {x | first < x <=
last }
Range(first: 0, last: 0, isLastIncluded: false) == [] // {x | first <= x <
last }

Range(first: -2, isFirstIncluded: false, last: 2, isLastIncluded: false) ==
[-1, 0, 1]
Range(first: -2, isFirstIncluded: false, last: 2, isLastIncluded: false,
stride: 2) == [-1, 1]


Note: only ForwardIndexType necessary.

  -- Howard.

On 6 April 2016 at 09:22, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Tue Apr 05 2016, Erica Sadun  wrote:
>
> >> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >>
> >> on Tue Apr 05 2016, Erica Sadun  wrote:
> >>
> >
> >>>On Apr 5, 2016, at 1:54 PM, Dave Abrahams
> >>> wrote:
> >>>IMO this:
> >>>
> >>>(-9...0).reverse()
> >>>
> >>>is better than
> >>>
> >>>stride(from: 0, to: -10, by: -1)
> >>>
> >>>What do you think?
> >>>
> >>> The latter better reflects an author's actual intent. The former
> depends on
> >>> implementation details, which can be hazy, especially, around the edge
> cases. It
> >>> is quicker to read, understand, and verify that the latter is what is
> >>> meant.
> >>
> >> Except that there seems to be some confusion over what "to:" means,
> right?
> >
> > obviously (0..<-10).by(-2) would be best.
>
> I don't think that's obvious at all, because 0 ≮ 10
>
> --
> Dave
>
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Xiaodi Wu via swift-evolution
On Tue, Apr 5, 2016 at 4:28 PM, Dave Abrahams via swift-evolution
 wrote:
>
> on Tue Apr 05 2016, Xiaodi Wu  wrote:
>
>> Right. I would argue that `(a+s...b).striding(by: s).reversed` is a great 
>> deal
>> less readable than `stride(from: b, to: a, by: -s)`. And since the latter is 
>> the
>> status quo, I would say that it's a point against restricting strides to the
>> proposed syntax.
>
> Yes, those are all points.  But it totally avoids the question of
> whether the case of striding over an inverted half-open range by a
> negative step is an important enough case to be worth complicating the
> library to make it readable.

At the risk of tedious pedantry--

Given that this discussion was spawned from one about Swift's for
loop, it would be remiss not to circle back and point out that what's
at issue isn't a matter of complicating an existing implementation to
support stride to (or, striding over an inverted half-open range) with
negative stride size, but rather whether a proposed simplification
ought to be implemented that removes this already supported use case.
IMO, the existing implementation is not overly inelegant, and deep in
the logic of StrideToIterator is an if statement (using a ternary
operator in the expression, no less!) to account for negative stride
size--so I can only conclude that its being supported isn't merely a
happy byproduct of the current implementation but very much an
explicitly planned-for feature.

> If it is important enough, I am much more inclined to support
>
> (a<..b).striding(by: s).reversed
>
> or
>
> (a<..b).striding(by: -s)  // i.e., negative strides automatically reverse
>
> simply because it makes a presumably-useful concept available (inverse
> half-open range), re-uses existing syntax, and doesn't bring up these
> naming questions.
>
> Frankly,
>
> (a+s...b).striding(by: -s)
>
> isn't all that bad.
>
>> On Tue, Apr 5, 2016 at 3:57 PM Dave Abrahams via swift-evolution
>>  wrote:
>>
>> on Tue Apr 05 2016, Xiaodi Wu
>>  wrote:
>>
>> > Certainly, for integer literals and strides of -1.
>> >
>> > I meant more generally that removal of stride(...) will eliminate the
>> > possibility of striding to but not through arbitrary half-open 
>> intervals
>> (a, b],
>> > where a < b, by a negative increment, because there is no such thing as
>> `a>..b`
>> > to express such an interval as a Swift range.
>> > Of course, all such cases can be handled by adjusting the endpoint and
>> using a
>> > closed range instead
>> >
>>
>> Indeed, if b - a is a multiple of s,
>>
>> (a+s...b).striding(by: s).reversed
>>
>> works.
>>
>> The question is whether this case is important enough to create a
>> special family of functions for, and then deal with the naming issues
>> raised by
>> 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0051-stride-semantics.md
>>
>> ?
>>
>> > On Tue, Apr 5, 2016 at 2:54 PM Dave Abrahams
>> >  wrote:
>> >
>> > on Tue Apr 05 2016, Xiaodi Wu  wrote:
>> >
>> > > On Mon, Apr 4, 2016 at 1:22 PM, Dave Abrahams
>> >  wrote:
>> > >>
>> > >> on Sat Apr 02 2016, Xiaodi Wu  wrote:
>> > >>
>> > >>> [snip]
>> > >>>
>> > >>> Not included:
>> > >>> 1. I know Ranges are in flux, so I've held off on extending Range 
>> with
>> > >>> a striding(by:) method in this proof-of-concept.
>> > >>
>> > >> They're not in flux, except for not having been reviewed yet; they 
>> are
>> > >> settled in the swift-3-indexing-model branch.
>> > >
>> > > Did not know that. Will have to study what's there in more detail.
>> > >
>> > >>> 2. No attempt at the suggested stride(from:to:steps:) quite yet.
>> > >>
>> > >> #1 and #2 are mutually exclusive; we prefer #1 as it removes 
>> questions
>> > >> about the meaning of "to" or "through."
>> > >
>> > > I wasn't aware that was the thinking. Limiting strides to
>> > > `striding(by:)` removes the ability to express `stride(from: 0, to:
>> > > -10, by: -1)`
>> >
>> > IMO this:
>> >
>> > (-9...0).reverse()
>> >
>> > is better than
>> >
>> > stride(from: 0, to: -10, by: -1)
>> >
>> > What do you think?
>> >
>> > --
>> > Dave
>> >
>> > ___
>> > swift-evolution mailing list
>> > swift-evolution@swift.org
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> --
>> Dave
>>
>> ___
>> 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
>
> __

Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Xiaodi Wu via swift-evolution
I think my opinion is largely the same. A range is not a stride, and
sometimes we have use for striding backwards, a use case that shouldn't be
penalized. +1 to the free function.

I wouldn't mind, orthogonally, a way to express (a, b] as a range. It just
seems like that should be of use, somewhere.

Finally, orthogonal to all of the above, I'm super eager to end error
accumulation in floating point strides.
On Tue, Apr 5, 2016 at 6:52 PM Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Apr 5, 2016, at 5:22 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
> I don't think that's obvious at all, because 0 ≮ 10
>
>
> Points brought up elsewhere:
>
> * A range does not have direction, it is is an area of variation between
> lower and upper limits.
> * A range does not go from a larger amount to a smaller amount because it
> is not a sequence
> * Much of this problem goes away with striding (as Dave pointed out
> several times, sorry Dave)
>
> After consideration, I have been persuaded to the opinion that
>
>  stride(from: 0, to: -10, by: -1)
>
>
> and
>
>(-9...0).reverse()
>
>
> both represent the numbers -9, -8,...,0 better than any alternatives I
> have offered. I still
> prefer the stride version for intent and clarity.
>
> That said, I also prefer my revised SE-0051 semantics for better
> representing what strides will
> attempt to do.
>
> -- Erica
> p.s. Thanks all for the patient explanations
>
>
>
>
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Erica Sadun via swift-evolution

> On Apr 5, 2016, at 5:22 PM, Dave Abrahams via swift-evolution 
>  wrote:
> I don't think that's obvious at all, because 0 ≮ 10

Points brought up elsewhere:

* A range does not have direction, it is is an area of variation between lower 
and upper limits.
* A range does not go from a larger amount to a smaller amount because it is 
not a sequence
* Much of this problem goes away with striding (as Dave pointed out several 
times, sorry Dave)

After consideration, I have been persuaded to the opinion that

>  stride(from: 0, to: -10, by: -1)

and 

>(-9...0).reverse()

both represent the numbers -9, -8,...,0 better than any alternatives I have 
offered. I still
prefer the stride version for intent and clarity.

That said, I also prefer my revised SE-0051 semantics for better representing 
what strides will
attempt to do.

-- Erica
p.s. Thanks all for the patient explanations




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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Dave Abrahams via swift-evolution

on Tue Apr 05 2016, Erica Sadun  wrote:

>> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Tue Apr 05 2016, Erica Sadun  wrote:
>> 
>
>>>On Apr 5, 2016, at 1:54 PM, Dave Abrahams
>>> wrote:
>>>IMO this:
>>> 
>>>(-9...0).reverse()
>>> 
>>>is better than 
>>> 
>>>stride(from: 0, to: -10, by: -1)
>>> 
>>>What do you think?
>>> 
>>> The latter better reflects an author's actual intent. The former depends on
>>> implementation details, which can be hazy, especially, around the edge 
>>> cases. It
>>> is quicker to read, understand, and verify that the latter is what is
>>> meant.
>> 
>> Except that there seems to be some confusion over what "to:" means, right?
>
> obviously (0..<-10).by(-2) would be best.

I don't think that's obvious at all, because 0 ≮ 10

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Dave Abrahams via swift-evolution

on Tue Apr 05 2016, Stephen Canon  wrote:

> On Apr 5, 2016, at 3:22 PM, Erica Sadun via swift-evolution
>  wrote:
>
> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Tue Apr 05 2016, Erica Sadun
>  wrote:
>
> On Apr 5, 2016, at 1:54 PM, Dave Abrahams
>  wrote:
> IMO this:
>
> (-9...0).reverse()
>
> is better than 
>
> stride(from: 0, to: -10, by: -1)
>
> What do you think?
>
> The latter better reflects an author's actual intent. The former
> depends on
> implementation details, which can be hazy, especially, around the
> edge cases. It
> is quicker to read, understand, and verify that the latter is what
> is
> meant.
>
> Except that there seems to be some confusion over what "to:" means,
> right?
>
> obviously (0..<-10).by(-2) would be best.
>
> (0 ..> -10).by(-2)?
>
> Maybe having another range operator is overkill, but ..< seems pretty bonkers
> here.

I can't see any excuse for putting the smaller number on the right.  If
one really needs the numbers in that order, then I agree a stride free
function is better.

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Erica Sadun via swift-evolution

> On Apr 5, 2016, at 4:24 PM, Stephen Canon  wrote:
> 
>> On Apr 5, 2016, at 3:22 PM, Erica Sadun via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> on Tue Apr 05 2016, Erica Sadun >> > wrote:
>>> 
   On Apr 5, 2016, at 1:54 PM, Dave Abrahams
   mailto:dabrah...@apple.com>> wrote:
   IMO this:
 
   (-9...0).reverse()
 
   is better than 
 
   stride(from: 0, to: -10, by: -1)
 
   What do you think?
 
 The latter better reflects an author's actual intent. The former depends on
 implementation details, which can be hazy, especially, around the edge 
 cases. It
 is quicker to read, understand, and verify that the latter is what is
 meant.
>>> 
>>> Except that there seems to be some confusion over what "to:" means, right?
>> 
>> obviously (0..<-10).by(-2) would be best.
> 
> (0 ..> -10).by(-2)?
> 
> Maybe having another range operator is overkill, but ..< seems pretty bonkers 
> here.

Suddenly SE-0051 is starting to look a lot more promising.

https://github.com/apple/swift-evolution/blob/master/proposals/0051-stride-semantics.md
 


-- E

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Dave Abrahams via swift-evolution

on Tue Apr 05 2016, Xiaodi Wu  wrote:

> On Mon, Apr 4, 2016 at 1:22 PM, Dave Abrahams  wrote:
>>
>> on Sat Apr 02 2016, Xiaodi Wu  wrote:
>>
>>> [snip]
>>>
>>> Not included:
>>> 1. I know Ranges are in flux, so I've held off on extending Range with
>>> a striding(by:) method in this proof-of-concept.
>>
>> They're not in flux, except for not having been reviewed yet; they are
>> settled in the swift-3-indexing-model branch.
>
> Did not know that. Will have to study what's there in more detail.

Actually, let me amend that.  The protocols involved need to be
de-underscored, the doc comments need to be written, and I am noticing a
few missing things around the edges.  But the basic shape of it is stable.

>
>
>>> 2. No attempt at the suggested stride(from:to:steps:) quite yet.
>>
>> #1 and #2 are mutually exclusive; we prefer #1 as it removes questions
>> about the meaning of "to" or "through."
>
> I wasn't aware that was the thinking. Limiting strides to
> `striding(by:)` removes the ability to express `stride(from: 0, to:
> -10, by: -1)` because Range enforces (and it looks like it will
> continue to do so in the swift-3-indexing-model branch?) `lowerBound
> <= upperBound`, and in a half-open range it's the upper bound that's
> excluded.
>
>>> 2. No tests written yet for this proof-of-concept; I noticed that
>>> there's a stub for testing strides with bounds of type Double, but
>>> there's a comment about things not being ready because Double conforms
>>> to RandomIndexType--not sure what to make of that.
>>
>> Comments in that branch are badly out-of-date.  It's worth trying that,
>> especially since there is no RandomAccessIndexType in that branch any
>> longer.
>>
>>> 3. Haven't gotten around to testing performance.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
Dave

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Xiaodi Wu via swift-evolution
Well, probably best to have another operator: 0..>(-10). We go from 0 to
greater than -10.
On Tue, Apr 5, 2016 at 5:22 PM Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

>
> > On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> >
> > on Tue Apr 05 2016, Erica Sadun  wrote:
> >
> >>On Apr 5, 2016, at 1:54 PM, Dave Abrahams
> >> wrote:
> >>IMO this:
> >>
> >>(-9...0).reverse()
> >>
> >>is better than
> >>
> >>stride(from: 0, to: -10, by: -1)
> >>
> >>What do you think?
> >>
> >> The latter better reflects an author's actual intent. The former
> depends on
> >> implementation details, which can be hazy, especially, around the edge
> cases. It
> >> is quicker to read, understand, and verify that the latter is what is
> >> meant.
> >
> > Except that there seems to be some confusion over what "to:" means,
> right?
>
>
> obviously (0..<-10).by(-2) would be best.
>
> -- E
>
> ___
> 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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Stephen Canon via swift-evolution
> On Apr 5, 2016, at 3:22 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
>> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> on Tue Apr 05 2016, Erica Sadun  wrote:
>> 
>>>   On Apr 5, 2016, at 1:54 PM, Dave Abrahams
>>>wrote:
>>>   IMO this:
>>> 
>>>   (-9...0).reverse()
>>> 
>>>   is better than 
>>> 
>>>   stride(from: 0, to: -10, by: -1)
>>> 
>>>   What do you think?
>>> 
>>> The latter better reflects an author's actual intent. The former depends on
>>> implementation details, which can be hazy, especially, around the edge 
>>> cases. It
>>> is quicker to read, understand, and verify that the latter is what is
>>> meant.
>> 
>> Except that there seems to be some confusion over what "to:" means, right?
> 
> obviously (0..<-10).by(-2) would be best.

(0 ..> -10).by(-2)?

Maybe having another range operator is overkill, but ..< seems pretty bonkers 
here.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Erica Sadun via swift-evolution

> On Apr 5, 2016, at 4:22 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
>> 
>> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Tue Apr 05 2016, Erica Sadun  wrote:
>> 
>>>   On Apr 5, 2016, at 1:54 PM, Dave Abrahams
>>>wrote:
>>>   IMO this:
>>> 
>>>   (-9...0).reverse()
>>> 
>>>   is better than 
>>> 
>>>   stride(from: 0, to: -10, by: -1)
>>> 
>>>   What do you think?
>>> 
>>> The latter better reflects an author's actual intent. The former depends on
>>> implementation details, which can be hazy, especially, around the edge 
>>> cases. It
>>> is quicker to read, understand, and verify that the latter is what is
>>> meant.
>> 
>> Except that there seems to be some confusion over what "to:" means, right?
> 
> 
> obviously (0..<-10).by(-2) would be best.
> 
> -- E

or even (0..<(-10)).by(-2)

As much as this looks like a Lisp program, it still improves over the 
alternatives

-- E



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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Erica Sadun via swift-evolution

> On Apr 5, 2016, at 4:17 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue Apr 05 2016, Erica Sadun  wrote:
> 
>>On Apr 5, 2016, at 1:54 PM, Dave Abrahams
>> wrote:
>>IMO this:
>> 
>>(-9...0).reverse()
>> 
>>is better than 
>> 
>>stride(from: 0, to: -10, by: -1)
>> 
>>What do you think?
>> 
>> The latter better reflects an author's actual intent. The former depends on
>> implementation details, which can be hazy, especially, around the edge 
>> cases. It
>> is quicker to read, understand, and verify that the latter is what is
>> meant.
> 
> Except that there seems to be some confusion over what "to:" means, right?


obviously (0..<-10).by(-2) would be best.

-- E

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


Re: [swift-evolution] Feature proposal: Range operator with step

2016-04-05 Thread Dave Abrahams via swift-evolution

on Tue Apr 05 2016, Erica Sadun  wrote:

> On Apr 5, 2016, at 1:54 PM, Dave Abrahams
>  wrote:
> IMO this:
>
> (-9...0).reverse()
>
> is better than 
>
> stride(from: 0, to: -10, by: -1)
>
> What do you think?
>
> The latter better reflects an author's actual intent. The former depends on
> implementation details, which can be hazy, especially, around the edge cases. 
> It
> is quicker to read, understand, and verify that the latter is what is
> meant.

Except that there seems to be some confusion over what "to:" means, right?

-- 
Dave

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


  1   2   >