Subsequences and shared indices


(Tim Vermeulen) #1

Is it a requirement that collections share indices with its subsequence? Array and ArraySlice do share indices, which is why ArraySlice isn’t zero-based, and I think this is convenient. But String.CharacterView doesn’t seem to share indices with its subsequence (which is String.CharacterView as well). Consider this example:

let foo = "foobar".characters

let index = foo.index(foo.startIndex, offsetBy: 3)
let bar = foo.suffix(from: index) // "bar"

foo[index] // "b" :slight_smile:
foo[bar.startIndex] // "f" :frowning:

So does this mean that we can’t assume that collections and their subsequences share their indices (which could be very handy), or is this just a bug related to String.CharacterView?


(Hooman Mehr) #2

This is a bug reported multiple times in different forms. My version of it is: SR-1487 <https://bugs.swift.org/browse/SR-1487>.

It remains open because it is not easy to fix with the existing design of String. Apparently core standard library team are working on an overhaul of String to address this and other usability and performance issues.

···

On Oct 13, 2016, at 5:12 PM, Tim Vermeulen via swift-users <swift-users@swift.org> wrote:

Is it a requirement that collections share indices with its subsequence? Array and ArraySlice do share indices, which is why ArraySlice isn’t zero-based, and I think this is convenient. But String.CharacterView doesn’t seem to share indices with its subsequence (which is String.CharacterView as well). Consider this example:

let foo = "foobar".characters

let index = foo.index(foo.startIndex, offsetBy: 3)
let bar = foo.suffix(from: index) // "bar"

foo[index] // "b" :slight_smile:
foo[bar.startIndex] // "f" :frowning:

So does this mean that we can’t assume that collections and their subsequences share their indices (which could be very handy), or is this just a bug related to String.CharacterView?
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Tim Vermeulen) #3

Alright. Does this mean that we can otherwise assume that collections share indices with their subsequences? It might be worth documenting, one way or the other.

···

On 14 Oct 2016, at 02:40, Hooman Mehr <hooman@mac.com> wrote:

This is a bug reported multiple times in different forms. My version of it is: SR-1487 <https://bugs.swift.org/browse/SR-1487>.

It remains open because it is not easy to fix with the existing design of String. Apparently core standard library team are working on an overhaul of String to address this and other usability and performance issues.

On Oct 13, 2016, at 5:12 PM, Tim Vermeulen via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Is it a requirement that collections share indices with its subsequence? Array and ArraySlice do share indices, which is why ArraySlice isn’t zero-based, and I think this is convenient. But String.CharacterView doesn’t seem to share indices with its subsequence (which is String.CharacterView as well). Consider this example:

let foo = "foobar".characters

let index = foo.index(foo.startIndex, offsetBy: 3)
let bar = foo.suffix(from: index) // "bar"

foo[index] // "b" :slight_smile:
foo[bar.startIndex] // "f" :frowning:

So does this mean that we can’t assume that collections and their subsequences share their indices (which could be very handy), or is this just a bug related to String.CharacterView?
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Dave Abrahams) #4

Is it a requirement that collections share indices with its
subsequence?

Yes.

Array and ArraySlice do share indices, which is why ArraySlice isn’t
zero-based, and I think this is convenient. But String.CharacterView
doesn’t seem to share indices with its subsequence (which is
String.CharacterView as well).

That's a bug.

Consider this example:

let foo = "foobar".characters

let index = foo.index(foo.startIndex, offsetBy: 3)
let bar = foo.suffix(from: index) // "bar"

foo[index] // "b" :slight_smile:
foo[bar.startIndex] // "f" :frowning:

So does this mean that we can’t assume that collections and their
subsequences share their indices (which could be very handy), or is
this just a bug related to String.CharacterView?

The latter.

···

on Thu Oct 13 2016, Tim Vermeulen <swift-users-AT-swift.org> wrote:

--
-Dave


(Hooman Mehr) #5

`Slice` family of types (there are many) are well documented to share the indices and inherit the semantics. All collections that have a SubSequence of a Slice type, share indices. Unfortunately, standard library is not well documented in general and collection API have undergone big changes in Swift 3.0, so this may not be very clear now.

The problem with `String.CharacterView` is that its SubSequence is not a `Slice` type.

Try this out:

let subSeq1 = "abc".characters.prefix(1)
let subSeq2 = Array("abc".characters).prefix(1)

print(type(of:subSeq1)) // prints CharacterView
print(type(of:subSeq2)) // prints ArraySlice<Character>

Converting `String.CharacterView` to Array<Character> is an expensive operation and will kill the performance of string manipulation, but will work as you expect, since Array is properly sliced.

···

On Oct 13, 2016, at 5:42 PM, Tim Vermeulen <tvermeulen@me.com> wrote:

Alright. Does this mean that we can otherwise assume that collections share indices with their subsequences? It might be worth documenting, one way or the other.

On 14 Oct 2016, at 02:40, Hooman Mehr <hooman@mac.com <mailto:hooman@mac.com>> wrote:

This is a bug reported multiple times in different forms. My version of it is: SR-1487 <https://bugs.swift.org/browse/SR-1487>.

It remains open because it is not easy to fix with the existing design of String. Apparently core standard library team are working on an overhaul of String to address this and other usability and performance issues.

On Oct 13, 2016, at 5:12 PM, Tim Vermeulen via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

Is it a requirement that collections share indices with its subsequence? Array and ArraySlice do share indices, which is why ArraySlice isn’t zero-based, and I think this is convenient. But String.CharacterView doesn’t seem to share indices with its subsequence (which is String.CharacterView as well). Consider this example:

let foo = "foobar".characters

let index = foo.index(foo.startIndex, offsetBy: 3)
let bar = foo.suffix(from: index) // "bar"

foo[index] // "b" :slight_smile:
foo[bar.startIndex] // "f" :frowning:

So does this mean that we can’t assume that collections and their subsequences share their indices (which could be very handy), or is this just a bug related to String.CharacterView?
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users


(Hooman Mehr) #6

Thanks to Ole Begemann (who closed my bug report), I found out that Nate Cook submitted a fix <https://github.com/apple/swift/pull/4896> for this issue a few day ago. The fix will hopefully make it to the next maintenance release of Swift.

The documentation of range subscript (which is the main API for creating subsequences) already specifies that SubSequences (slices) should use the same indices, but I think we need to better document the specifications of SubSequence associated type and make sure that any API that returns a SubSequence links to SubSequence documentation.

···

On Oct 16, 2016, at 3:33 PM, Dave Abrahams via swift-users <swift-users@swift.org> wrote:

on Thu Oct 13 2016, Tim Vermeulen <swift-users-AT-swift.org> wrote:

Is it a requirement that collections share indices with its
subsequence?

Yes.

Array and ArraySlice do share indices, which is why ArraySlice isn’t
zero-based, and I think this is convenient. But String.CharacterView
doesn’t seem to share indices with its subsequence (which is
String.CharacterView as well).

That's a bug.

Consider this example:

let foo = "foobar".characters

let index = foo.index(foo.startIndex, offsetBy: 3)
let bar = foo.suffix(from: index) // "bar"

foo[index] // "b" :slight_smile:
foo[bar.startIndex] // "f" :frowning:

So does this mean that we can’t assume that collections and their
subsequences share their indices (which could be very handy), or is
this just a bug related to String.CharacterView?

The latter.

--
-Dave

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users