Move Foundation.Data in to the standard library

A good example to think about is Range. Ranges are just two bounds, and are a collection when the bounds are countable. Since slicing a range is just a question of adjusting its bounds, it's perfect as a self-slice. It's also a good example of something with a non-zero starting index: a range's index is its bound, and the subscript is the identify function. (-5..<5).startIndex is -5.

Note, ArraySlice mainly still exists because of a need to avoid triggering COW on the underlying array. The hope is that the generalized accessor feature currently in the works would allow us to replace ArraySlice with a plain ol' regular Slice<Array>, along with some conditional conformances for things like withUnsafeBufferPointer etc.

1 Like

I would love to see a straightforward, safe, owned buffer pointer API added to the standard library. It would be easy to build that on top of UnsafeBufferPointer, or UnsafeRawBufferPointer if you're interested in reusing the same memory for distinct data types.

In its current form, I'm strongly opposed to including Foundation.Data in the Swift standard library. It needs to go through API review first. The current API doesn't fit with the standard library's Unsafe APIs, and it fundamentally violates type safety and bounds checking. I can accept some of this as a compatibility layer, but I don't want such a striking counterexample of Swift good practice in the standard library itself. It contradicts the language goals of security and undermines the strong stance that we've taken against undefined behavior.

These were my initial recommendations for fixing the Data API with minimal changes, back in 2016:
https://github.com/atrick/swift/commit/796b08fa5635a7d61cbb6bf0718178e0ce326e4f

I was led to believe the entire API would go through a redesign, so I eventually parked these issues in JIRA:

If there isn't going to be a larger redesign, then I think the changes outlined in the bug are, roughly speaking, the minimal prerequisite for promoting Data into the standard library.

12 Likes

In fact, that's a general requirement. For any Sequence's SubSequence, that sub-sequence must be its own sub-sequence; using a separate type for slices must not be turtles all the way down, but at most one level deep (i.e. not a distinct sub-sub-sequence type).

Is this documented somewhere?

It's now a requirement on the associated type

associatedtype SubSequence : Sequence = AnySequence<Self.Element> where Self.SubSequence == Self.SubSequence.SubSequence

which makes subsequences much less annoying to deal with.

1 Like