[swift-evolution] [Proposal] Safer half-open range operator

Daniel Quirino quirinux at gmail.com
Thu Apr 14 03:30:24 CDT 2016


Totally agreed with you guys, for me the matter question here is:

Why should we care about language details instead  what the app really have
to do?

Keeping in mind that kind of stuff doesn't help, the focus should be in
their functionalities and all that could be done to get handy and keep a
clearly code should be done, I think we need less C/C++/Obj-C style on
swift and I let a question:

What controlling arrays bounds stands for? being that swift could do this
behind the scenes.



Em quarta-feira, 13 de abril de 2016, Luis Henrique B. Sousa via
swift-evolution <swift-evolution at swift.org> escreveu:

> Another common application would be on pagination systems. For example,
> this function that I just found randomly:
>
> https://github.com/MrAlek/PagedArray/blob/bf64cbb140cf8bd109483dd749ac40a5f4531dfd/Source/PagedArray.swift#L88
>
>
> public func indexes(pageIndex: Int) -> Range<Index> {
>     assert(pageIndex >= startPageIndex && pageIndex <= lastPageIndex,
> "Page index out of bounds")
>
>     let startIndex: Index = (pageIndex-startPageIndex)*pageSize
>     let endIndex: Index
>     if pageIndex == lastPageIndex {
>         endIndex = count
>     } else {
>         endIndex = startIndex+pageSize
>     }
>
>     return (startIndex..<endIndex)
> }
>
>
> wouldn't be required anymore before accessing the array, having simply
> something like
>
> > let current = pageIndex * pageSize
> > array[safe: (current - pageSize) ..< (current + pageSize)]
>
> (or *truncate* according to the user expectation) instead, which in my
> opinion looks much more elegant and handy.
>
>
> Regards,
>
> - Luis
>
> On Wed, Apr 13, 2016 at 7:37 PM, Vladimir.S via swift-evolution <
> swift-evolution at swift.org
> <javascript:_e(%7B%7D,'cvml','swift-evolution at swift.org');>> wrote:
>
>>
>> On 13.04.2016 19:59, Pyry Jahkola wrote:
>>
>>> On 13 Apr 2016, at 17:53, Luis Henrique B. Sousa <lshsousa at gmail.com
>>>> <javascript:_e(%7B%7D,'cvml','lshsousa at gmail.com');>
>>>> <mailto:lshsousa at gmail.com
>>>> <javascript:_e(%7B%7D,'cvml','lshsousa at gmail.com');>>> wrote:
>>>>
>>>> (…) I totally agree with @Vladimir that we could have a more clear and
>>>> /swift-ly/ way to concisely wrap those operations.
>>>>
>>>> The behaviour pointed out by him looks very nice and doable to me.
>>>>
>>>> a = [1,2,3]
>>>> a[-1..<6] - raises runtime error (right behavior by default, doesn't
>>>> affect existing code)
>>>> a[truncate: -1..<6] - produces [1,2,3] (the very behaviour I proposed
>>>> initially)
>>>> a[safe: -1..<6] - produces nil (i.e [T]?) (no runtime errors and makes
>>>> it
>>>> easy to handle unexpected results)
>>>>
>>>
>>> I don't feel strongly about this. Yes, if this were shorter to express,
>>> it
>>> would feel like /nicer/ design. But what Haravikk and Chris L. already
>>> said
>>> seems to me as /wiser/ design.
>>>
>>
>>
>> IMO it is not just nicer, it provides you with handy and explicit
>> alternatives.
>>
>> In some situations, you are checking bounds and you sure that if you
>> calculated them incorrectly - error will be raised.
>> But sometimes, you don't need to check exact bounds, probably "take these
>> values, or give me nil of no such".
>>
>> I can compare this with Dictionary we have in Swift.
>> Can you say if it is "wise" to return Optional(T) when we calls
>> dict[somekey] ? Probably it is wise to raise error if there is no such key?
>> (to force us to check the key first).
>>
>> The proposed subscript for special situations when you know you need
>> exactly this behavior to make your code clear and readable and you fully
>> controls code&error flow.
>>
>>
>>> (@Vladimir: Besides, I'm sure `.clamped(to:)` wasn't invented for this
>>> purpose but for doing interval arithmetic on ranges. It just happens to
>>> somewhat work here.)
>>>
>>> – Would this feature really provide a measurable benefit to developers?
>>> – Under which circumstances do you find yourself with a past-the-end
>>> upper
>>> bound such as 6 where `a.count == 3`?
>>> – …Let alone a /negative/ start index like `-1`?
>>>
>>> I find cases like these to be much more common in languages like Python
>>> and
>>> Ruby where e.g. `array[-2]` refers to the penultimate element. Swift
>>> doesn't seem to want to go there.
>>>
>>>
>> Each good feature will provide benefit to developers. For those, who work
>> a lot with arrays/bounds/slices/copies this will provide measurable
>> benefit, IMO.
>> Can we live without such improvement? Absolutely. Are there more
>> important proposals? Yes. But will this make Swift more elegant, handy,
>> clear? Yes, I believe.
>>
>> As for "Under which circumstances.." questions. Well.. something like
>> "get +- 5 elements(at max) with center in some index"
>>
>> let a = [1,2,3,4,5,6]
>> let index = random(0..<a.count)
>> let result = a[truncate: index-5...index+5]
>>
>> or "get 5 elements from index, if no 5 elements from index - return empty
>> array"
>>
>> let a = [1,2,3,4,5,6]
>> let index = random(0..<a.count)
>> if let result = a[safe: index..<index+5]  //[Int]?
>>  {return result}
>> else
>>  {return []}
>>
>> Something like this.
>>
>>
>> For the use cases I can think of, Swift 3—as the proposal currently goes
>>> <
>>> https://github.com/apple/swift/blob/swift-3-indexing-model/stdlib/public/core/Collection.swift#L724-L808
>>> >—already
>>> offers the following suitable methods:
>>>
>>>      array[bounds]
>>>      array.prefix(maxLength)// no precondition
>>>      array.prefix(upTo: index)
>>>      array.prefix(through: index)
>>>      array.dropLast(n)// no precondition
>>>      array.dropFirst(n)// no precondition
>>>      array.suffix(from: index)
>>>      array.suffix(maxLength)      // no precondition
>>>
>>> If these feel too clumsy to use, maybe we should focus on making them all
>>> more convenient. Ideally, that suggestion would apply to all
>>> `Collection`s.
>>>
>>> — Pyry
>>>
>>>
>> Yes, some variants can be covered by these methods:
>> array.prefix(maxLength) -> array[truncate: 0..<maxLength]
>> array.prefix(upTo) -> array[0..<upTo]
>> array.prefix(through) -> array[0...through]
>>
>> And some has no good alternatives in subscription:
>> array.suffix(from: index) -> array[truncate: index...Int.max ??
>> array.suffix(maxLength)   -> array[truncate: hm..
>>
>> But. As array[bound] returns a copy(slice) of array, it feels natural to
>> have variants of behavior of array[bound], just like you have different
>> variants of prefix() methods.
>>
>> So it seems for me like this proposal for subscript variants(safe: &
>> truncate:) is good addition to then proposal you pointed to.
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> <javascript:_e(%7B%7D,'cvml','swift-evolution at swift.org');>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>
>

-- 
Obrigado.
Daniel Quirino
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160414/83d6c1b6/attachment.html>


More information about the swift-evolution mailing list