<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 28, 2017 at 7:59 PM, Andrew Trick <span dir="ltr"><<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><span><br><div><blockquote type="cite"><div>On Sep 6, 2017, at 10:15 PM, Taylor Swift <<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>> wrote:</div><br class="m_-2058615137118872999m_-8059955500785466851Apple-interchange-newline"><div><div dir="ltr">okay so I think so far what’s been agreed on is <br><br><div><b>1</b>. rename “Bytes” to “Memory” in the raw pointer API. Note: this brings the `<span style="font-family:monospace,monospace">copyBytes<C>(from:)</span>` collection method into the scope of this proposal<br></div><div><br></div><b>2</b>. change raw offsets to be in terms of bytes, not typed strides. This argument will be called `<span style="font-family:monospace,monospace">atByteOffset:</span>` and will only appear in <span style="font-family:monospace,monospace">UnsafeMutableRawBufferPointer</span>. “<span style="font-family:monospace,monospace">at:</span>” arguments are no longer needed in <span style="font-family:monospace,monospace">UnsafeMutableRawPointer</span>, since we can just use pointer arithmetic now.<br><div><div><br><br></div><b>3</b>. move <span style="font-family:monospace,monospace">UnsafeMutableBufferPointer</span>’s `<span style="font-family:monospace,monospace">at:</span>` arguments to the front of the parameter list. mostly cause any pointer arithmetic happens in the front so structurally we want to mirror that.</div><div><br></div><div><b>4</b>. add dual (to:) single element initializers and assigners to <span style="font-family:monospace,monospace">UnsafeMutablePointer</span>, but not <span style="font-family:monospace,monospace">UnsafeMutableRawPointer</span> because it’s apparently not useful there. <span style="font-family:monospace,monospace">`UnsafeMutableRawPointer.initi<wbr>alizeMemory<T>(as:</span><span style="font-family:monospace,monospace">repeating:<wbr>count:)</span>` still loses its default count to prevent confusion with its buffer variant.<br></div><div><br></div><div><b>5</b>. memory deallocation on buffer pointers is clearly documented to only be defined behavior when the buffer matches a whole heap block. <br></div></div>
</div></blockquote></div><div><br></div></span>Kelvin,<div><br><div><div>Attempting to limit the scope of this proposal backfired. I was hoping to avoid discussing changes to the slice API, instead providing basic functionality within the buffer API itself. However, Dave Abrahams has argued that once the slice API is extended, the positional arguments are extraneous and less clear.</div><div><br></div><div>Instead of</div><div><br></div><div> buf.intialize(at: i, from: source)</div><div><br></div><div>We want to force a more obvious idiom:</div><div><br></div><div> buf[i..<n].intialize(from: source)</div><div><br></div></div></div></div></blockquote><div><br></div><div>The problem with subscript notation is we currently get the <span style="font-family:monospace,monospace">n</span> argument from the <span style="font-family:monospace,monospace">source</span> argument. So what would really have to be written is <br></div><div><br></div><div><span style="font-family:monospace,monospace">buf[i ..< i + source.count].initialize(from: source) </span><br></div><div><br></div><div>which is a lot more ugly and redundant. One option could be to decouple the count parameter from the length of the source buffer, but that opens up the whole can of worms in which length do we use? What happens if <span style="font-family:monospace,monospace">n - i</span> is less than or longer than <span style="font-family:monospace,monospace">source.count</span>? If we enforce the precondition that <span style="font-family:monospace,monospace">source.count == n - i</span>, then this syntax seems horribly redundant. <br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div><div></div><div>I think this is a reasonable argument and convinced myself that it's possible to extend the slice API. I'm also convinced now that we don't need overloads to handle an UnsafeBufferPointer source, instead we can provide a single generic entry point on both UnsafeMutableBufferPointer and its slice, optimized within the implementation:</div><div><br></div><div> `initialize<S : Sequence>(from: S) -> (S.Iterator, Index)</div><div><br></div><div>We can always drop down to the UnsafePointer API to get back to a direct unsafe implementation as a temporary workaround for performance issues. <br></div></div></div></div></blockquote><div><br></div><div>Using <span style="font-family:monospace,monospace">Sequence</span>s throws out a whole host of assumptions we’ve been taking advantage of. We can’t check for <span style="font-family:monospace,monospace">source.count</span> anymore since that requires traversing the entire <span style="font-family:monospace,monospace">Sequence</span>. And if the performance is so bad relative to the <span style="font-family:monospace,monospace">UnsafePointer</span> API, we have to ask what the purpose of such a buffer API would even be. The whole purpose of the buffer API was to make it easier to do things with pointers without having to keep track of buffer lengths externally. It should be built around the <span style="font-family:monospace,monospace">UnsafePointer</span> API, not the much higher level <span style="font-family:monospace,monospace">Sequence</span> API.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div><div></div><div><br></div><div>Let's set aside for now whether we support full or partial initialization/assignment, how to handle moveInitialize, and whether we need to return the Iterator/Index. This is going to require another iteration on swift-evolution, which <b>we should discuss in a separate thread</b>. </div><div><br></div><div>At this point, I suggest removing the controversial aspects of SE-0184 so that we can put the other changes behind us and focus future discussion around a smaller follow-up proposal.</div><div><br></div><div>Here I've summarized the changes that I think could be accepted as-is:</div><div><a href="https://gist.github.com/atrick/c1ed7afb598e5cc943bdac7683914e3e" target="_blank">https://gist.github.com/atrick<wbr>/c1ed7afb598e5cc943bdac7683914<wbr>e3e</a></div><div><br></div><div>If you amend SE-0184 accordingly and file a new PR, I think it can be quickly approved.</div><div><br></div><div>-Andy</div></div><div><br></div></div></div></blockquote><div><br></div><div>fine with me i guess <br></div></div><br></div></div>