<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 </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 </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 streams/arrays with elements </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..<18] </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 </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 </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 </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 </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), and bury it deep into a String extension, once written, </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: </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=""> subscript(i: Int) -> 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=""> guard i >= 0 && i < 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=""> 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=""> }</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=""> subscript(range: Range<Int>) -> 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=""> 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=""> return substring(with: lowerIndex..<(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=""> }</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=""> subscript(range: ClosedRange<Int>) -> 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=""> 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=""> return substring(with: lowerIndex..<(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=""> } </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><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=""> </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.] </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 </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 </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 </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 </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. </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. </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 </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 </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. </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 </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 </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 </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. </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 </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> </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=""> </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=""> </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=""> </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=""> </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>