Slicing should return Array by default rather than the confusing and error-prone ArraySlice

ArraySlice is confusing and error-prone since indexing doesn't necessarily start at zero and many functions require arrays rather than slices as parameters. ArraySlice is also a form of premature optimization.

IMO, it would be better for slicing to return an Array. If you want more efficiency, you could use an ArraySlice type annotation to get back an ArraySlice much as you would use a Character type annotation if you don't want a string.

1 Like

Previous discussion. :+1:

FWIU golang primary array type is in fact a slice. this makes it a bit weird on some cases, but overall is working pretty fine. What would prevent swift from implementing most array utilities function to make them work over arrayslice as well ?

the non-zero-based indexing is a major problem, but one that should be solved by making slice.startIndex and slice.endIndex practical to use, rather than giving up on ArraySlice altogether. I’ve been thinking about a possible syntax for this

slice[+2] // slice[slice.index(slice.startIndex, offsetBy:  2)]
slice[1-] // slice[slice.index(slice.endIndex,   offsetBy: -1)]

it’s not like anyone uses unary plus right now anyway,, we’re literally wasting a perfectly good operator.

It's even possible to define a subscript that returns regular arrays (starting at index 0) instead of slices - and because Swift not only looks at parameters, but also on the return type of overloaded functions, both can live alongside each other fairly well

extension Array {
    public func suffix(_ maxLength: Int) -> Array<Element> {
        let slice: Array.SubSequence = self.suffix(maxLength)
        return Array(slice)
var array0 = Array(stride(from: 0, to: 16, by: 2))
let test = array0.suffix(3)
print(test.index(of: 10)!) // 0

i think introducing performance traps to solve an ergonomics problem is exactly the wrong way to approach this. we need to think about how we can align our model of how slices should be used with what the syntax encourages us to write.


We've been on this infinite loop before.

Imho this is a only a "conditional trap" - and slices have their own pitfalls:
Besides the possible irritations with the index, a slice can keep the collection it was created from alive, which can lead to a surprising high memory footprint.
Afaics, in most cases it is a bad idea to store a slice in a variable, and using an array instead has no downsides.

What exactly are the problems you see with an overload like public func suffix(_ maxLength: Int) -> Array<Element>?

1 Like

I actually think the other way around, I hate that Data returns Data when sliced instead of a DataSlice which breaks the assumption that Data is a zero-based bytes storage. That said, I‘m super comfortable with the *Slice family.