<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 8, 2017 at 7:53 PM, Andrew Trick <span dir="ltr">&lt;<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><span class="gmail-"><br><div><blockquote type="cite"><div>On Aug 8, 2017, at 9:52 AM, Taylor Swift via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="gmail-m_-4271691199891306538Apple-interchange-newline"><div><div dir="ltr">Since Swift 5 just got opened up for proposals, SE-184 Improved Pointers is ready for community review, and I encourage everyone to look it over and provide feedback. Thank you!<br>&lt;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0184-improved-pointers.md" target="_blank">https://github.com/apple/<wbr>swift-evolution/blob/master/<wbr>proposals/0184-improved-<wbr>pointers.md</a>&gt;<br></div></div></blockquote></div><div><br></div></span><div><div>Excellent. Thanks for patiently iterating on this. I know it&#39;s time consuming.</div><div><br></div><div>&gt; This differs from the previous draft of this proposal, in that this</div><div>&gt; expansion is more additive and less source-breaking, preserving the</div><div>&gt; much of the sized API present on UnsafeMutablePointer.</div><div><br></div><div>Yay!</div><div><br></div><div>&gt; For the binary operations assign(from:), moveAssign(from:),</div><div>&gt; moveInitialize(from:), and initialize(from:), it is assumed that the</div><div>&gt; other buffer pointer contains at least as many elements as self does.</div><div><br></div><div>Uh-oh! This should be consistent with</div><div>UnsafeRawBufferPointer.copy(<wbr>from:bytes:) (the raw version of</div><div>assign/initialize(from:)). There we assume no data is dropped and</div><div>allow an uninitalized buffer tail. What was your rationale for the</div><div>opposite choice and how can we reconcile these APIs?</div></div></div></blockquote><div><br></div><div>The rationale was simply that it’s not straightforward to “finish” initializing a partially initialized buffer since we don’t have <span style="font-family:monospace,monospace">UnsafeMutablePointer</span> memory initializers that work on offsets from the base address, so we might as well assume that anyone using it is initializing the whole buffer in one go. This isn’t really that strong a rationale and I’m open to switching it to be consistent with <span style="font-family:monospace,monospace">UnsafeRawBufferPointer.copy(from:bytes:)</span>.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div><div><br></div><div>&gt; add a default value of 1 to all size parameters on</div><div>&gt; UnsafeMutablePointer and applicable size parameters on</div><div>&gt; UnsafeMutableRawPointer</div><div><br></div><div>I&#39;m generally ok with this if you have seen the benefit of it in real</div><div>code. However, I do not think any `repeating:` methods should have a</div><div>default count.</div></div></div></blockquote><div><br></div><div>Actually, i believe <span style="font-family:monospace,monospace">initialize(to:count:)</span> is currently the one method that already <i>has</i> a default count. That’s probably because the standard library calls this method with a count argument of 1 more than any other memorystate method. I don’t know if this decision was only made for the sake of the stdlib or if it had an API justification.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div><div><br></div><div>&gt; avoids the contradictory and inconsistent use of count to represent a byte quantity</div><div><br></div><div>Background: Whether you consider an API consistent depends on how you</div><div>prioritize the guidelines. Here you&#39;ve taken guidelines that I started</div><div>to use for new raw pointer APIs and given them higher priority than</div><div>other guidelines, in this case having the `count` initializer label match</div><div>the name of the public property being initialized. I think your change</div><div>is an improvement, but there was nothing accidental about the previous</div><div>API.</div><div><br></div><div>&gt; UnsafeMutableRawBufferPointer.<wbr>allocate(bytes:alignedTo:)</div><div><br></div><div>Well, I think it&#39;s somewhat ridiculous for users to write this every time they allocate a buffer:</div><div><br></div><div>`<wbr>UnsafeMutableRawBufferPointer.<wbr>allocate(bytes: size, alignedTo: MemoryLayout&lt;UInt&gt;.alignment)`</div><div><br></div><div>If anyone reading the code is unsure about the Swift API&#39;s alignment</div><div>guarantee, it&#39;s trivial to check the API docs.</div><div><br></div><div>You could introduce a clearly documented default `alignedTo`</div><div>argument. The reason I didn&#39;t do that is that the runtime won&#39;t</div><div>respect it anyway. But I think it would be fair to go ahead with the</div><div>API and file a bug against the runtime.</div></div></div></blockquote><div><br></div><div>Default argument of <span style="font-family:monospace,monospace">MemoryLayout&lt;Int&gt;.alignment</span> is the way to go but as you said i don’t know if that is actually allowed/works. An alternative is to have two allocate methods each, one that takes an alignment argument and one that doesn’t (and aligns to pointer alignment) but that feels inelegant. Default arguments would be better.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div><div><br></div><div>&gt; and initializeMemory&lt;Element&gt;(as:<wbr>at:repeating:count:),</div><div>&gt; initializeMemory&lt;Element&gt;(as:<wbr>from:count:)</div><div>&gt; moveInitializeMemory&lt;Element&gt;(<wbr>as:from:count:), and</div><div>&gt; bindMemory&lt;Element&gt;(to:count:) to UnsafeMutableRawBufferPointer</div><div><br></div><div>I think you should move the raw pointer changes to a separate bullet point.</div><div><br></div><div>Presumably the raw buffer capacity must match or exceed count * stride?</div><div><br></div><div>-Andy</div></div></div></blockquote><div><br></div><div>The reason the raw buffer pointers don’t fill in their own size is the destination type might not line up with the raw buffer size, and then there’s questions of rounding and whatnot. <span style="font-family:monospace,monospace">bindMemory(to:count:)</span> would also have to perform integer division or some other defined behavior. Though if people think computing the strided count inside the buffer pointer method is the right way to go, I’m open to that.<br></div></div><br></div></div>