[swift-evolution] Let range operators always return empty ranges if the upper bound is smaller than the lower bound.
Denis Nikitenko
d.nikitenko at icloud.com
Wed Jan 20 08:10:59 CST 2016
Another hearty +1 from me as well. I’ve run into this recently and used the stride-based work-round. However, using
for i in startIndex.stride(through: endIndex, by: 1){
...
}
instead of
for i in startIndex…endIndex{
…
}
solely so that the body of the loop never executes if startIndex > endIndex seems unnecessary - especially since
for i in startIndex…<endIndex+1{
…
}
works perfectly fine. It would make sense to make `…` and `..<` consistent with each other and return an empty range in this case - which would also be consistent with the overall behaviour of stride().
Denis
> On Jan 20, 2016, at 3:55 AM, Thorsten Seitz via swift-evolution <swift-evolution at swift.org> wrote:
>
> +1
>
> -Thorsten
>
> Am 20.01.2016 um 02:32 schrieb Howard Lovatt via swift-evolution <swift-evolution at swift.org>:
>
>> +1 from me. I have been caught by this. In the degenerate case I didn't want the loop to be processed, but instead I got a runtime error. I solved the problem by changing to a C style for loop, but with the removal of C style for loops this will be more of a problem.
>>
>> This could be solved with a library function as already suggested, however having `...`, `..<`, `...?`, and `..<?` seems excessive. Therefore my suggestion is to make `...` & `..<` behave as proposed (i.e. return empty ranges when limits mean nothing enclosed by range).
>>
>> On Wednesday, 20 January 2016, Félix Cloutier <swift-evolution at swift.org> wrote:
>> I don't have a strong opinion on this, but maybe there could be a ..<?/...? operator for ranges that may or may not be well-formed? This solution can be implemented "at home" too.
>>
>> I'd love to see where and how developers use ranges. It may be more helpful than it looks like. For instance, if you use a range to get an array slice, would your rather have an empty slice if your range underflows instead of the current error behavior?
>>
>> Félix
>>
>>> Le 19 janv. 2016 à 15:46:00, Uwe Falck via swift-evolution <swift-evolution at swift.org> a écrit :
>>>
>>> I’m looking for feedback on this request if its worth to start an evolution proposal.
>>>
>>>
>>> Let range operators always return empty ranges if the upper bound is smaller than the lower bound.
>>>
>>> ####
>>>
>>> Introduction
>>>
>>> ####
>>>
>>> Consider two loops. The first loop iterator will return an empty range and will not be executed. The second loop throws an error. I would like to see the range iterator always returning an empty range if end index < start index.
>>>
>>> for i in 3..<3
>>> { print(i) }
>>>
>>> for i in 3…2
>>> { print(i) }
>>>
>>>
>>> ####
>>>
>>> Motivation
>>>
>>> ####
>>>
>>> The two expressions above are mathematically equivalent and I would like them to return the same result for consistency.
>>>
>>> Furthermore, and more important: if C-style for loops are gone with Swift 3.0, programmers may translate
>>>
>>> func fibonacci(n: Int) -> Int { // works for n>=0
>>> var memo = [0,1]
>>> for var i = 2; i <= n; i++ {
>>> memo.append(memo[i-1] + memo[i-2])
>>> }
>>> return memo[n]
>>> }
>>>
>>> probably into
>>>
>>> func fibonacci(n: Int) -> Int { // works only for n>=2!
>>> var memo = [0,1]
>>> for i in 2...n {
>>> memo.append(memo[i-1] + memo[i-2])
>>> }
>>> return memo[n]
>>> }
>>>
>>> This example is from Stackoverflow[1] with two suggested solutions to prevent the runtime error for 0 and 1
>>>
>>> let startIndex = 2
>>> let endIndex = n
>>> for i in startIndex.stride(through: endIndex, by: 1) {
>>> memo.append(memo[i-1] + memo[i-2])
>>> }
>>>
>>> …and another one uses the empty range generate by ..<
>>>
>>> for i in 2 ..< max(2, n+1) {
>>> memo.append(memo[i-1] + memo[i-2])
>>> }
>>>
>>> Clearly the not-working-solution looks most logical. All other control flow elements, like while, will just not execute if their condition is not met on loop entry.
>>>
>>>
>>> #####
>>>
>>> Proposed solution
>>>
>>> #####
>>>
>>> Let both range iterators return emtpy ranges, if end index < start index, and not only for a..<b with a==b.
>>>
>>> #####
>>>
>>> Impact on existing code
>>>
>>> #####
>>>
>>> None.
>>>
>>> ####
>>>
>>> Alternatives considered
>>>
>>> ####
>>>
>>> If range operators will allow downward variants this idea becomes pointless.
>>>
>>> ####
>>>
>>> Open questions
>>>
>>> ####
>>>
>>> None.
>>>
>>>
>>> [1] http://stackoverflow.com/questions/34323227/a-concise-way-to-not-execute-a-loop-now-that-c-style-for-loops-are-going-to-be-r?lq=1
>>>
>>>
>>> Thanks,
>>>
>>>
>>> --
>>>
>>> Uwe
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>> --
>> -- Howard.
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list