<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">This is all valuable feedback. I also have a bunch of convenience APIs in</div><div class="">mind but haven't been pushing them yet because:</div><div class=""><br class=""></div><div class="">- the Swift 4 schedule is tight</div><div class=""><br class=""></div><div class="">- I don't want to speculatively add API surface until enough users</div><div class=""> have had experience with the feature. Maybe there are better ideas.</div><div class="">…</div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Mar 23, 2017, at 7:22 PM, Karl Wagner <<a href="mailto:razielim@gmail.com" class="">razielim@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">The convenience initialiser should exist on all of the unsafe buffers, not just the raw (untyped) ones.</div></div></div></blockquote><div><br class=""></div><div>I think it's fair to add the UnsafeBuffer.init(rebasing:) initializer</div><div>as part of this SE-0138 amendment. It's not so much a new API as a</div><div>consistency fix. I’ll update the current proposal.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I’ve run in to this problem a few times, and I think it would get worse if we adopted a ContiguouslyStored protocol to formalise accessing the raw-pointers of generic collections. It would mean that you couldn’t write code that works with UnsafeRawBufferPointer/Data/DispatchData generically, or with UnsafeBufferPointer<T>/Array<T>.<div class=""><br class=""></div><div class="">Also, there seem to be some implicit conversions for the unsafe-pointer types, but UMBP -> UBP requires an awkward initialiser. We should introduce an implicit conversion for that case or add an “immutable” computed property to UMBP.</div></div></div></blockquote><div><br class=""></div><div>UnsafeBufferPointer should have init from mutable. We already had a bug for that.</div><div>Thanks for reminding me: <a href="https://bugs.swift.org/browse/SR-3929" class="">https://bugs.swift.org/browse/SR-3929</a></div><div><br class=""></div><div>I think that needs a new proposal, but it's a trivial addition. I can work on that.</div><div><br class=""></div><div>I agree that implicit conversions would be nice but does merit some</div><div>discussion and involves a bit of type system work. You have to be a</div><div>bit careful with implicit conversion because of potentially ambigous</div><div>overloads. Implicit conversion is primarily for C interop. Eventually</div><div>I do think it would be nice to optionally import some pointer+length</div><div>arguments as UnsafeBuffer. We just don't do it now. Regardless of</div><div>interop, this would also be handy way to pass an inout argument as a</div><div>buffer without wrapping it in a closure.</div><div><br class=""></div><div>Your specific concern seems to be about the mutable -> immutable</div><div>conversion being implicit though. But that just comes down to writing out</div><div>the type name. As bad as the type name is, to me that's not worth an</div><div>evolution proposal at the moment. I suggest filing a bug for any</div><div>implicit conversion issues, or `immutable` property suggestions for now.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">And while we’re on the subject, memory allocation/deallocation functions are weirdly dispersed. In order to allocate an UnsafeMutableBufferPointer<T>, for instance, you have to do:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">var buffer: UnsafeMutableBufferPointer<T></font></div><div class=""><font face="Courier" class="">init(length: Int) {</font></div><div class=""><font face="Courier" class=""> let b = UnsafeMutablePointer<T>.allocate(capacity: length)</font></div><div class=""><font face="Courier" class=""> buffer = UnsafeMutableBufferPointer(start: b, count: length)</font></div><div class=""><font face="Courier" class="">}</font></div></blockquote></div></div></blockquote><div><br class=""></div><div>We've had a bug open on this since introducing raw buffers:</div><div><a href="https://bugs.swift.org/browse/SR-3088" class="">https://bugs.swift.org/browse/SR-3088</a></div><div><br class=""></div><div>This is obvious enough that I can probably sneak it into Swift 4 if I just get around to writing the proposal.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Also, the deallocate API feels weird - since it deallocates n items from the head of the pointer, it is a consuming operation and I feel like it should return a new pointer (with @discardableResult). Once you’ve deallocated a memory address, you can never re-allocate that specific location so there is no reason to know about it any more.</div></div></div></blockquote><div><br class=""></div><div>Now we're outside UnsafeBufferPointer territory.</div><div>UnsafePointer.deallocate(capacity:) needs to be passed the</div><div>same capacity as allocate. If that's confusing, please file a</div><div>documentation bug.</div><div><br class=""></div><div>Or you may be referring to UnsafePointer.deinitialize(count:). That</div><div>returns a raw pointer to the same memory address to indicate that you</div><div>can now initialize the same memory as a different type.</div><div><br class=""></div><div>With move-only types, I think we'll be able to revisit some of the</div><div>pointer initialize/deinitialize API to be more robust.</div><div><br class=""></div><div>-Andy</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">- Karl</div><div class=""><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 21 Mar 2017, at 03:21, Andrew Trick via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">This proposal amends SE-0138: Normalize UnsafeRawBufferPointer Slices<br class="">to fix a design bug: <a href="https://github.com/apple/swift-evolution/pull/651" class="">https://github.com/apple/swift-evolution/pull/651</a><br class=""><br class="">The issue was discussed on swift-evolution in Nov/Dec:<br class="">See [swift-evolution] [Pitch] Normalize Slice Types for Unsafe Buffers<br class=""><a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161128/029108.html" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161128/029108.html</a><br class=""><br class="">The implementation of this fix is in PR #8222:<br class=""><a href="https://github.com/apple/swift/pull/8222" class="">https://github.com/apple/swift/pull/8222</a><br class=""><br class="">Fix: Change Unsafe[Mutable]RawBufferPointer's SubSequence type<br class=""><br class="">Original: Unsafe[Mutable]RawBufferPointer.SubSequence = Unsafe[Mutable]RawBufferPointer<br class=""><br class="">Fixed: Unsafe[Mutable]RawBufferPointer.SubSequence = [Mutable]RandomAccessSlice<Unsafe[Mutable]RawBufferPointer><br class=""><br class="">This is a source breaking bug fix that only applies to<br class="">post-3.0.1. It's extremely unlikely that any Swift 3 code would rely<br class="">on the SubSequence type beyond the simple use case of passing a<br class="">raw buffer subrange to an another raw buffer argument:<br class=""><br class="">`takesRawBuffer(buffer[i..<j])`<br class=""><br class="">A diagnostic message now instructs users to convert the slice to a<br class="">buffer using a `rebasing` initializer:<br class=""><br class="">`takesRawBuffer(UnsafeRawBufferPointer(rebasing: buffer[i..<j]))`<br class=""><br class="">To support this, the following `rebasing` initializers are added:<br class=""><br class="">extension UnsafeRawBufferPointer {<br class=""> public init(rebasing slice: RandomAccessSlice<UnsafeRawBufferPointer>)<br class=""> public init(<br class=""> rebasing slice: MutableRandomAccessSlice<UnsafeMutableRawBufferPointer><br class=""> )<br class="">}<br class=""><br class="">extension UnsafeMutableRawBufferPointer {<br class=""> public init(<br class=""> rebasing slice: MutableRandomAccessSlice<UnsafeMutableRawBufferPointer><br class=""> )<br class="">}<br class=""><br class="">The source compatibility test builds are unnaffected by this change.<br class=""><br class="">-Andy<br class="">_______________________________________________<br class="">swift-evolution mailing list<br class="">swift-evolution@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></body></html>