<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">On 03.01.18 01:19, Karl Wagner via
swift-dev wrote:<br>
</div>
<blockquote type="cite"
cite="mid:1C4683DA-7FE1-400B-9AA4-05493193A26D@gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Swift used to do this, but we switched it around so indexes
couldn’t self-increment.
<div class=""><br class="">
</div>
<div class="">
<div>One of the problems was that strings are value-types. So
you would get an index, then append stuff to the string, but
when you tried to advance the index again it would blow up.
The index retained the backing, which means the “append”
caused a copy, and the index was suddenly pointing to a
different String backing.</div>
<div><br class="">
</div>
<div>Basically, self-incrementing indexes require that the
Collection has reference semantics. Otherwise there simply is
no concept of an independent “owning” Collection which your
Index can hold a reference to.</div>
<div><br class="">
</div>
<div>Anyway, that doesn’t mean you’re wrong. Collection-slicing
syntax is still way too ugly. We need to keep it safe, and
communicative, but it should also be obvious and not tiring.</div>
<div><br class="">
</div>
<div>Currently, you have to write:</div>
<div><br class="">
</div>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">
<div class="">
<div><font class="" face="Courier"><collection>[<collection>.index(<collection>.<member>,
offsetBy: <distance>)]</font></div>
</div>
<div><font class="" face="Courier"><br class="">
</font></div>
</blockquote>
And an example...<br class="">
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">
<div><font class="" face="Courier"><br class="">
</font></div>
<div><font class="" face="Courier">results[results.index(results.startIndex,
offsetBy: 3)]</font></div>
</blockquote>
<div class="">
<div><br class="">
</div>
<div>Which is safe, and communicative, and obvious, but also
really, really tiring. There are ways we can make it less
tiring without sacrificing the good parts:</div>
<div><br class="">
</div>
<div>1) Add a version of index(_: offsetBy:) which takes a
KeyPath<Self, Self.Index> as its first argument. That’s
a minor convenience you can add today in your own projects. It
removes one repetition of <collection>, in many common
cases.</div>
</div>
<div><br class="">
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">
<div><font class="" face="Courier">extension Collection {</font></div>
<div><font class="" face="Courier"> func index(_ i: KeyPath<Self, Index>,
offsetBy n: IndexDistance) -> Index {</font></div>
<div><font class="" face="Courier">
return index(self[keyPath: i], offsetBy: n)</font></div>
<div><font class="" face="Courier"> }</font></div>
<div><font class="" face="Courier"> func index(_ i: KeyPath<Self, Index>,
offsetBy n: IndexDistance, limitedBy: Index) -> Index? {</font></div>
<div><font class="" face="Courier">
return index(self[keyPath: i], offsetBy: n, limitedBy:
limitedBy)</font></div>
<div><font class="" face="Courier"> }</font></div>
<div><font class="" face="Courier">}</font></div>
</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">
<div><br class="">
</div>
</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">
<div class="">
<div><font class="" face="Courier">results[results.index(\.startIndex,
offsetBy: 3)]</font></div>
</div>
<div><font class="" face="Courier"><br class="">
</font></div>
</blockquote>
Seriously, man, KeyPaths are just <i class="">the business</i>. I
love them.<br class="">
<div class="">
<div><br class="">
</div>
<div>2) Bind <collection> to something like an anonymous
closure argument within the subscript. Or just allow “.”
syntax, as for static members. That removes another
<collection>.</div>
<div><br class="">
</div>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">
<div><span style="font-family: Courier;" class="">results[.index(\.startIndex,
offsetBy: 3)]</span></div>
<div><span style="font-family: Courier;" class=""><br class="">
</span></div>
<div><span style="font-family: Courier;" class="">or</span></div>
<div><span style="font-family: Courier;" class=""><br class="">
</span></div>
<div><span style="font-family: Courier;" class="">results[$.index(\.startIndex,
offsetBy: 3)]</span></div>
</blockquote>
<div><br class="">
</div>
<div>If anybody’s interested, I was playing around with an
“IndexExpression” type for this kind of thing. The language lets
you get pretty far, but it doesn’t work and I can’t figure out
why. It looks like a simple-enough generic struct, but it fails
with a cyclic metadata dependency.</div>
<div><br class="">
</div>
<div><a
href="https://gist.github.com/karwa/04cc43431951f24ae9334ba8a25e6a31"
class="" moz-do-not-send="true">https://gist.github.com/karwa/04cc43431951f24ae9334ba8a25e6a31</a></div>
</blockquote>
<br>
I'm not 100% sure why, but moving the <tt>IndexType</tt> enum out
of the <tt>IndexExpression</tt> struct makes it work (Xcode 9.2,
Swift 4.0.3):<br>
<br>
<tt>enum IndexType<C: Collection> {</tt><tt><br>
</tt><tt> case keypath(KeyPath<C, C.Index>)</tt><tt><br>
</tt><tt> case index(C.Index)</tt><tt><br>
</tt><tt>}</tt><tt><br>
</tt><tt><br>
</tt><tt>struct IndexExpression<C: Collection> {</tt><tt><br>
</tt><tt> let base: IndexType<C></tt><tt><br>
</tt><tt> let distance: C.IndexDistance</tt><tt><br>
</tt><tt><br>
</tt><tt> func resolve(in collection: C) -> C.Index {</tt><tt><br>
</tt><tt> let baseIdx: C.Index</tt><tt><br>
</tt><tt> switch base {</tt><tt><br>
</tt><tt> case .index(let idx): baseIdx = idx</tt><tt><br>
</tt><tt> case .keypath(let kp): baseIdx =
collection[keyPath: kp]</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt> return collection.index(baseIdx, offsetBy:
distance)</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt>}</tt><tt><br>
</tt><tt><br>
</tt><tt>let string = "hello everybody!"</tt><tt><br>
</tt><tt>let myIdx = string.startIndex</tt><tt><br>
</tt><tt>string[myIdx + 2] // "l"</tt><tt><br>
</tt><tt>string[\.endIndex - 3] // "d"</tt><br>
<br>
<blockquote type="cite"
cite="mid:1C4683DA-7FE1-400B-9AA4-05493193A26D@gmail.com">
<div>- Karl</div>
<div><br class="">
</div>
<div class="">
<div>
<blockquote type="cite" class="">
<div class="">On 19. Dec 2017, at 08:38, Cao, Jiannan via
swift-dev <<a href="mailto:swift-dev@swift.org"
class="" moz-do-not-send="true">swift-dev@swift.org</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" class="">
<div style="word-wrap: break-word; -webkit-nbsp-mode:
space; line-break: after-white-space;" class="">
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" class="">
<div style="word-wrap: break-word; -webkit-nbsp-mode:
space; line-break: after-white-space;" class="">
<div class="">I implemented the second approach:
SuperIndex</div>
<div class=""><br class="">
</div>
<a href="https://github.com/frogcjn/SuperStringIndex/"
class="" moz-do-not-send="true">https://github.com/frogcjn/SuperStringIndex/</a>
<div class=""><br class="">
</div>
<div class="">
<p style="box-sizing: border-box; margin-top: 0px;
margin-bottom: 16px; color: rgb(36, 41, 46);
font-family: -apple-system, BlinkMacSystemFont,
"Segoe UI", Helvetica, Arial,
sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI
Symbol"; font-size: 16px; background-color:
rgb(255, 255, 255);" class="">SuperString is a
special version of String. Its SuperIndex keeps a
reference to the string, let the index calculate
the offset.</p>
<div class=""><br class="">
</div>
<div class="">
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: Menlo; color: rgb(112, 61, 170);
background-color: rgb(255, 255, 255);" class=""><span
style="color: #ba2da2" class="">struct</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> SuperIndex : </span>Comparable<span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">, </span>Strideable<span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">, </span>CustomStringConvertible<span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> {</span></div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: "Fira Code";
background-color: rgb(255, 255, 255);
min-height: 13px;" class=""> <br
class="webkit-block-placeholder">
</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: "Fira Code";
background-color: rgb(255, 255, 255);" class="">
<span style="font-stretch: normal;
line-height: normal; font-family: Menlo;
color: rgb(186, 45, 162);" class="">var</span>
owner: <span style="font-stretch: normal;
line-height: normal; font-family: Menlo;
color: rgb(112, 61, 170);" class="">Substring</span></div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: "Fira Code";
background-color: rgb(255, 255, 255);" class="">
<span style="font-stretch: normal;
line-height: normal; font-family: Menlo;
color: rgb(186, 45, 162);" class="">var</span>
wrapped: <span style="font-stretch: normal;
line-height: normal; font-family: Menlo;
color: rgb(112, 61, 170);" class="">String</span>.<span
style="font-stretch: normal; line-height:
normal; font-family: Menlo; color: rgb(112,
61, 170);" class="">Index</span></div>
<p style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: "Fira Code";
background-color: rgb(255, 255, 255);
min-height: 13px;" class=""> <br
class="webkit-block-placeholder">
</p>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>...</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: "Fira Code";
background-color: rgb(255, 255, 255);
min-height: 13px;" class=""><br class="">
</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: Menlo; color: rgb(0, 132, 0);
background-color: rgb(255, 255, 255);" class=""><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> </span>// Offset</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: "Fira Code";
background-color: rgb(255, 255, 255);" class="">
<span style="font-stretch: normal;
line-height: normal; font-family: Menlo;
color: rgb(186, 45, 162);" class="">var</span>
offset: <span style="font-stretch: normal;
line-height: normal; font-family: Menlo;
color: rgb(112, 61, 170);" class="">Int</span>
{</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: Menlo; background-color: rgb(255,
255, 255);" class=""><span style="font-stretch:
normal; line-height: normal; font-family:
"Fira Code";" class=""> </span><span
style="color: #ba2da2" class="">return</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> </span><span style="color: #4f8187"
class="">owner</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">.</span><span style="color: #3e1e81"
class="">distance</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">(from: </span><span style="color:
#4f8187" class="">owner</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">.</span><span style="color: #703daa"
class="">startIndex</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">, to: </span><span style="color:
#4f8187" class="">wrapped</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">)</span></div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal;
font-family: "Fira Code";
background-color: rgb(255, 255, 255);" class="">
}</div>
</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal; font-family:
"Fira Code"; background-color: rgb(255,
255, 255);" class=""><br class="">
</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal; font-family:
"Fira Code"; background-color: rgb(255,
255, 255);" class=""> // <span style="color:
rgb(112, 61, 170); font-family: Menlo;" class="">Strideable</span></div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal; font-family:
"Fira Code"; background-color: rgb(255,
255, 255);" class="">
<div style="margin: 0px; font-stretch: normal;
line-height: normal; font-family: Menlo;"
class=""><span style="font-stretch: normal;
line-height: normal; font-family: "Fira
Code";" class=""> </span><span
style="color: #ba2da2" class="">func</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> advanced(by n: </span><span
style="color: #4f8187" class="">SuperIndex</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">.</span><span style="color: #4f8187"
class="">Stride</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">) -> </span><span style="color:
#4f8187" class="">SuperIndex</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> {</span></div>
<div style="margin: 0px; font-stretch: normal;
line-height: normal; font-family: Menlo;"
class=""><span style="font-stretch: normal;
line-height: normal; font-family: "Fira
Code";" class=""> </span><span
style="color: #ba2da2" class="">return</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> </span><span style="color: #4f8187"
class="">SuperIndex</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">(</span><span style="color: #4f8187"
class="">owner</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">.</span><span style="color: #3e1e81"
class="">index</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">(</span><span style="color: #4f8187"
class="">wrapped</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">, offsetBy: n), </span><span
style="color: #4f8187" class="">owner</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">)</span></div>
<div style="margin: 0px; font-stretch: normal;
line-height: normal;" class=""> }</div>
<div style="margin: 0px; font-stretch: normal;
line-height: normal;" class=""><br class="">
</div>
<div style="margin: 0px; font-stretch: normal;
line-height: normal;" class="">
<div style="margin: 0px; font-stretch: normal;
line-height: normal; font-family: Menlo;
color: rgb(79, 129, 135);" class=""><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> </span><span style="color:
#ba2da2" class="">static</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> </span><span style="color:
#ba2da2" class="">func</span><span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> +(lhs: </span>SuperIndex<span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">, rhs: </span>SuperIndex<span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">.</span>Stride<span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class="">) -> </span>SuperIndex<span
style="font-stretch: normal; line-height:
normal; font-family: "Fira Code";"
class=""> {</span></div>
<div style="margin: 0px; font-stretch: normal;
line-height: normal;" class=""> <span
style="font-stretch: normal; line-height:
normal; font-family: Menlo; color: rgb(186,
45, 162);" class="">return</span> lhs.<span
style="font-stretch: normal; line-height:
normal; font-family: Menlo; color: rgb(49,
89, 93);" class="">advanced</span>(by: rhs)</div>
<div style="margin: 0px; font-stretch: normal;
line-height: normal;" class=""> }</div>
</div>
</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal; font-family:
"Fira Code"; background-color: rgb(255,
255, 255);" class="">}</div>
<div style="margin: 0px; font-stretch: normal;
font-size: 11px; line-height: normal; font-family:
"Fira Code"; background-color: rgb(255,
255, 255);" class=""><br class="">
</div>
<div class="highlight highlight-source-swift"
style="box-sizing: border-box; margin-bottom:
16px; color: rgb(36, 41, 46); font-family:
-apple-system, BlinkMacSystemFont, "Segoe
UI", Helvetica, Arial, sans-serif,
"Apple Color Emoji", "Segoe UI
Emoji", "Segoe UI Symbol";
font-size: 16px; background-color: rgb(255, 255,
255);">
<pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; word-wrap: normal; padding: 16px; overflow: auto; line-height: 1.45; background-color: rgb(246, 248, 250); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> a<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">:</span> SuperString <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> <span class="pl-s" style="box-sizing: border-box; color: rgb(3, 47, 98);"><span class="pl-pds" style="box-sizing: border-box;">"</span>01234<span class="pl-pds" style="box-sizing: border-box;">"</span></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> o <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">startIndex</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> o1 <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> o <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">4</span>
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[o]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 0</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 01234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">..<</span>(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 01</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 012</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">..<</span>o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">3</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 2</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[o1<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span><span class="pl-smi" style="box-sizing: border-box;">o1</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">1</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 23</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">if</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> number <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">index</span>(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">of</span>: <span class="pl-s" style="box-sizing: border-box; color: rgb(3, 47, 98);"><span class="pl-pds" style="box-sizing: border-box;">"</span>1<span class="pl-pds" style="box-sizing: border-box;">"</span></span>) {
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(number) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(a[number<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span>}
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">if</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> number <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">index</span>(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">where</span>: { <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">$0</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">></span> <span class="pl-s" style="box-sizing: border-box; color: rgb(3, 47, 98);"><span class="pl-pds" style="box-sizing: border-box;">"</span>1<span class="pl-pds" style="box-sizing: border-box;">"</span></span> }) {
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(number) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 2</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span>}
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> b <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> a[(o<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">1</span>)<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> z <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> b.<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">startIndex</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">let</span> z1 <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">=</span> z <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">4</span>
<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[z]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 1234</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">..<</span>(z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 12</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>(z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 123</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[(z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>)<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 34</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[z<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span><span class="pl-smi" style="box-sizing: border-box;">z</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">+</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">3</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 34</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"></span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">print</span>(b[z1<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">...</span><span class="pl-smi" style="box-sizing: border-box;">z1</span><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-</span><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">2</span>]) <span class="pl-c" style="box-sizing: border-box; color: rgb(106, 115, 125);"><span class="pl-c" style="box-sizing: border-box;">//</span> 3</span></pre>
</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
<blockquote type="cite" class="">
<div class="">在 2017年12月18日,下午4:53,Cao, Jiannan
<<a href="mailto:frogcjn@163.com" class=""
moz-do-not-send="true">frogcjn@163.com</a>>
写道:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"
class="">
<div style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"
class="">
<div style="word-wrap: break-word;
-webkit-nbsp-mode: space; line-break:
after-white-space;" class="">Or we can
copy the design of std::vector::iterator
in C++.The index could keep a reference
to the collection.
<div class="">When the index being
offset by + operator, it could call
the owner to offset the index, since
it keeps a reference to
the collection owner.<br class="">
<div class=""><br class="">
</div>
<div class="">let startIndex =
s.startIndex</div>
<div class="">s[startIndex+1]</div>
<div class=""><br class="">
</div>
</div>
<blockquote style="margin: 0 0 0 40px;
border: none; padding: 0px;" class="">
<div class="">
<div style="margin: 0px;
font-stretch: normal; font-size:
11px; line-height: normal;
font-family: Menlo;
background-color: rgb(255, 255,
255);" class="">
<div style="margin: 0px;
font-stretch: normal;
line-height: normal; color:
rgb(112, 61, 170);" class=""><span
style="color: #ba2da2"
class="">public</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> </span><span
style="color: #ba2da2"
class="">struct</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class="">
MyIndex<T: </span>Collection<span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class="">> : </span>Comparable<span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> </span><span
style="color: #ba2da2"
class="">where</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> </span>T<span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class="">.</span>Index<span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> == </span>MyIndex<span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> {</span></div>
<div style="margin: 0px;
font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> <span
style="font-stretch: normal;
line-height: normal;
font-family: Menlo; color:
rgb(186, 45, 162);" class="">public</span>
<span style="font-stretch:
normal; line-height: normal;
font-family: Menlo; color:
rgb(186, 45, 162);" class="">let</span>
owner: <span
style="font-stretch: normal;
line-height: normal;
font-family: Menlo; color:
rgb(112, 61, 170);" class="">T</span></div>
<div style="margin: 0px;
font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""><span
style="font-stretch: normal;
line-height: normal;
font-family: Menlo; color:
rgb(112, 61, 170);" class="">...</span></div>
<div style="margin: 0px;
font-stretch: normal;
line-height: normal;" class=""><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> </span><span
style="color: #ba2da2"
class="">public</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> </span><span
style="color: #ba2da2"
class="">static</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> </span><span
style="color: #ba2da2"
class="">func</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> + (lhs:
</span><span style="color:
#703daa" class="">MyIndex</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class="">, rhs: </span><span
style="color: #703daa"
class="">T</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class="">.</span><span
style="color: #703daa"
class="">IndexDistance</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class="">) ->
</span><span style="color:
#703daa" class="">MyIndex</span><span
style="font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> {</span></div>
<div style="margin: 0px;
font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> <span
style="font-stretch: normal;
line-height: normal;
font-family: Menlo; color:
rgb(186, 45, 162);" class="">return</span>
lhs.owner.index(lhs, offsetBy:
rhs)</div>
<div style="margin: 0px;
font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class=""> }</div>
<div style="margin: 0px;
font-stretch: normal;
line-height: normal;
font-family: "Fira
Code";" class="">}</div>
</div>
</div>
</blockquote>
<div class="">
<div class="">
<div class=""><br class="">
<blockquote type="cite" class="">
<div class="">在
2017年12月15日,上午9:34,Michael
Ilseman <<a
href="mailto:milseman@apple.com"
class=""
moz-do-not-send="true">milseman@apple.com</a>>
写道:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta
http-equiv="Content-Type"
content="text/html;
charset=utf-8" class="">
<div style="word-wrap:
break-word;
-webkit-nbsp-mode: space;
line-break:
after-white-space;" class="">Yes,
I was trying to highlight
that they are different and
should be treated different.
This was because it seemed
you were conflating the two
in your argument. You claim
that people expect it, and
I’m pointing out that what
people actually expect
(assuming they’re coming
from C or languages with a
similar model) already
exists as those models deal
in encoded offsets.
<div class=""><br class="">
</div>
<div class="">More important
than expectations
surrounding what to
provide to a subscript are
expectations surrounding
algorithmic complexity.
This has security
implications. The
expectation of subscript
is that it is
“constant-ish”, for a
fuzzy hand-wavy definition
of “constant-ish” which
includes amortized
constant or logarithmic.</div>
<div class=""><br class="">
</div>
<div class="">Now, I agree
with the overall sentiment
that `index(offsetBy:)` is
unwieldy. I am interested
in approaches to improve
this. But, we cannot throw
linear complexity into
subscript without extreme
justification.</div>
<div class=""><br class="">
<div class=""><br class="">
<blockquote type="cite"
class="">
<div class="">On Dec
14, 2017, at 5:25
PM, Cao, Jiannan
<<a
href="mailto:frogcjn@163.com"
class=""
moz-do-not-send="true">frogcjn@163.com</a>>
wrote:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space; line-break:
after-white-space;" class="">
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class="">This
offset is
unicode offset,
is not the
offset of
element.
<div class="">For
example:
index(startIndex,
offsetBy:1) is
encodedOffset
4 or 8, not 1.</div>
<div class=""><br
class="">
</div>
<div class="">Offset
indexable is
based on the
offset of
count of each
element/index.
it is the same
result of
s.index(s.startIndex,
offsetBy:i)</div>
<div class="">The
encodedOffset
is the
underlaying
offset of
unicode
string, not
the same
concept of the
offset index
of collection.</div>
<div class=""><br
class="">
</div>
<div class="">The
offset
indexable is
meaning to the
elements and
index of
collection
(i-th element
of the
collection),
not related to
the unicode
offset (which
is the
underlaying
data offset
meaning to the
UTF-16
String).</div>
<div class=""><br
class="">
</div>
<div class="">These
two offset is
totally
different.</div>
<div class="">
<div class=""><br
class="">
</div>
<div class="">Best,</div>
<div class="">Jiannan</div>
<div class=""><br
class="">
<blockquote
type="cite"
class="">
<div class="">在
2017年12月15日,上午9:17,Michael Ilseman <<a
href="mailto:milseman@apple.com"
class=""
moz-do-not-send="true">milseman@apple.com</a>>
写道:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class=""><br
class="">
<div class=""><br
class="">
<blockquote
type="cite"
class="">
<div class="">On
Dec 14, 2017,
at 4:49 PM,
Cao, Jiannan
via swift-dev
<<a
href="mailto:swift-dev@swift.org"
class=""
moz-do-not-send="true">swift-dev@swift.org</a>>
wrote:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class="">
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class="">
<div class="">People
used to the
offset index
system instead
of the
String.Index.
Using offset
indices to
name the
elements,
count the
elements is
normal and
nature.</div>
<div class=""><br
class="">
</div>
</div>
</div>
</div>
</blockquote>
<div class=""><br
class="">
</div>
<div class="">The
offset system
that you’re
referring to
is totally
available in
String today,
if you’re
willing for it
to be the
offset into
the encoding.
That’s the
offset
“people”
you’re
referring to
are likely
used to and
consider
normal and
natural. On
String.Index,
there is the
following:</div>
<div class=""><br
class="">
</div>
<div class="">
<pre
class="code-source
code-source-indented" data-language="swift" style="box-sizing: inherit;
margin-top:
0px;
margin-bottom:
0px; padding:
0.35294rem
0.58824rem
0.35294rem
2.47059em;
font-size:
17px;
white-space:
normal;
overflow-wrap:
normal;
word-wrap:
normal;
letter-spacing:
0px; overflow:
auto;
background-color:
rgb(249, 250,
250); border:
1px solid
rgb(230, 230,
230);
border-top-left-radius:
4px;
border-top-right-radius:
4px;
border-bottom-right-radius:
4px;
border-bottom-left-radius:
4px; speak:
literal-punctuation;
text-indent:
-1.88235em;
color: rgb(51,
51, 51);"><code
style="box-sizing: inherit; font-size: 15px; font-family: "SF
Mono",
Menlo,
monospace,
"SF Pro
Icons";
letter-spacing:
-0.027em;
line-height:
1.26667;"
class=""><span
class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13,
145);">init</span>(<span
class="syntax-identifier" style="box-sizing: inherit;">encodedOffset</span> <span
class="syntax-param-name" style="box-sizing: inherit; color: rgb(64, 64,
64);">offset</span>: <a
class="symbolref"
href="https://developer.apple.com/documentation/swift/int"
style="box-sizing: inherit; color: rgb(92, 38, 153); text-decoration:
none;"
moz-do-not-send="true">Int</a>)</code></pre>
<div class=""><br
class="">
</div>
<div class="">and </div>
<div class=""><br
class="">
</div>
<div class="">
<pre
class="code-source
code-source-indented" data-language="swift" style="box-sizing: inherit;
margin-top:
0px;
margin-bottom:
0px; padding:
0.35294rem
0.58824rem
0.35294rem
2.47059em;
font-size:
17px;
white-space:
normal;
overflow-wrap:
normal;
word-wrap:
normal;
letter-spacing:
0px; overflow:
auto;
background-color:
rgb(249, 250,
250); border:
1px solid
rgb(230, 230,
230);
border-top-left-radius:
4px;
border-top-right-radius:
4px;
border-bottom-right-radius:
4px;
border-bottom-left-radius:
4px; speak:
literal-punctuation;
text-indent:
-1.88235em;
color: rgb(51,
51, 51);"><code
style="box-sizing: inherit; font-size: 15px; font-family: "SF
Mono",
Menlo,
monospace,
"SF Pro
Icons";
letter-spacing:
-0.027em;
line-height:
1.26667;"
class=""><span
class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13,
145);">var</span> <span
class="syntax-identifier" style="box-sizing: inherit;">encodedOffset</span>: <a
class="symbolref"
href="https://developer.apple.com/documentation/swift/int"
style="box-sizing: inherit; color: rgb(92, 38, 153); text-decoration:
none;"
moz-do-not-send="true">Int</a> { <span
class="syntax-keyword" style="box-sizing: inherit; color: rgb(170, 13,
145);">get</span> }</code></pre>
<div class=""><br
class="">
</div>
</div>
</div>
<div class=""><br
class="">
</div>
<div class="">[1] <a
href="https://developer.apple.com/documentation/swift/string.index"
class=""
moz-do-not-send="true">https://developer.apple.com/documentation/swift/string.index</a></div>
<div class=""><br
class="">
</div>
<div class=""><br
class="">
</div>
<blockquote
type="cite"
class="">
<div class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class="">
<div class="">
<div class=""><b
class="">This
offset index
system has a
long history
and a real
meaning to the
collection. </b>The
subscript s[i]
has a fix
meaning of
"getting the
i-th element
in this
collection",
which is
normal and
direct. Get
the range with
offset
indices, is
also direct.
It means the
substring is
from the i-th
character up
to the j-th
character of
the original
string.</div>
<div class=""><br
class="">
</div>
</div>
<div class="">
<div class="">People
used to play
subscript,
range with
offset
indices. Use
string[string.index(i,
offsetBy: 5)]
is not as
directly and
easily as
string[i + 5].
Also the
Range<String.Index>
is not as
directly as
Range<Offset>.
Developers
need to
transfer the
Range<String.Index>
result of
string.range(of:)
to
Range<OffsetIndex>
to know the
exact range of
the substring.
Range<String.Index> has a real meaning to the machine and
underlaying
data location
for the
substring, but
Range<OffsetIndex> also has a direct location information for
human being,
and represents<b
class=""> the
abstract
location
concept of the
collection
(This is the
most UNIMPEACHABLE
REASON I could
provide)</b>.</div>
<div class=""><b
class=""><br
class="">
</b></div>
<div class=""><b
class="">Offset
index system
is based on
the nature of
collection. Each element of the collection could be located by offset,
which is a
direct and
simple
conception to
any
collection.
Right? </b>Even
the String
with
String.Index
has some
offset index
property
within it. For
example: the
`count` of the
String, is the
offset index
of the
endIndex.The
enumerated()
generated a
sequence with
elements
contains the
same offset as
the offset
index system
provided. And
when we apply
Array(string),
the string
divided by
each character
and make the
offset indices
available for
the new array.</div>
</div>
<div class="">
<div class=""><br
class="">
</div>
<div class=""><b
class="">The
offset index
system is just
an assistant
for
collection,
not a
replacement to
String.Index. </b>We
use
String.Index
to represent
the normal
underlaying of
the String. We
also could use
offset indices
to represent
the nature of
the Collection
with its
elements.
Providing the
offset index
as a second
choice to
access
elements in
collections,
is not only
for the String
struct, is for
all
collections,
since <b
class="">it is
the nature of
the collection
concept</b>,
and developer
could choose
use it or not.<b
class=""> </b><br
class="">
<br class="">
</div>
<div class="">We
don't make the
String.Index
O(1), but
translate the
offset indices
to the
underlaying
String.Index.
Each time
using
subscript with
offset index,
we just need
to translate
offset indices
to underlaying
indices using
c.index(startIndex, offsetBy:i), c.distance(from: startIndex, to:i) </div>
</div>
<div class=""><br
class="">
</div>
<div class="">We
can make the
offset indices
available
through
extension to
Collection (as
my GitHub repo
demo: <a
href="https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-"
class=""
style="background-color:
rgb(255, 255,
255);"
moz-do-not-send="true">https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-</a>).</div>
<div class=""><br
class="">
</div>
or we could
make it at
compile time:
<div class="">for
example</div>
<div class=""><br
class="">
</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>c[1...]</div>
<div class="">compile
to</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>c[c.index(startIndex,
offsetBy:1)...]</div>
<div class=""><br
class="">
</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let
index: Int =
s.index(of:
"a")</div>
<div class="">compile
to</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let
index: Int
= s.distance(from:
s.startIndex,
to:
s.index(of:"a"))</div>
<div class=""><br
class="">
</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let
index = 1 //
if used in s
only</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>s[index..<index+2]</div>
<div class="">compile
to</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let
index =
s.index(s.startIndex,
offsetBy: 1)</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>s[index..<s.index(index,
offsetBy: 2)]</div>
<div class=""><br
class="">
</div>
<div class="">
<div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let
index = 1 //
if used both
in s1, s2</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>s1[index..<index+2]</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>s2[index..<index+2]</div>
<div class="">compile
to</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let
index = 1</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let
index1
= s1.index(s.startIndex,
offsetBy:
index)</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let
index2 =
s2.index(s.startIndex,
offsetBy:
index)</div>
<div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>s1[index1..<s.index(index1,
offsetBy: 2)]</div>
</div>
<div class="">
<div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>s2[index2..<s.index(index2,
offsetBy: 2)]</div>
</div>
<div class=""><br
class="">
</div>
<div class="">I
really want
the team to
consider
providing the
offset index
system as an
assistant to
the
collection. It
is the very
necessary
basic concept
of Collection.</div>
<div class=""><br
class="">
</div>
<div class="">Thanks!</div>
<div class="">Jiannan</div>
<div class="">
<div class=""><br
class="">
<blockquote
type="cite"
class="">
<div class="">在
2017年12月15日,上午2:13,Jordan Rose <<a
href="mailto:jordan_rose@apple.com"
class=""
moz-do-not-send="true">jordan_rose@apple.com</a>>
写道:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class="">
<div class="">We
really don't
want to make
subscripting a
non-O(1)
operation.
That just
provides false
convenience
and encourages
people to do
the wrong
thing with
Strings
anyway.</div>
<div class=""><br
class="">
</div>
<div class="">I'm
always
interested in
why people
want this kind
of ability.
Yes, it's nice
for teaching
programming to
be able to
split strings
on character
boundaries
indexed by
integers, but
where does it
come up in
real life? The
most common
cases I see
are trying to
strip off the
first or last
character, or
a known prefix
or suffix, and
I feel like we
should have
better answers
for those than
"use integer
indexes"
anyway.</div>
<div class=""><br
class="">
</div>
<div class="">Jordan</div>
<br class="">
<div class=""><br
class="">
<blockquote
type="cite"
class="">
<div class="">On
Dec 13, 2017,
at 22:30, Cao,
Jiannan via
swift-dev <<a
href="mailto:swift-dev@swift.org" class="" moz-do-not-send="true">swift-dev@swift.org</a>>
wrote:</div>
<br
class="Apple-interchange-newline">
<div class="">
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8" class="">
<div
style="word-wrap:
break-word;
-webkit-nbsp-mode:
space;
line-break:
after-white-space;"
class="">Hi,
<div class=""><br
class="">
</div>
<div class="">I
would like to
discuss the
String.Index
problem within
Swift. I know
the current
situation of
String.Index
is based on
the nature of
the
underlaying
data structure
of the string.</div>
<div class=""><br
class="">
</div>
<div class="">But
could we just
make
String.Index
contain offset
information?
Or make offset
index
subscript
available for
accessing
character in
String?</div>
<div class=""><br
class="">
</div>
<div class="">for
example:</div>
<blockquote
style="margin:
0 0 0 40px;
border: none;
padding: 0px;"
class=""><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color:
rgb(186, 45,
162);"
class="">let</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class=""> a =
</span><span
style="color:
rgb(209, 47,
27);
font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255);"
class="">"01234"</span><br
class="">
<span
style="color:
rgb(62, 30,
129);
font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">0</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">]) </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(0,
132, 0);"
class="">// 0<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(62, 30,
129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">0</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">...</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">4</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">]) </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(0,
132, 0);"
class="">//
01234<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(62, 30,
129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[...])
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(0, 132,
0);" class="">//
01234</span><br
class="">
<span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(62, 30,
129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[..<</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">2</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">]) </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(0,
132, 0);"
class="">// 01<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(62, 30,
129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[...</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">2</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">]) </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(0,
132, 0);"
class="">//
012<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(62, 30,
129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">2</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">...])
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(0, 132,
0);" class="">//
234<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(62, 30,
129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">2</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">...</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">3</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">]) </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(0,
132, 0);"
class="">// 23<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(62, 30,
129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">2</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">...</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(39,
42, 216);"
class="">2</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">]) </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(0,
132, 0);"
class="">// 2</span><br
class="">
<span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(186, 45,
162);"
class="">if</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class=""> </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color:
rgb(186, 45,
162);"
class="">let</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">
number = </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">.</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(49,
89, 93);"
class="">index</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(of:
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(209, 47,
27);" class="">"1"</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">) {<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255);"
class=""> </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(62,
30, 129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(number)
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(0, 132,
0);" class="">//
1<br class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255);"
class=""> </span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(62,
30, 129);"
class="">print</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">(</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);
color: rgb(79,
129, 135);"
class="">a</span><span
style="font-family: Menlo; font-size: 11px; background-color: rgb(255,
255, 255);"
class="">[number...])
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255); color:
rgb(0, 132,
0);" class="">//
1234<br
class="">
</span><span
style="font-family:
Menlo;
font-size:
11px;
background-color:
rgb(255, 255,
255);"
class="">}</span></blockquote>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class=""><br class="">
</span></div>
<div class=""><br
class="">
</div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">0 equals to
Collection.Index
of
collection.index(startIndex,
offsetBy: 0)</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">1 equals to</span><span
style="background-color: rgb(255, 255, 255);" class=""> Collection.Index
of
collection.index(startIndex,
offsetBy: 1)</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">...</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">we keep the
String.Index,
but allow
another kind
of index,
which is
called
"offsetIndex"
to access the
String.Index
and the
character in
the string.</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">Any Collection
could use the
offset index
to access
their element,
regarding the
real index of
it.</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class=""><br class="">
</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">I have make the
Collection
OffsetIndexable
protocol
available
here, and make
it more accessible for StringProtocol considering all API related to the
index.</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class=""><br class="">
</span></div>
<div class="">
<div class=""><span
style="background-color: rgb(255, 255, 255);" class=""><a
href="https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-"
class=""
moz-do-not-send="true">https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-</a></span></div>
</div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class=""><br class="">
</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">If someone want
to make the
offset
index/range
available for
any
collection,
you just need
to extend the
collection:</span></div>
<div class="">
<pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; word-wrap: normal; padding: 16px; overflow: auto; line-height: 1.45; background-color: rgb(246, 248, 250); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(36, 41, 46);" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">extension</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);"><span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">String</span></span> : <span class="pl-e" style="box-sizing: border-box; color: rgb(111, 66, 193);">OffsetIndexableCollection </span>{
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">extension</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);">Substring</span> : <span class="pl-e" style="box-sizing: border-box; color: rgb(111, 66, 193);">OffsetIndexableCollection </span>{
}</pre>
<div class=""><br
class="">
</div>
</div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class=""><br class="">
</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">I hope the Swift
core team
could consider
bring the
offset index
to string, or
make
it available
to other
collection,
thus
let developer
to decide
whether their
collection
could use
offset indices
as an
assistant for
the real index
of the
collection.</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class=""><br class="">
</span></div>
<div class=""><br
class="">
</div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">Thanks!</span></div>
<div class=""><span
style="background-color: rgb(255, 255, 255);" class="">Jiannan</span></div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
<br>
</body>
</html>