<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 Dec 19, 2015, at 8:52 PM, Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">


<title class=""></title>

<div class=""><div class="">On Fri, Dec 18, 2015, at 02:39 PM, Dave Abrahams via swift-evolution wrote:<br class=""></div>
<blockquote type="cite" class=""><div class="">&nbsp;</div>
<div class="">Yes, we already have facilities to do most of what Python can do here, but one major problem IMO is that the “language” of slicing is so non-uniform: we have [a..&lt;b], dropFirst, dropLast, prefix, and suffix. &nbsp;Introducing “$” for this purpose could make it all hang together<span class="font" style="font-family:AvenirNext-Regular">&nbsp;and also eliminate the “why does it have to be so hard to look at the 2nd character of a string?!” problem. &nbsp;That is, use the identifier “$” (yes, that’s an identifier in Swift) to denote the beginning-or-end of a collection. &nbsp;Thus,</span><br class=""></div>
<div class=""><div style="font-family:AvenirNext-Regular;" class="">&nbsp;</div>
<div style="font-family:AvenirNext-Regular;" class=""><span class="font" style="font-family:Menlo">&nbsp; c[c.startIndex.advancedBy(3)] =&gt;<span style="white-space:pre;" class=""></span>c[$+3] &nbsp; &nbsp; &nbsp; &nbsp;// Python: c[3]</span><br class=""></div>
<div style="font-family:AvenirNext-Regular;" class=""><div class=""><span class="font" style="font-family:Menlo">&nbsp; c[c.endIndex.advancedBy(-3)] =&gt;<span style="white-space:pre;" class=""></span>c[$-3] &nbsp; &nbsp; &nbsp; &nbsp;// Python: c[-3]</span><br class=""></div>
<div class="">&nbsp;</div>
<div class=""><span class="font" style="font-family:Menlo">&nbsp; c.dropFirst(3) &nbsp;=&gt;</span><span class="font" style="font-family:Menlo"></span><span class="font" style="font-family:Menlo">c[$+3...] &nbsp; &nbsp; // Python: c[3:]</span><br class=""></div>
</div>
<div style="font-family:AvenirNext-Regular;" class=""><span class="font" style="font-family:Menlo">&nbsp; c.dropLast(3) =&gt;<span style="white-space:pre;" class=""></span>c[..&lt;$-3] &nbsp; &nbsp; // Python: c[:-3]</span><br class=""></div>
<div style="font-family:AvenirNext-Regular;" class=""><span class="font" style="font-family:Menlo">&nbsp; c.prefix(3) =&gt;<span style="white-space:pre;" class=""></span>c[..&lt;$+3] &nbsp; &nbsp; // Python: c[:3]</span><br class=""></div>
<div style="font-family:AvenirNext-Regular;" class=""><span class="font" style="font-family:Menlo">&nbsp; c.suffix(3) =&gt;&nbsp;<span style="white-space:pre;" class=""></span>c[$-3...] &nbsp; &nbsp; // Python: c[-3:]</span><br class=""></div>
<div style="font-family:AvenirNext-Regular;" class="">&nbsp;</div>
</div>
<div class=""><span class="font" style="font-family:AvenirNext-Regular">It even has the nice connotation that, “this might be a little more expen</span><span class="font" style="font-family:Menlo">$</span><span class="font" style="font-family:AvenirNext-Regular">ive than plain indexing” (which it might, for non-random-access collections). &nbsp;</span>I think the syntax is still a bit heavy, not least because of “..&lt;“ and “...”, but the direction has potential.&nbsp;<br class=""></div>
<div class="">&nbsp;</div>
<div class="">&nbsp;I haven’t had the time to really experiment with a design like this; the community might be able to help by prototyping and using some alternatives. &nbsp;You can do all of this outside the standard library with extensions.<br class=""></div>
</blockquote><div class="">&nbsp;</div>
<div class="">Interesting idea.<br class=""></div>
<div class="">&nbsp;</div>
<div class="">One downside is it masks potentially O(N) operations (ForwardIndex.advancedBy()) behind the + operator, which is typically assumed to be an O(1) operation. </div></div></div></blockquote><div><br class=""></div><div>Yeah, but the “$” is sufficiently unusual that it doesn’t bother me too much.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="">Alos, the $+3 syntax suggests that it requires there to be at least 3 elements in the sequence, but prefix()/suffix()/dropFirst/etc. all take maximum counts, so they operate on sequences of fewer elements.<br class=""></div></div></div></blockquote><div><br class=""></div>For indexing, $+3 would make that requirement. &nbsp;For slicing, it wouldn’t. &nbsp;I’m not sure why you say something about the <u class="">syntax</u> suggests exceeding bounds would be an error.</div><div><br class=""><blockquote type="cite" class=""><div class="">

