[swift-evolution] [Pitch] Normalize Slice Types for Unsafe Buffers

Kevin Ballard kevin at sb.org
Wed Dec 14 15:52:08 CST 2016


On Fri, Dec 9, 2016, at 11:50 AM, Dave Abrahams via swift-evolution wrote:
> 
> on Fri Dec 09 2016, Andrew Trick <swift-evolution at swift.org> wrote:
> 
> >> On Dec 9, 2016, at 10:27 AM, Dave Abrahams via swift-evolution
> > <swift-evolution at swift.org> wrote:
> >> 
> >> 
> >> on Thu Dec 08 2016, Xiaodi Wu <xiaodi.wu-AT-gmail.com <http://xiaodi.wu-at-gmail.com/>> wrote:
> >> 
> >
> >>> On Thu, Dec 8, 2016 at 6:53 PM, Ben Cohen via swift-evolution <
> >>> swift-evolution at swift.org> wrote:
> >>> 
> >>>> 
> >>>> On Dec 8, 2016, at 4:35 PM, Jordan Rose via swift-evolution <
> >>>> swift-evolution at swift.org> wrote:
> >>>> 
> >>>> Um, Sequence doesn’t have a subscript (or indexes). Sequences are
> >>>> single-pass. So if this is important, it needs to stay a Collection.
> >>>> 
> >>>> 
> >>>> Just because something fulfills one of the requirements of a Collection
> >>>> does not mean it should be one. It needs to tick all the boxes before its
> >>>> allowed to be elevated.
> >>>> 
> >>>> But it’s still allowed to have subscripts (UnsafePointer has subscripting
> >>>> but isn’t a collection) or be multi-pass (strides are multiples but are
> >>>> only sequences). That’s OK
> >>>> 
> >>>> In this case, yes it’s multi-pass, yes it has a subscript, but no it isn’t
> >>>> a collection because it doesn’t meet the requirements for slicing i.e. that
> >>>> indices of the slice be indices of the parent.
> >>>> (relatedly… it appears this requirement is documented on the concrete
> >>>> Slice type rather than on Collection… which is a documentation bug we
> >>>> should fix).
> >>>> 
> >>> 
> >>> If this is indeed a requirement for Collection, then my vote would be for
> >>> Nate's option #1 and Andy's option #2, to give UnsafeRawBufferPointer a
> >>> Slice type that fulfills the requirement. It's the smallest change,
> >>> preserves the use of integer indices, and preserves what Andy stated as the
> >>> desired use case of making it easy for users to switch out code written for
> >>> [UInt8].
> >>> 
> >>> I'm not sure I fully understand yet why Dave finds the idea of Collection
> >>> conformance fishy, 
> >> 
> >> Because the memory can easily be already bound to another type than
> >> UInt8, and there's no obvious reason why UInt8 should be privileged as a
> >> type you can get out of a raw buffer without binding the memory.
> >
> > I strongly disagree with that statement. The overwhelmingly common use
> > case for raw buffers is to view them as a sequence of UInt8 *without*
> > binding the type.  Generally, at the point that you're dealing with a
> > raw buffer it's impossible to (re)bind memory because you don't know
> > what type it holds. 
> 
> Oh, you can't just rebind to UInt8 because that's not defined as
> universally compatible with all data.  OK, sorry.

If you're dealing with raw bytes to begin with then I'd hope you're working with types that can be safely expressed as a collection of bytes. And since this is an unsafe type, I don't think there's any problem with having the possibility of trying to express e.g. [NSObject] as a raw byte buffer.

> > The reason it's so important to have an UnsafeRawBufferPointer data
> > type is precisely so that users don't need mess about with binding
> > memory. It's easy to get that wrong even when it's possible.
> >
> > The only reason that UInt8 is special is that when users create
> > temporary typed buffers for bytes (e.g. they sometimes want a growable
> > array or just don't want to bother with manual allocation) they always
> > use UInt8 as the element type.
> >
> > That said, we could easily divide these concerns into two types as
> > you suggested. A raw buffer, which doesn't have any special UInt8
> > features, and a RawBytes collection that handles both buffer slicing
> > and UInt8 interoperability.
> 
> But, now that I think of it, that wouldn't really solve any problems,
> would it?

Agreed. If we have a separate RawBytes type, then I'm not really sure what the point of UnsafeRawBufferPointer is anymore. The whole point of that type is it's a collection of bytes rather than just being a tuple `(baseAddress: UnsafeRawPointer, count: Int)`.

-Kevin Ballard


More information about the swift-evolution mailing list