> On Nov 30, 2016, at 6:15 PM, Dave Abrahams via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> on Wed Nov 30 2016, Kevin Ballard <swift-evolution@swift.org 
> <mailto:swift-evolution@swift.org>> wrote:
> 
>> This sounds like a sensible idea. But there is one behavioral change you
>> haven't addressed, which is that this changes how indexes work on the
>> slice. With all other slice types that come to mind, the slice shares
>> the same indexes as the base, e.g.
>> 
>>  let ary = Array(0..<10)
>> 
>>  print(ary[3]) // prints 3
>> 
>>  print(ary[2..<5][3]) // still prints 3
> 
> This is an important invariant that we need to maintain.
> 
>> UnsafeBufferPointer is indexed using 0-based integers, so with your
>> proposal, slicing an UnsafeBufferPointer produces a value that uses
>> different indexes. We could solve this by adding a new field, but that
>> would break the expectation that startIndex is always zero. 
> 
> I'm not sure that's an expectation we're obligated to honor.  Of course,
> once you get into “unsafe” territory like this, breaking even the
> expectations that aren't based on documented guarantees can be really
> dangerous.
> 
> We probably ought to have wrapped those integers in some Index type
> specific to UnsafeBufferPointer, so zero wasn't even a value.
> 
>> But we can't just ignore this problem, because algorithms that are
>> designed around collections may assume that slices preserve indexes.
>> 
>> In addition, since you point out that UnsafeRawBufferPointer is already
>> its own subsequence, and that type also guarantees that startIndex is
>> always zero, it sounds like we already have an instance of this problem
>> in the stdlib, and so this needs to be addressed with
>> UnsafeRawBufferPointer as well.
> 
> Sounds like it!

Argh, thanks to Kevin for pointing all this out!

I can see at least three approaches to resolving the inconsistency between the 
two sets of buffer types and correcting index sharing for raw buffer pointers.

1) Switch to using Slice as a wrapper for UnsafeRawBufferPointer.
2) Make all buffer pointers their own slices, keeping integer-based indices, 
but remove the zero-based index expectation. With this we'd need to add an 
additional stored property to keep track of the relative offset from the 
"original" buffer.
3) Make all buffer pointers their own slices but use a different index type. If 
the indices were just wrapped pointers, that would handle the index sharing 
without needing an additional property on the buffer. We could also maintain 
integer-based stridable conformance (which greatly simplifies index 
arithmetic), since the indices would just offset by a byte for raw buffers or a 
stride for typed buffers.

The first option would certainly be the smallest change; the third seems like 
it would do the most good, for the reasons Dave laid out. I've tried the third 
option out here for raw buffers:
        
https://github.com/apple/swift/compare/master...natecook1000:nc-buffer-indices

Thanks!
Nate


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

Reply via email to