<div class="">There's also some confusion with using $ for both start and end. What if I say c[$..&lt;$]? We'd have to infer from position that the first $ is the start and the second $ is the end, but then what about c[$+n..&lt;$+m]? We can't treat the usage of + as meaning "from start" because the argument might be negative. And if we use the overall sign of the operation/argument together, then the expression `$+n` could mean from start or from end, which comes right back to the problem with Python syntax.</div></div></blockquote><div><br class=""></div><div>There’s a problem with Python syntax? &nbsp;I’m guessing you mean that c[a:b] can have very different interpretations depending on whether a and b are positive or negative?</div><div><br class=""></div><div>First of all, I should say: that doesn’t really bother me. &nbsp;The 99.9% use case for this operation uses literal constants for the offsets, and I haven’t heard of it causing confusion for Python programmers. &nbsp;That said, if we wanted to address it, we could easily require n and m above to be literals, rather than Ints (which incidentally guarantees it’s an O(1) operation). &nbsp;That has upsides and downsides of course.</div></div><div><blockquote type="cite" class=""><div class=""><div class="">&nbsp;</div>
<div class="">I think Jacob's idea has some promise though:</div>
<div class="">&nbsp;</div>
<div class="">c[c.startIndex.advancedBy(3)] =&gt; c[fromStart: 3]<br class=""></div>
<div class="">c[c.endIndex.advancedBy(-3)] =&gt; c[fromEnd: 3]</div></div></blockquote><div><br class=""></div><blockquote type="cite" class=""><div class="">
<div class="">But naming the slice operations is a little trickier. We could actually just go ahead and re-use the existing method names for those:</div>
<div class="">&nbsp;</div>
<div class="">c.dropFirst(3) =&gt; c[dropFirst: 3]<br class=""></div>
<div class="">c.dropLast(3) =&gt; c[dropLast: 3]<br class=""></div>
<div class="">c.prefix(3) =&gt; c[prefix: 3]<br class=""></div>
<div class="">c.suffix(3) =&gt; c[suffix: 3]<br class=""></div>
<div class="">&nbsp;</div>
<div class="">That's not so compelling, since we already have the methods, but I suppose it makes sense if you want to try and make all slice-producing methods use subscript syntax (which I have mixed feelings about). </div></div></blockquote><div><br class=""></div><div>Once we get efficient in-place slice mutation (via slice addressors), it becomes a lot more compelling, IMO. &nbsp;But I still don’t find the naming terribly clear, and I don’t love that one needs to combine two subscript operations in order to drop the first and last element or take just elements 3..&lt;5.</div><div><br class=""></div><div>Even if we need separate symbols for “start” and “end” (e.g. using “$” for both might just be too confusing for people in the end, even if it works otherwise), I still think a generalized form that allows ranges to be used everywhere for slicing is going to be much easier to understand than this hodgepodge of words we use today.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div class="">But the [fromStart:] and [fromEnd:] subscripts seem useful.</div></div></blockquote><br class=""></div><div>Yeah… I really want a unified solution that covers slicing as well as offset indexing.</div><div><br class=""></div><div class="">
-Dave<div class=""><br class=""></div><br class="Apple-interchange-newline">

</div>
<br class=""></body></html>