<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 29, 2017 at 6:17 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><div><div class="gmail-m_5121526513827288420gmail-h5"><br><div><br><blockquote type="cite"><div>On Sep 29, 2017, at 4:03 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>&gt; wrote:</div><br class="gmail-m_5121526513827288420gmail-m_-6613431841721747590Apple-interchange-newline"><div><div dir="auto"><div><br></div><div><br>On Sep 29, 2017, at 5:56 PM, Dave Abrahams &lt;<a href="mailto:dabrahams@apple.com" target="_blank">dabrahams@apple.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><br><div><br><blockquote type="cite"><div>On Sep 29, 2017, at 3:48 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>&gt; wrote:</div><br class="gmail-m_5121526513827288420gmail-m_-6613431841721747590Apple-interchange-newline"><div><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 29, 2017 at 4:13 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><span><br><div><br><blockquote type="cite"><div>On Sep 29, 2017, at 1:23 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>&gt; wrote:</div><br class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-interchange-newline"><div><blockquote 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;margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div><div>Instead of</div><div><br></div><div> <span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span>buf.intialize(at: i, from: source)</div><div><br></div><div>We want to force a more obvious idiom:</div><div><br></div><div> <span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span>buf[i..&lt;n].intialize(from: source)</div><div><br></div></div></div></div></blockquote><div 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></div><div 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 problem with subscript notation is we currently get the<span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span><span style="font-family:monospace,monospace">n</span><span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span>argument from the<span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span><span style="font-family:monospace,monospace">source</span><span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span>argument. So what would really have to be written is<span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span><br></div><div 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></div><div 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"><span style="font-family:monospace,monospace">buf[i ..&lt; i + source.count].initialize(from: source)<span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span></span><br></div><div 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></div><div 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">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 class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span><span style="font-family:monospace,monospace">n - i</span><span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span>is less than or longer than<span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span><span style="font-family:monospace,monospace">source.count</span>? If we enforce the precondition that<span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span><span style="font-family:monospace,monospace">source.count == n - i</span>, then this syntax seems horribly redundant.<span class="gmail-m_5121526513827288420gmail-m_-6613431841721747590m_1404466990729912635Apple-converted-space"> </span></div></div></blockquote></div><br></span><div>Sorry, a better analogy would have been:</div><div><br></div><div><div><div><div><div> buf[i...].intialize(from: source)</div><div><br></div><div>Whether you specify the slice’s end point depends on whether you want to completely initialize that slice or whether you’re just filling up as much of the buffer as you can. It also depends on whether `source` is also a buffer (of known size) or some arbitrary Sequence.</div><div><br></div><div>Otherwise, point  taken.</div><div><br></div><div>-Andy</div></div></div></div></div></div></blockquote><div><br></div><div>After thinking about this more, one-sided ranges might provide just the expressivity we need. What if:</div><div><br></div><div><span style="font-family:monospace,monospace"> buf[offset...].initialize(from<wbr>: source) // initializes source.count elements from source starting from offset</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">buf[offset ..&lt; endIndex].initialize(from: source) // initializes up to source.count elements from source starting from offset<br></span></div><div><br></div><div><br></div></div>The one sided one does not give a full initialization guarantee. The two sided one guarantees the entire segment is initialized. </div></div></div></blockquote><div><br></div><div>In every other context, x[i...] is equivalent to x[i..&lt;x.endIndex]</div><div><br></div><div>I don&#39;t think breaking that precedent is a good idea.</div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra">For move operations, the one sided one will fully deinitialize the source buffer while the two sided one will only deinitialize <span style="font-family:monospace,monospace">endIndex - offset</span> elements. <br></div></div>
</div></blockquote></div><br><div>
—<br>-Dave<br></div></div></blockquote><br><div>well since people want to use subscript notation so much we need some way of expressing case 1. writing both bounds in the subscript seems to imply a full initialization (and thus partial movement) guarantee.</div></div></div></blockquote><br></div></div></div><div>Presumably, in your use case, you’re working directly with buffers on both sides (please point us to the real code). With the slicing approach, that would be done as follows:</div><div><br></div><div>bufA[i ..&lt; i + bufB.count].initialize(from: bufB)</div><div><br></div><div>That will enforce full initialization of the slice: precondition(self.count == source.count).</div><div><br></div><div>Your point stands that it is redundant. That point will need to be weighed against other points, which I think should be discussed in another thread.</div><div><br></div><div>-Andy</div></div></blockquote><div><br></div><div>To this and your other method about the real library code; right now the PNG library doesn’t use buffer methods (since they don’t exist yet) and pixels are plain-old-data so i’m not using the memory state API there anyway (the original proposal didn’t even have anything to do with those APIs actually). However I did take a few minutes to write a quick <a href="https://gist.github.com/kelvin13/0860334278aeab5c1cbaefbefb050268#file-dequeue-swift">queue implementation</a> in Swift which does not make any assumptions about the Element type. I then rewrote it using the hypothetical buffer API I proposed, and then the hypothetical buffer API using subscript notation. <br></div><div><br></div><div><br></div><div><br></div><div><b>These are the relevant function calls using the current API (the rest of the code has been stripped out)</b><br></div><div><br><span style="font-family:monospace,monospace">        newBuffer:</span><wbr><span style="font-family:monospace,monospace">UnsafeMutablePointer&lt;Element&gt; = <br>                    UnsafeMutablePointer&lt;Element&gt;.</span><wbr><span style="font-family:monospace,monospace">allocate(capacity: newCapacity)<br>            <br><span style="background-color:rgb(255,242,204)">        newBuffer              .moveInitialize( from:  buffer + self.zero, <br>                              </span></span><wbr><span style="background-color:rgb(255,242,204)"><span style="font-family:monospace,monospace">                          count: self.capacity - self.zero)<br>        (newBuffer + self.zero).moveInitialize( from:  buffer, <br>                              </span></span><wbr><span style="font-family:monospace,monospace"><span style="background-color:rgb(255,242,204)">                          count: self.zero)</span><br>        buffer.deallocate(capacity: self.capacity)<br><br>        (self.buffer! + self.bufferPosition(of: self.count)).initialize(to: data) <br><br>        let dequeued:Element = (self.buffer! + self.zero).move()</span></div><div><br></div><div><b>These are the function calls using the SE 184 API </b><br></div><div><br></div><div><span style="font-family:monospace,monospace">        newBuffer:UnsafeMutableBufferPointer&lt;Element&gt; = <br>                    UnsafeMutableBufferPointer&lt;Element&gt;.allocate(capacity: newCapacity)<br>            <br><span style="background-color:rgb(255,242,204)">        newBuffer.moveInitialize(at: 0,         from: self.buffer[self.zero...   ])</span></span></div><div><span style="background-color:rgb(255,242,204)"><span style="font-family:monospace,monospace">        newBuffer.moveInitialize(at: self.zero, from: self.buffer[0 ..&lt; self.zero])</span></span></div><div><span style="font-family:monospace,monospace">        self.buffer.deallocate()</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">        (self.buffer.baseAddress! + self.bufferPosition(of: self.count)).initialize(to: data) <br><br>        let dequeued:Element = (self.buffer! + self.zero).move()</span></div><div><br></div></div></div><div class="gmail_extra"><b>And with the proposed subscript notation</b></div><div class="gmail_extra"><br></div><div class="gmail_extra"><span style="font-family:monospace,monospace">        newBuffer:UnsafeMutableBufferPointer&lt;Element&gt; = <br>                    UnsafeMutableBufferPointer&lt;Element&gt;.allocate(capacity: newCapacity)<br>            <br><span style="background-color:rgb(255,242,204)">        newBuffer[0...                        ].moveInitialize(from: self.buffer[self.zero...   ])<br>        newBuffer[self.zero ... self.zero &lt;&lt; 1].moveInitialize(from: self.buffer[0 ..&lt; self.zero])</span><br>        self.buffer.deallocate()<br>        <br>        (self.buffer.baseAddress! + self.bufferPosition(of: self.count)).initialize(to: data) <br><br>        let dequeued:Element = (self.buffer! + self.zero).move()</span></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">I took out the rebasing calls since apparently we’re bringing slices into the scope of this proposal.<br></div></div>