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

Dave Abrahams dabrahams at apple.com
Wed Apr 6 15:28:27 CDT 2016


on Wed Apr 06 2016, Xiaodi Wu <swift-evolution at swift.org> wrote:

> On Wed, Apr 6, 2016 at 1:16 PM, Dave Abrahams <dabrahams at apple.com> wrote:
>>
>> on Wed Apr 06 2016, Xiaodi Wu <xiaodi.wu-AT-gmail.com> 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
>>> <swift-evolution at swift.org> wrote:
>>>
>>>     on Wed Apr 06 2016, Brent Royal-Gordon <brent-AT-architechies.com> 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..<array.endIndex`, which is exactly what we already
>>>     > 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 at swift.org
>>>     https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>> --
>> Dave
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
Dave



More information about the swift-evolution mailing list