<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="-webkit-font-kerning: none;" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">We know that:</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">The cumbersome complexity of current Swift String handling&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">and programming is caused by the fact that Unicode characters&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">are stored and processed as&nbsp; streams/arrays with elements&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">of variable-width (1...4 bytes for each character) Unicode characters.</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">Because of that, direct subscripting of string elements e.g. str[2..&lt;18]&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">is not possible.Therefore it was, and still is, not implemented in Swift,</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">much to the unpleasant surprise of many new Swift programmers&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">coming from many other PLs like me. They did miss plain direct subscripting&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">so much that the first thing ever they do before using Swift intensively is&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">implementing the following or similar dreadful code (at least for direct&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">subscripting),&nbsp; and bury it deep into a String extension, once written,&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">hopefully never to be seen again, like in this example:&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">extension String</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">{</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp;&nbsp; subscript(i: Int) -&gt; String</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp;&nbsp; {</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; &nbsp; &nbsp; guard i &gt;= 0 &amp;&amp; i &lt; characters.count else { return "" }</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; &nbsp; &nbsp; return String(self[index(startIndex, offsetBy: i)])</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; }</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; subscript(range: Range&lt;Int&gt;) -&gt; String</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; {</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; &nbsp; &nbsp; let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) ?? endIndex</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; &nbsp; &nbsp; return substring(with: lowerIndex..&lt;(index(lowerIndex, offsetBy: range.upperBound - range.lowerBound, limitedBy: endIndex) ?? endIndex))</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; }</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; subscript(range: ClosedRange&lt;Int&gt;) -&gt; String</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; {</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; &nbsp; &nbsp; let lowerIndex = index(startIndex, offsetBy: max(0,range.lowerBound), limitedBy: endIndex) ?? endIndex</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; &nbsp; &nbsp; return substring(with: lowerIndex..&lt;(index(lowerIndex, offsetBy: range.upperBound - range.lowerBound + 1, limitedBy: endIndex) ?? endIndex))</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp; &nbsp; }&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">&nbsp;}</span></div><p style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class="">&nbsp;&nbsp; &nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">[splendid jolly good Earl Grey tea is now being served to help those flabbergasted to recover as quickly as possible.]&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">This rather indirect and clumsy way of working with string data is because&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">(with the exception of UTF-32 characters) Unicode characters come in&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">variable-width encoding (1 to 4 bytes for each char), which as we know&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">makes string handling for UTF-8, UTF-16 very complex and inefficient.</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">E.g. to isolate a substring it is necessary to sequentially&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">traverse the string instead of direct access.&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">However, that is not the case with UTF-32, because with UTF-32 encoding</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">each character has a fixed-width and always occupies exactly 4 bytes, 32 bit.&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">Ergo: the problem can be easily solved: The simple solution is to always&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">and without exception use UTF-32 encoding as Swift's internal&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">string format because it only contains fixed width Unicode characters.&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">Unicode strings with whatever UTF encoding as read into the program would&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">be automatically converted to 32-bit UTF32 format. Note that explicit conversion&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">e.g. back to UTF-8, can be specified or defaulted when writing Strings to a&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">storage medium or URL etc.&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">Possible but imho not recommended: The current String system could be pushed</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">down and kept alive (e.g. as Type StringUTF8?) as a secondary alternative to&nbsp;</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">accommodate those that need to process very large quantities of text in core.</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">What y'all think?</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">Kind regards</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=""><span style="font-kerning: none" class="">TedvG</span></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><a href="http://www.tedvg.com" class=""><span style="font-kerning: none" class=""></span>www.tedvg.com</a></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><a href="http://www.ravelnotes.com" class="">www.ravelnotes.com</a>&nbsp;</div><p style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class="">&nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><p style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class="">&nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><p style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class="">&nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><p style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class="">&nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Helvetica; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial; min-height: 13px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div></body></html>