<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 19, 2017, at 6:16 PM, Taylor Swift <<a href="mailto:kelvin13ma@gmail.com" class="">kelvin13ma@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">What you’re describing is basically an earlier version of the proposal which had a slightly weaker precondition (source >= destination) than yours (source == destination). That one basically ignored the Sequence methods at the expense of greater API surface area.<br class=""></div></div></blockquote><div><br class=""></div><div>The Sequence methods don’t provide the simpler, more convenient form of initialization/deinitialization that I thought you wanted. I see two reasonable options.</div><div><br class=""></div><div>1. Don’t provide any new buffer initialization/deinitialization convenience. i.e. drop UsafeMutableBufferPointer moveInitialize, moveAssign, and deinitialize from your proposal.</div><div><br class=""></div><div>2. Provide the full set of convenience methods: initialize, assign, moveInitialize, and moveAssign assuming self.count==source.count. And provide deinitialize() to be used only in conjunction with those new initializers.</div><div><br class=""></div><div>The question is really whether those new methods are going to significantly simplify your code. If not, #1 is the conservative choice. Don't provide convenience which could be misused. Put off solving that problem until we can design a new move-only buffer type that tracks partially initialized state.</div><div><br class=""></div><div>-Andy </div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_extra"><div class="gmail_quote">On Sat, Aug 19, 2017 at 9:08 PM, Andrew Trick <span dir="ltr" class=""><<a href="mailto:atrick@apple.com" target="_blank" class="">atrick@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class="h5"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Aug 19, 2017, at 6:03 PM, Taylor Swift <<a href="mailto:kelvin13ma@gmail.com" target="_blank" class="">kelvin13ma@gmail.com</a>> wrote:</div><br class="m_3005726242190826242Apple-interchange-newline"><div class=""><div class="gmail_extra" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br class="m_3005726242190826242Apple-interchange-newline"><br class=""><div class="gmail_quote">On Sat, Aug 19, 2017 at 8:52 PM, Andrew Trick<span class="m_3005726242190826242Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:atrick@apple.com" target="_blank" class="">atrick@apple.com</a>></span><span class="m_3005726242190826242Apple-converted-space"> </span>wrote<wbr class="">:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div class=""><span class="m_3005726242190826242gmail-"><div class=""><blockquote type="cite" class=""><div class=""><div class="gmail_extra" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div class=""><span class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class=""><br class=""></div><div class="">The problem is I would expect to be able to safely call deinitialize() and friends after calling initialize(from:). If Element is a class type and initialize doesn’t fill the entire buffer range, calling deinitialize() will crash. That being said, since copy(from:bytes:) and copyBytes(from:) don’t do any initialization and have no direct counterparts in UnsafeMutableBufferPointer, it’s okay if they have different behavior than the other methods.</div></div></div></blockquote><br class=""></div></span><div class=""><div class="">You astutely pointed out that the UnsafeMutableBufferPointer.dei<wbr class="">nitialize() method is dangerous, and I asked you to add a warning to its comments. However, given the danger, I think we need to justify adding the method to begin with. Are there real use cases that greatly benefit from it?</div></div></div></blockquote></div></div><div class="gmail_extra" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br class=""></div><div class="gmail_extra" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">I agree that’s a problem, which is why i was iffy on supporting partial initialization to begin with. The use case is for things like growing collections where you have to periodically move to larger storage. However, deinitialize is no more dangerous than moveInitialize, assign(repeating:count:), or moveAssign; they all deinitialize at least one entire buffer. If deinitialize is to be omitted, so must a majority of the unsafe pointer API.</div></div></blockquote></div><br class=""></span><div class=""><div class="">Here's an alternative. Impose the precondition(source.count == self.count) to the following UnsafeMutableBufferPointer convenience methods that you propose adding:</div><div class=""><br class=""></div><div class="">+++ func assign(from:UnsafeBufferPointe<wbr class="">r<Element>)</div><div class="">+++ func assign(from:UnsafeMutableBuffe<wbr class="">rPointer<Element>)</div><div class="">+++ func moveAssign(from:UnsafeMutableB<wbr class="">ufferPointer<Element>)</div><div class="">+++ func moveInitialize(from:UnsafeMuta<wbr class="">bleBufferPointer<Element>)</div><div class="">+++ func initialize(from:UnsafeBufferPo<wbr class="">inter<Element>)</div><div class="">+++ func initialize(from:UnsafeMutableB<wbr class="">ufferPointer<Element>)</div><div class=""><br class=""></div><div class="">I don't that introduces any behavior that is inconsistent with other methods. `copyBytes` is a totally different thing that only works on trivial types. The currently dominant use case for UnsafeBufferPointer, partially initialized backing store, does not need to use your new convenience methods. It can continue dropping down to pointer+count style initialization/deinitializatio<wbr class="">n.</div></div><div class=""><br class=""></div><div class="">-Andy</div></div></blockquote><div class=""> </div></div></div><div class="gmail_extra" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">the latest draft does not have<span class="m_3005726242190826242Apple-converted-space"> </span><span style="font-family:monospace,monospace" class="">assign(from:</span><span style="font-family:monospace,monospace" class="">UnsafeMutable<wbr class="">BufferPointer<</span><span style="font-family:monospace,monospace" class="">Element>)</span><span class="m_3005726242190826242Apple-converted-space"> </span>or <span class="m_3005726242190826242Apple-converted-space"> </span><span style="font-family:monospace,monospace" class="">in<wbr class="">itialize(from:</span><span style="font-family:monospace,monospace" class="">UnsafeMutableBuf<wbr class="">ferPointer<</span><span style="font-family:monospace,monospace" class="">Element>)</span>, it uses the generic Sequence methods that are already there that do not require that precondition.</div></div></blockquote></div><br class=""></div></div><div class=""><div class="">Sorry, I was pasting from your original proposal. Here are the relevant methods from the latest draft:</div><div class=""><br class=""></div><div class=""><a href="https://github.com/kelvin13/swift-evolution/blob/1b7738513c00388b8de3b09769eab773539be386/proposals/0184-improved-pointers.md" target="_blank" class="">https://github.com/kelvin13/<wbr class="">swift-evolution/blob/<wbr class="">1b7738513c00388b8de3b09769eab7<wbr class="">73539be386/proposals/0184-<wbr class="">improved-pointers.md</a></div><span class=""><div class=""><br class=""></div><div class="">+++ func moveInitialize(from:<wbr class="">UnsafeMutableBufferPointer<<wbr class="">Element>)</div></span><div class="">+++ func moveAssign(from:<wbr class="">UnsafeMutableBufferPointer<<wbr class="">Element>)</div><div class=""><br class=""></div><div class="">But with the precondition, the `assign` method could be reasonably added back, right?</div><span class=""><div class="">+++ func assign(from:<wbr class="">UnsafeMutableBufferPointer<<wbr class="">Element>)</div><div class=""><br class=""></div></span><div class="">Likewise, I don’t have a problem with initialize(from: UnsafeBufferPointer) where self.count==source.count. The Sequence initializer is different. It’s designed for the Array use case and forces the caller to deal with partial initialization. </div><div class=""><br class=""></div><div class="">UnsafeMutableRawBufferPointer.<wbr class="">moveInitializeMemory on the other hand probably doesn't need that precondition since there's no way to deinitialize. It just needs clear comments.</div><div class=""><br class=""></div><div class="">-Andy</div></div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>