[swift-evolution] [Proposal] More lenient subscript methods over Collections

Luis Henrique B. Sousa lshsousa at gmail.com
Tue May 17 17:18:47 CDT 2016


Many thanks, @Maximilian. I'm also not sure about the performance cost, but
I think it is worth it.
So I just updated the proposal also including the additional min/max you
have suggested (thanks once again):
https://github.com/apple/swift-evolution/pull/328

Best regards,

- Luis

On Tue, May 17, 2016 at 10:32 PM, Maximilian Hünenberger <
m.huenenberger at me.com> wrote:

> While it is true that it uses min and max, you have to add *additional
> min max* in order to achieve the desired behavior.
>
> So the implementation should be: (also considering (hopefully all) recent
> naming/index model updates)
>
> // Index is already Comparable
> extension Collection {
>
>     subscript(clamping range: Range<Index>) -> SubSequence {
>         // ---> here you have to use the additional min/max
>         let start = min(max(startIndex, range.startIndex), endIndex)
>         let end = max(min(endIndex, range.endIndex), startIndex)
>         return self[start ..< end]
>
>         // ---> or as alternative, probably a bit less performant but
> Swiftier
>         return self[range.clamping(startIndex..<endIndex)]
>     }
>
>     subscript(checking range: Range<Index>) -> SubSequence? {
>         guard range.startIndex >= startIndex && range.endIndex <= endIndex
>             else { return nil }
>         return self[range]
>     }
>
>     subscript(checking index: Index) -> Generator.Element? {
>         // ---> minor syntax update *
>         guard self.indices.contains(index)
>             else { return nil }
>         return self[index]
>     }
>
> }
>
> * I'm not sure it is worth the performance cost for arbitrary indices
> collection with O(n) search. I could imagine Set and Dictionary indices
> cannot be easily validated in comparison to Array indices. However this
> approach is more general and handles non trivial index collections where
> there is no guarantee that any index between startIndex and endIndex is a
> valid one.
> The same arguments also apply to `subscript(checking range ...)` where you
> could validate start and endIndex of the range.
>
> Best regards
> Maximilian
>
> Am 16.05.2016 um 09:45 schrieb Luis Henrique B. Sousa <lshsousa at gmail.com
> >:
>
> Yes. The suggested implementation does use min/max:
>
>
> https://github.com/luish/swift-evolution/blob/more-lenient-subscripts/proposals/nnnn-more-lenient-collections-subscripts.md#detailed-design
>
> - Luis
>
> On Sun, May 15, 2016 at 3:42 PM, Maximilian Hünenberger <
> m.huenenberger at me.com> wrote:
>
>> I brought these up because the current implementation produces an error
>> in these cases. You have to insert additional min/max operations.
>>
>> Am 15.05.2016 um 16:38 schrieb Luis Henrique B. Sousa <lshsousa at gmail.com
>> >:
>>
>> Exactly, the idea is to return an empty array just like other languages
>> do. (e.g. python)
>>
>> - Luis
>>
>> On Sun, May 15, 2016 at 10:13 AM, Vladimir.S via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>> On 15.05.2016 0:09, Maximilian Hünenberger via swift-evolution wrote:
>>>
>>>> One point which should be discussed is the following behaviour:
>>>>
>>>> let array = [0]
>>>> // ranges are completely out of bounds and produce an error
>>>> array[clamping: 1...2] // error
>>>> array[clamping: -2...-1] // error
>>>>
>>>> Should a range which has no intersection with the indices of the
>>>> collection
>>>> produce an error or just clamp to 0..<0 respectively
>>>> endIndex..<endIndex?
>>>>
>>>
>>> I expect it will returns [] i.e. empty array, as no elements with
>>> 1...2(-2..-1) indexes in the array. I understand `clamping` similar as
>>> 'bounded','in these bounds'. And as soon as [0,1,2,3,4][clamping:2...10]
>>> will silently move the right position to allowed index(4), and
>>> [0,1,2,3,4][clamping:-2...0]  will move left position to 0, I expect that
>>> in [0][clamping: 1...2] will try to move both limits to allowed, and as no
>>> intersection - silently return empty array.
>>>
>>>
>>>> Best regards
>>>> Maximilian
>>>>
>>>> Am 13.05.2016 um 17:10 schrieb Luis Henrique B. Sousa via
>>>> swift-evolution
>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>>>>
>>>> It seems that there is a consensus that this proposal might be a good
>>>>> addition to the standard library. All comments on this thread in the
>>>>> past
>>>>> few weeks were related to naming, not around the behaviour or validity
>>>>> of
>>>>> the proposed methods. So I will submit this proposal for review very
>>>>> soon
>>>>> assuming that nobody else has strong arguments against it. :-)
>>>>>
>>>>> Proposal:
>>>>> https://github.com/luish/swift-evolution/blob/more-lenient-subscripts/proposals/nnnn-more-lenient-collections-subscripts.md
>>>>>
>>>>> If you have any corrections or suggestions to the proposal text itself,
>>>>> please comment on this gist:
>>>>> https://gist.github.com/luish/832c34ee913159f130d97a914810dbd8
>>>>> (or pull request to my repo)
>>>>>
>>>>> Regards,
>>>>>
>>>>> - Luis
>>>>>
>>>>> On Tue, May 10, 2016 at 4:13 PM, Luis Henrique B. Sousa
>>>>> <lshsousa at gmail.com <mailto:lshsousa at gmail.com>> wrote:
>>>>>
>>>>>     Please let me know if you have more suggestions or corrections on
>>>>>     this proposal.
>>>>>     I'm tempted to submit it for review. :-)
>>>>>
>>>>>     - Luis
>>>>>
>>>>>     On Tue, May 10, 2016 at 8:53 AM, Luis Henrique B. Sousa
>>>>>     <lshsousa at gmail.com <mailto:lshsousa at gmail.com>> wrote:
>>>>>
>>>>>         It sounds good, thanks for you suggestions @Vladimir, @Patrick
>>>>>         and @Brent.
>>>>>
>>>>>         I've just updated the proposal:
>>>>>
>>>>> https://github.com/luish/swift-evolution/blob/more-lenient-subscripts/proposals/nnnn-more-lenient-collections-subscripts.md#detailed-design
>>>>>
>>>>>         - Luis
>>>>>
>>>>>         On Tue, May 10, 2016 at 6:50 AM, Vladimir.S via swift-evolution
>>>>>         <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>> wrote:
>>>>>
>>>>>             Yes, I feel like 'within' is much better than 'bounded'.
>>>>>
>>>>>             How about such changes in proposal:
>>>>>
>>>>>             a[bounded: -1 ..< 5]  -->  a[within: -1 ..< 5]  (or
>>>>> a[inside:
>>>>>             -1 ..< 5] )
>>>>>
>>>>>             a[optional: 0 ..< 5]  -->  a[checking: 0 ..< 5]
>>>>>             a[optional: 5]        -->  a[checking: 5]
>>>>>
>>>>>             ?
>>>>>
>>>>>             On 10.05.2016 6:27, Patrick Smith via swift-evolution
>>>>> wrote:
>>>>>
>>>>>                 I like the idea of the of the bounded subscript,
>>>>> however
>>>>>                 the optional one I
>>>>>                 feel could be used for clumsy code.
>>>>>
>>>>>                 .first and .last have value, but once you start
>>>>> stepping
>>>>>                 several arbitrary
>>>>>                 indices in, then that code is likely fragile?
>>>>>
>>>>>
>>>>>                 I can think of ‘within’, ‘inside’ and ‘intersecting’ as
>>>>>                 alternative names
>>>>>                 for ‘bounded’ that attempt to explain what is going on:
>>>>>
>>>>>                 let a = [1, 2, 3]
>>>>>
>>>>>                 a[within: 0 ..< 5] // [1, 2, 3]
>>>>>                 a[inside: 0 ..< 5] // [1, 2, 3]
>>>>>                 a[intersecting: 0 ..< 5] // [1, 2, 3]
>>>>>
>>>>>
>>>>>                     On 28 Apr 2016, at 10:11 PM, Luis Henrique B. Sousa
>>>>>                     via swift-evolution
>>>>>                     <swift-evolution at swift.org
>>>>>                     <mailto:swift-evolution at swift.org>
>>>>>                     <mailto:swift-evolution at swift.org
>>>>>                     <mailto:swift-evolution at swift.org>>> wrote:
>>>>>
>>>>>                     As we have discussed throughout this thread, the
>>>>>                     initial proposal was
>>>>>                     modified to include alternative subscript methods
>>>>>                     instead of modifying
>>>>>                     the default operator/subscript behaviour.
>>>>>                     The first draft is
>>>>>                     here:
>>>>>
>>>>> https://github.com/luish/swift-evolution/blob/more-lenient-subscripts/proposals/nnnn-more-lenient-collections-subscripts.md
>>>>>
>>>>>                     I've also put this as a gist so that you can leave
>>>>>                     comments with respect
>>>>>                     to the proposal document itself. Any suggestion or
>>>>>                     help is very welcome.
>>>>>
>>>>> https://gist.github.com/luish/832c34ee913159f130d97a914810dbd8
>>>>>
>>>>>                     Regards,
>>>>>
>>>>>                     - Luis
>>>>>
>>>>>                     On Mon, Apr 11, 2016 at 1:23 PM, Luis Henrique B.
>>>>> Sousa
>>>>>                     <lshsousa at gmail.com <mailto:lshsousa at gmail.com>
>>>>>                     <mailto:lshsousa at gmail.com
>>>>>
>>>>>                     <mailto:lshsousa at gmail.com>>> wrote:
>>>>>
>>>>>                         This proposal seeks to provide a safer ..< (aka
>>>>>                     half-open range
>>>>>                         operator) in order to avoid **Array index out
>>>>> of
>>>>>                     range** errors in
>>>>>                         execution time.
>>>>>
>>>>>                         Here is my first draft for this proposal:
>>>>>
>>>>>
>>>>> https://github.com/luish/swift-evolution/blob/half-open-range-operator/proposals/nnnn-safer-half-open-range-operator.md
>>>>>
>>>>>                         In short, doing that in Swift causes a runtime
>>>>> error:
>>>>>
>>>>>                         leta =[1,2,3]
>>>>>                         letb =a[0..<5]
>>>>>                         print(b)
>>>>>
>>>>>                         > Error running code:
>>>>>                         > fatal error: Array index out of range
>>>>>
>>>>>                         The proposed solution is to slice the array
>>>>>                     returning all elements
>>>>>                         that are below the half-open operator, even
>>>>>                     though the number of
>>>>>                         elements is lesser than the ending of the
>>>>>                     half-open operator. So the
>>>>>                         example above would return [1,2,3].
>>>>>                         We can see this very behaviour in other
>>>>>                     languages, such as Python and
>>>>>                         Ruby as shown in the proposal draft.
>>>>>
>>>>>                         This would eliminate the need for verifications
>>>>>                     on the array size
>>>>>                         before slicing it -- and consequently runtime
>>>>>                     errors in cases when
>>>>>                         the programmer didn't.
>>>>>
>>>>>                         Viewing that it is my very first proposal, any
>>>>>                     feedback will be helpful.
>>>>>
>>>>>                         Thanks!
>>>>>
>>>>>                         Luis Henrique Borges
>>>>>                         @luishborges
>>>>>
>>>>>
>>>>>                     _______________________________________________
>>>>>                     swift-evolution mailing list
>>>>>                     swift-evolution at swift.org
>>>>>                     <mailto:swift-evolution at swift.org>
>>>>>                     <mailto:swift-evolution at swift.org
>>>>>                     <mailto:swift-evolution at swift.org>>
>>>>>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>                 _______________________________________________
>>>>>                 swift-evolution mailing list
>>>>>                 swift-evolution at swift.org <mailto:
>>>>> swift-evolution at swift.org>
>>>>>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>>             _______________________________________________
>>>>>             swift-evolution mailing list
>>>>>             swift-evolution at swift.org <mailto:
>>>>> swift-evolution at swift.org>
>>>>>             https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org <mailto: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
>>>>
>>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160517/97e32dff/attachment.html>


More information about the swift-evolution mailing list